├── README ├── canoneos.cpp ├── canoneos.h ├── canonps.cpp ├── canonps.h ├── copying.txt ├── eosvaluetitles.h ├── examples ├── EOSBulb │ └── EOSBulb.pde ├── EOSCamController │ ├── EOSCamController.pde │ ├── camcontroller.h │ ├── controls.cpp │ ├── controls.h │ ├── dataitem.cpp │ ├── dataitem.h │ ├── eoseventparser.cpp │ ├── eoseventparser.h │ ├── expcomp_macro.h │ ├── hdrcapture.cpp │ ├── hdrcapture.h │ ├── menu.cpp │ ├── menu.h │ ├── screen.cpp │ ├── screen.h │ ├── screenitem.cpp │ └── screenitem.h ├── EOSCapture │ └── EOSCapture.pde ├── EOSEventLab │ └── EOSEventLab.pde ├── EOSEventMonitor │ └── EOSEventMonitor.pde ├── EOSFocus │ └── EOSFocus.pde ├── EOSHDRCapture │ ├── EOSHDRCapture.pde │ ├── expcomp_macro.h │ ├── hdrcapture.cpp │ └── hdrcapture.h ├── EOSRemote │ ├── EOSConsole.cpp │ ├── EOSConsole.h │ ├── EOSRemote.pde │ ├── eoseventparser.cpp │ ├── eoseventparser.h │ └── valuetitles.h ├── PSCapture │ ├── PSCapture.pde │ ├── pseventparser.cpp │ ├── pseventparser.h │ ├── ptpobjinfoparser.cpp │ ├── ptpobjinfoparser.h │ └── sample_output.txt ├── PSDevProp │ ├── PSDevProp.pde │ ├── devpropparser.cpp │ ├── devpropparser.h │ └── sample_output_a640.txt ├── PSRemote │ ├── PSRemote.pde │ ├── psconsole.cpp │ ├── psconsole.h │ ├── pseventparser.cpp │ ├── pseventparser.h │ ├── ptpobjinfoparser.cpp │ └── ptpobjinfoparser.h ├── PTPCapture │ └── PTPCapture.pde └── PTPDevInfo │ ├── PTPDevInfo.pde │ ├── devinfoparser.cpp │ └── devinfoparser.h ├── gpl2.txt ├── mtpconst.h ├── psvaluetitles.h ├── ptp.cpp ├── ptp.h ├── ptpcallback.cpp ├── ptpcallback.h ├── ptpconst.h ├── ptpdebug.cpp ├── ptpdebug.h ├── ptpdpparser.h ├── ptpmsgstr.h ├── scheduler.cpp ├── scheduler.h ├── simplefifo.h ├── simpletimer.cpp ├── simpletimer.h └── valuelist.h /README: -------------------------------------------------------------------------------- 1 | PTP and camera-specific libraries for Arduino USB Host Project. 2 | 3 | This library depends on https://github.com/felis/USB_Host_Shield">USB_Host_Shield library written to support http://www.circuitsathome.com/arduino_usb_host_shield_projects. 4 | 5 | The project is hosted at http://www.circuitsathome.com 6 | -------------------------------------------------------------------------------- /canoneos.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #include "canoneos.h" 18 | 19 | 20 | void EOSStateHandlers::OnSessionOpenedState(PTP *ptp) 21 | { 22 | if (!FAILED(((CanonEOS*)ptp)->SetPCConnectMode(1)) && !FAILED(((CanonEOS*)ptp)->SetExtendedEventInfo(1))) 23 | ptp->SetState(PTP_STATE_DEVICE_INITIALIZED); 24 | } 25 | 26 | uint32_t ImgQualitySupplier::GetDataSize() 27 | { 28 | return ((pictFormat & 0xFFFF0000) ? 0x0000002C : 0x0000001C); 29 | } 30 | 31 | void ImgQualitySupplier::GetData(const uint16_t len, uint8_t *pbuf) 32 | { 33 | uint8_t num_files = (pictFormat & 0xFFFF0000) ? 2 : 1; 34 | 35 | ((uint32_t*)pbuf)[0] = (num_files == 2) ? 0x0000002C : 0x0000001C; 36 | ((uint32_t*)pbuf)[1] = (uint32_t) EOS_DPC_ImageQuality; 37 | ((uint32_t*)pbuf)[2] = (uint32_t) num_files; 38 | 39 | uint32_t format = pictFormat; 40 | 41 | for (uint8_t i=0, pos=3; i>= 4) 46 | ((uint32_t*)pbuf)[pos++] = (uint32_t)(format & 0xF); 47 | } 48 | } 49 | 50 | CanonEOS::CanonEOS(uint8_t addr, uint8_t epin, uint8_t epout, uint8_t epint, uint8_t nconf, PTPStateHandlers *s) 51 | : PTP(addr, epin, epout, epint, nconf, s) 52 | { 53 | } 54 | 55 | uint16_t CanonEOS::SetImageQuality(uint32_t format) 56 | { 57 | uint16_t ptp_error = PTP_RC_GeneralError; 58 | OperFlags flags = { 0, 0, 1, 1, 1, 0 }; 59 | 60 | ImgQualitySupplier sup; 61 | sup.SetPictureFormat(format); 62 | 63 | if ( (ptp_error = Transaction(EOS_OC_SetDevicePropValue, &flags, NULL, (void*)&sup)) != PTP_RC_OK) 64 | PTPTRACE2("SetImageQuality error", ptp_error); 65 | 66 | return ptp_error; 67 | } 68 | 69 | uint16_t CanonEOS::SetPCConnectMode(uint8_t mode) 70 | { 71 | uint32_t params[1]; 72 | params[0] = (uint32_t) mode; 73 | return Operation(EOS_OC_SetPCConnectMode, 1, params); 74 | } 75 | 76 | uint16_t CanonEOS::SetExtendedEventInfo(uint8_t mode) 77 | { 78 | uint32_t params[1]; 79 | params[0] = (uint32_t) mode; 80 | return Operation(EOS_OC_SetExtendedEventInfo, 1, params); 81 | } 82 | 83 | uint16_t CanonEOS::StartBulb() 84 | { 85 | uint32_t params[3]; 86 | 87 | params[0] = 0xfffffff8; 88 | params[1] = 0x00001000; 89 | params[2] = 0x00000000; 90 | 91 | Operation(0x911A, 3, params); 92 | Operation(0x911B, 0, NULL); 93 | Operation(0x9125, 0, NULL); 94 | 95 | return PTP_RC_OK; 96 | } 97 | 98 | uint16_t CanonEOS::StopBulb() 99 | { 100 | uint32_t params[3]; 101 | 102 | params[0] = 0xffffffff; 103 | params[1] = 0x00001000; 104 | params[2] = 0x00000000; 105 | Operation(0x911A, 3, params); 106 | 107 | params[0] = 0xfffffffc; 108 | Operation(0x911A, 3, params); 109 | Operation(0x9126, 0, NULL); 110 | Operation(0x911C, 0, NULL); 111 | 112 | return PTP_RC_OK; 113 | } 114 | 115 | uint16_t CanonEOS::CancelTransfer(uint32_t object_id) 116 | { 117 | uint32_t params[1]; 118 | params[0] = object_id; 119 | 120 | return Operation(EOS_OC_CancelTransfer, 1, params); 121 | } 122 | 123 | uint16_t CanonEOS::ResetTransfer(uint32_t object_id) 124 | { 125 | uint32_t params[1]; 126 | params[0] = object_id; 127 | 128 | return Operation(EOS_OC_ResetTransfer, 1, params); 129 | } 130 | 131 | uint16_t CanonEOS::SwitchLiveView(bool on) 132 | { 133 | uint16_t ptp_error = PTP_RC_GeneralError; 134 | 135 | if ((ptp_error = SetProperty(EOS_DPC_LiveView, (on) ? 2 : 0)) == PTP_RC_OK) 136 | { 137 | if (on) 138 | { 139 | if ((ptp_error = SetProperty(0xD1B3, 0)) != PTP_RC_OK) 140 | { 141 | PTPTRACE2("LiveView start failure:", ptp_error); 142 | SetProperty(EOS_DPC_LiveView, 0); 143 | return PTP_RC_GeneralError; 144 | } 145 | } 146 | } 147 | return ptp_error; 148 | } 149 | 150 | uint16_t CanonEOS::MoveFocus(uint16_t step) 151 | { 152 | uint16_t ptp_error = PTP_RC_GeneralError; 153 | OperFlags flags = { 1, 0, 0, 0, 0, 0 }; 154 | uint32_t params[1]; 155 | 156 | params[0] = (uint32_t) step; 157 | 158 | if ( (ptp_error = Transaction(EOS_OC_MoveFocus, &flags, params, NULL)) != PTP_RC_OK) 159 | PTPTRACE2("MoveFocus error: ", ptp_error); 160 | 161 | return ptp_error; 162 | } 163 | 164 | uint16_t CanonEOS::EventCheck(PTPReadParser *parser) 165 | { 166 | uint16_t ptp_error = PTP_RC_GeneralError; 167 | OperFlags flags = { 0, 0, 0, 1, 1, 0 }; 168 | 169 | if ( (ptp_error = Transaction(0x9116, &flags, NULL, parser)) != PTP_RC_OK) 170 | PTPTRACE2("EOSEventCheck error:", ptp_error); 171 | 172 | return ptp_error; 173 | } 174 | 175 | uint16_t CanonEOS::Capture() 176 | { 177 | return Operation(EOS_OC_Capture, 0, NULL); 178 | } 179 | 180 | 181 | uint16_t CanonEOS::SetProperty(uint16_t prop, uint32_t val) 182 | { 183 | uint16_t ptp_error = PTP_RC_GeneralError; 184 | OperFlags flags = { 0, 0, 1, 1, 3, 12 }; 185 | uint32_t params[3]; 186 | 187 | params[0] = 0x0000000C; 188 | params[1] = (uint32_t)prop; 189 | params[2] = val; 190 | 191 | if ( (ptp_error = Transaction(EOS_OC_SetDevicePropValue, &flags, NULL, (void*)params)) != PTP_RC_OK) 192 | PTPTRACE2("SetProperty error:", ptp_error); 193 | 194 | return ptp_error; 195 | } 196 | 197 | uint16_t CanonEOS::GetProperty(uint16_t prop, PTPReadParser *parser) 198 | { 199 | uint16_t ptp_error = PTP_RC_GeneralError; 200 | OperFlags flags = { 1, 0, 0, 1, 1, 0 }; 201 | uint32_t params[1]; 202 | 203 | params[0] = (uint32_t)prop; 204 | 205 | if ( (ptp_error = Transaction(EOS_OC_GetDevicePropValue, &flags, params, (void*)parser)) != PTP_RC_OK) 206 | PTPTRACE2("GetProperty error:", ptp_error); 207 | 208 | return ptp_error; 209 | } 210 | 211 | uint16_t CanonEOS::GetDeviceInfoEx(PTPReadParser *parser) 212 | { 213 | uint16_t ptp_error = PTP_RC_GeneralError; 214 | OperFlags flags = { 0, 0, 0, 1, 1, 0 }; 215 | 216 | if ( (ptp_error = Transaction(EOS_OC_GetDeviceInfoEx, &flags, NULL, (void*)parser)) != PTP_RC_OK) 217 | PTPTRACE2("GetDeviceInfo error:", ptp_error); 218 | 219 | return ptp_error; 220 | } 221 | 222 | uint16_t CanonEOS::GetObject(uint32_t object_id, uint32_t parent_id, PTPReadParser *parser) 223 | { 224 | uint16_t ptp_error = PTP_RC_GeneralError; 225 | OperFlags flags = { 2, 0, 0, 1, 1, 0 }; 226 | uint32_t params[2]; 227 | 228 | params[0] = object_id; 229 | params[1] = parent_id; 230 | 231 | if ( (ptp_error = Transaction(EOS_OC_GetObject, &flags, params, (void*)parser)) != PTP_RC_OK) 232 | PTPTRACE2("GetObject error:", ptp_error); 233 | 234 | return ptp_error; 235 | } 236 | -------------------------------------------------------------------------------- /canoneos.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #ifndef __CANONEOS_H__ 18 | #define __CANONEOS_H__ 19 | 20 | #include "WProgram.h" 21 | #include "ptp.h" 22 | 23 | // PTP Operation Codes (EOS specific) 24 | #define EOS_OC_GetStorageIDs 0x9101 25 | #define EOS_OC_GetStorageInfo 0x9102 26 | #define EOS_OC_GetObject 0x9107 27 | #define EOS_OC_GetDeviceInfoEx 0x9108 28 | #define EOS_OC_GetObjectIDs 0x9109 29 | #define EOS_OC_Capture 0x910f 30 | #define EOS_OC_SetDevicePropValue 0x9110 31 | #define EOS_OC_SetPCConnectMode 0x9114 32 | #define EOS_OC_SetExtendedEventInfo 0x9115 33 | #define EOS_OC_GetEvent 0x9116 34 | #define EOS_OC_TransferComplete 0x9117 35 | #define EOS_OC_CancelTransfer 0x9118 36 | #define EOS_OC_ResetTransfer 0x9119 37 | #define EOS_OC_GetDevicePropValue 0x9127 38 | #define EOS_OC_GetLiveViewPicture 0x9153 39 | #define EOS_OC_MoveFocus 0x9155 40 | 41 | // PTP Device Properties 42 | #define EOS_DPC_CameraDescription 0xD402 43 | 44 | // Non-PTP Device properties 45 | #define EOS_DPC_Aperture 0xD101 46 | #define EOS_DPC_ShutterSpeed 0xD102 47 | #define EOS_DPC_Iso 0xD103 48 | #define EOS_DPC_ExposureCompensation 0xD104 49 | #define EOS_DPC_ShootingMode 0xD105 50 | #define EOS_DPC_DriveMode 0xD106 51 | #define EOS_DPC_ExpMeterringMode 0xD107 52 | #define EOS_DPC_AFMode 0xD108 53 | #define EOS_DPC_WhiteBalance 0xD109 54 | #define EOS_DPC_PictureStyle 0xD110 55 | #define EOS_DPC_TransferOption 0xD111 56 | #define EOS_DPC_UnixTime 0xD113 57 | #define EOS_DPC_ImageQuality 0xD120 58 | #define EOS_DPC_LiveView 0xD1B0 59 | #define EOS_DPC_AvailableShots 0xD11B 60 | #define EOS_DPC_CaptureDestination 0xD11C 61 | #define EOS_DPC_BracketMode 0xD11D 62 | 63 | // Non-PTP Events 64 | #define EOS_EC_DevPropChanged 0xC189 65 | #define EOS_EC_ObjectCreated 0xC181 66 | #define EOS_EC_DevPropValuesAccepted 0xC18A 67 | #define EOS_EC_Capture 0xC18B 68 | #define EOS_EC_HalfPushReleaseButton 0xC18E 69 | 70 | 71 | class EOSStateHandlers : public PTPStateHandlers 72 | { 73 | public: 74 | virtual void OnSessionOpenedState(PTP *ptp); 75 | }; 76 | 77 | class ImgQualitySupplier : PTPDataSupplier 78 | { 79 | uint32_t pictFormat; 80 | 81 | public: 82 | ImgQualitySupplier() {}; 83 | void SetPictureFormat(uint32_t format) { pictFormat = format; }; 84 | virtual uint32_t GetDataSize(); 85 | virtual void GetData(const uint16_t len, uint8_t *pbuf); 86 | }; 87 | 88 | class CanonEOS : public PTP 89 | { 90 | public: 91 | enum { modeADEP=5, modeM=3, modeAv=2, modeTv=1, modeP=0, modeAuto=9, modePortrait=0xC, modeLandscape=0xD, 92 | modeMacro=0xE, modeSport=0xB, modeNight=0xA, modeFlashOff=0xF}; 93 | 94 | enum { driveSingleShot = 0, driveSelf = 1, driveContinuous = 0x10 }; 95 | 96 | enum { iso100 = 0x48, iso200 = 0x50, iso400 = 0x58, iso800 = 0x60, iso1600 = 0x68 }; 97 | 98 | enum { styleStandard = 0x81, stylePortrait, styleLandscape, styleNeutral, styleFaithful, styleMonochrome, 99 | styleUser1 = 0x21, styleUser2, styleUser3 }; 100 | 101 | enum { afmodeOneShot, afmodeAIServo, afmodeAIFocus }; 102 | 103 | enum { pictSFine = 0x00000321, pictSNormal = 0x00000221, pictMFine = 0x00000311, pictMNormal = 0x00000211, 104 | pictLFine = 0x00000301, pictLNormal = 0x00000201, pictRaw = 0x00000406, pictRawPlusL = 0x00301406 }; 105 | 106 | enum { wbAuto, wbDaylight, wbCloudy, wbTungsten, wbFluorescent, wbStrobe, wbWhitePaper, wbShade = 8 }; 107 | 108 | enum 109 | { 110 | ecPlus2 = 0x10, //"+2" 111 | ecPlus1_2d3 = 0x0d, //"+1 2/3" 112 | ecPlus1_1d3 = 0x0b, //"+1 1/3" 113 | ecPlus1 = 0x08, //"+1" 114 | ecPlus0_2d3 = 0x05, //"+2/3" 115 | ecPlus0_1d3 = 0x03, //"+1/3" 116 | ecZerro = 0x00, //"0" 117 | ecMinus0_1d3= 0xfd, //"-1/3" 118 | ecMinus0_2d3= 0xfb, //"-2/3" 119 | ecMinus1 = 0xf8, //"-1" 120 | ecMinus1_1d3= 0xf5, //"-1 1/3" 121 | ecMinus1_2d3= 0xf3, //"-1 2/3" 122 | ecMinus2 = 0xf0, //"-2" 123 | }; 124 | 125 | CanonEOS(uint8_t addr, uint8_t epin, uint8_t epout, uint8_t epint, uint8_t nconf, PTPStateHandlers *s); 126 | 127 | uint16_t SetPCConnectMode(uint8_t mode); 128 | uint16_t SetExtendedEventInfo(uint8_t mode); 129 | uint16_t Capture(); 130 | uint16_t StartBulb(); 131 | uint16_t StopBulb(); 132 | uint16_t SwitchLiveView(bool on); 133 | uint16_t MoveFocus(uint16_t step); 134 | uint16_t SetProperty(uint16_t prop, uint32_t val); 135 | 136 | uint16_t GetProperty(uint16_t prop, PTPReadParser *parser); 137 | 138 | uint16_t GetDeviceInfoEx(PTPReadParser *parser); 139 | uint16_t SetImageQuality(uint32_t format); 140 | 141 | uint16_t GetObject(uint32_t object_id, uint32_t parent_id, PTPReadParser *parser); 142 | uint16_t ResetTransfer(uint32_t object_id); 143 | uint16_t CancelTransfer(uint32_t object_id); 144 | 145 | virtual uint16_t EventCheck(PTPReadParser *parser); 146 | uint16_t DigitalZoom(uint16_t magnify); 147 | 148 | }; 149 | 150 | 151 | #endif // __CANONEOS_H__ -------------------------------------------------------------------------------- /canonps.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #include "canonps.h" 18 | 19 | void PSStateHandlers::OnSessionOpenedState(PTP *ptp) 20 | { 21 | if (FAILED(((CanonPS*)ptp)->SetDevicePropValue(PS_DPC_EventEmulateMode, (uint16_t)4)) ) 22 | PTPTRACE("EventEmulateMode error\r\n"); 23 | 24 | if (FAILED(((CanonPS*)ptp)->Initialize(true)) ) 25 | PTPTRACE("Initialization error\r\n"); 26 | 27 | ptp->SetState(PTP_STATE_DEVICE_INITIALIZED); 28 | } 29 | 30 | 31 | CanonPS::CanonPS(uint8_t addr, uint8_t epin, uint8_t epout, uint8_t epint, uint8_t nconf, PTPStateHandlers *s) 32 | : PTP(addr, epin, epout, epint, nconf, s) 33 | { 34 | } 35 | 36 | uint16_t CanonPS::EventCheck(PTPReadParser *parser) 37 | { 38 | uint16_t ptp_error = PTP_RC_GeneralError; 39 | OperFlags flags = { 0, 0, 0, 1, 1, 0 }; 40 | 41 | if ( (ptp_error = Transaction(PS_OC_CheckEvent, &flags, NULL, parser)) != PTP_RC_OK) 42 | PTPTRACE2("EOSEventCheck error: ", ptp_error); 43 | 44 | return ptp_error; 45 | } 46 | 47 | uint16_t CanonPS::Initialize(bool binit) 48 | { 49 | uint16_t ptp_error; 50 | 51 | if (binit) 52 | { 53 | if ((ptp_error = Operation(PS_OC_StartShootingMode, 0, NULL)) != PTP_RC_OK) 54 | PTPTRACE2("StartShootingMode failed: ", ptp_error); 55 | } 56 | else 57 | { 58 | if ((ptp_error = Operation(PS_OC_EndShootingMode, 0, NULL)) != PTP_RC_OK) 59 | PTPTRACE2("EndShootingMode failed: ", ptp_error); 60 | } 61 | return ptp_error; 62 | } 63 | 64 | uint16_t CanonPS::Capture() 65 | { 66 | uint16_t ptp_error; 67 | 68 | if ((ptp_error = Operation(PS_OC_FocusLock, 0, NULL)) != PTP_RC_OK) 69 | PTPTRACE2("Focus Lock Error: ", ptp_error); 70 | 71 | if ((ptp_error = Operation(PS_OC_InitiateCaptureInMemory, 0, NULL)) != PTP_RC_OK) 72 | PTPTRACE2("Capture Error: ", ptp_error); 73 | 74 | return ptp_error; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /canonps.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #ifndef __CANONPS_H__ 18 | #define __CANONPS_H__ 19 | 20 | #include "ptp.h" 21 | 22 | // PTP Operation Codes (PowerShot specific) 23 | #define PS_OC_GetObjectSize 0x9001 24 | #define PS_OC_StartShootingMode 0x9008 25 | #define PS_OC_EndShootingMode 0x9009 26 | #define PS_OC_ViewfinderOn 0x900B 27 | #define PS_OC_ViewfinderOff 0x900C 28 | #define PS_OC_ReflectChanges 0x900D 29 | #define PS_OC_CheckEvent 0x9013 30 | #define PS_OC_FocusLock 0x9014 31 | #define PS_OC_FocusUnlock 0x9015 32 | #define PS_OC_InitiateCaptureInMemory 0x901A 33 | #define PS_OC_GetPartialObject 0x901B 34 | #define PS_OC_GetViewfinderImage 0x901d 35 | #define PS_OC_GetChanges 0x9020 36 | #define PS_OC_GetFolderEntries 0x9021 37 | 38 | // PTP PowerShot Extention Events 39 | #define PS_EC_ShutDownCFDoorWasOpened 0xC001 /* The Device has shut down due to the opening of the SD card cover.*/ 40 | #define PS_EC_ResetHwError 0xC005 /* The device has generated a hardware error. */ 41 | #define PS_EC_AbortPCEvf 0xC006 /* The Viewfinder mode has been cancelled. */ 42 | #define PS_EC_EnablePCEvf 0xC007 /* The Viewfinder mode has been enablede. */ 43 | #define PS_EC_FullViewReleased 0xC008 /* Transfer timing of main image data */ 44 | #define PS_EC_ThumbnailReleased 0xC009 /* Transfer timing of thumbnail image data */ 45 | #define PS_EC_ChangeBatteryStatus 0xC00A /* The power condition of the camera has changed. */ 46 | #define PS_EC_PushedReleaseSw 0xC00B /* User has pressed the release swtich on camera. */ 47 | #define PS_EC_PropertyChanged 0xC00C /* A group of properties relating to release control have been changed. */ 48 | #define PS_EC_RotationAngleChanged 0xC00D /* The angle of rotation of the camera has been changed. */ 49 | #define PS_EC_ChangedByCamUI 0xC00E /* An operation control on the camera has been operated.*/ 50 | #define PS_EC_Shutdown 0xD001 /* Shutdown */ 51 | #define PS_EC_StartDirectTransfer 0xC011 52 | #define PS_EC_StopDirectTransfer 0xC013 53 | 54 | // PowerShot-specific Device Properties 55 | #define PS_DPC_BeepMode 0xD001 56 | #define PS_DPC_BatteryKind 0xD002 57 | #define PS_DPC_BatteryStatus 0xD003 58 | #define PS_DPC_UILockType 0xD004 59 | #define PS_DPC_CameraMode 0xD005 60 | #define PS_DPC_ImageQuality 0xD006 61 | #define PS_DPC_FullViewFileFormat 0xD007 62 | #define PS_DPC_ImageSize 0xD008 63 | #define PS_DPC_SelfTime 0xD009 64 | #define PS_DPC_FlashMode 0xD00A 65 | #define PS_DPC_Beep 0xD00B 66 | #define PS_DPC_ShootingMode 0xD00C 67 | #define PS_DPC_ImageMode 0xD00D 68 | #define PS_DPC_DriveMode 0xD00E 69 | #define PS_DPC_EZoom 0xD00F 70 | #define PS_DPC_MeteringMode 0xD010 71 | #define PS_DPC_AFDistance 0xD011 72 | #define PS_DPC_FocusingPoint 0xD012 73 | #define PS_DPC_WhiteBalance 0xD013 74 | #define PS_DPC_SlowShutterSetting 0xD014 75 | #define PS_DPC_AFMode 0xD015 76 | #define PS_DPC_ImageStabilization 0xD016 77 | #define PS_DPC_Contrast 0xD017 78 | #define PS_DPC_ColorGain 0xD018 79 | #define PS_DPC_Sharpness 0xD019 80 | #define PS_DPC_Sensitivity 0xD01A 81 | #define PS_DPC_ParameterSet 0xD01B 82 | #define PS_DPC_ISOSpeed 0xD01C 83 | #define PS_DPC_Aperture 0xD01D 84 | #define PS_DPC_ShutterSpeed 0xD01E 85 | #define PS_DPC_ExpCompensation 0xD01F 86 | #define PS_DPC_FlashCompensation 0xD020 87 | #define PS_DPC_AEBExposureCompensation 0xD021 88 | #define PS_DPC_AvOpen 0xD023 89 | #define PS_DPC_AvMax 0xD024 90 | #define PS_DPC_FocalLength 0xD025 91 | #define PS_DPC_FocalLengthTele 0xD026 92 | #define PS_DPC_FocalLengthWide 0xD027 93 | #define PS_DPC_FocalLengthDenominator 0xD028 94 | #define PS_DPC_CaptureTransferMode 0xD029 95 | #define PS_DPC_Zoom 0xD02A 96 | #define PS_DPC_NamePrefix 0xD02B 97 | #define PS_DPC_SizeQualityMode 0xD02C 98 | #define PS_DPC_SupportedThumbSize 0xD02D 99 | #define PS_DPC_SizeOfOutputDataFromCamera 0xD02E 100 | #define PS_DPC_SizeOfInputDataToCamera 0xD02F 101 | #define PS_DPC_RemoteAPIVersion 0xD030 102 | #define PS_DPC_FirmwareVersion 0xD031 103 | #define PS_DPC_CameraModel 0xD032 104 | #define PS_DPC_CameraOwner 0xD033 105 | #define PS_DPC_UnixTime 0xD034 106 | #define PS_DPC_CameraBodyID 0xD035 107 | #define PS_DPC_CameraOutput 0xD036 108 | #define PS_DPC_DispAv 0xD037 109 | #define PS_DPC_AvOpenApex 0xD038 110 | #define PS_DPC_DZoomMagnification 0xD039 111 | #define PS_DPC_MlSpotPos 0xD03A 112 | #define PS_DPC_DispAvMax 0xD03B 113 | #define PS_DPC_AvMaxApex 0xD03C 114 | #define PS_DPC_EZoomStartPosition 0xD03D 115 | #define PS_DPC_FocalLengthOfTele 0xD03E 116 | #define PS_DPC_EZoomSizeOfTele 0xD03F 117 | #define PS_DPC_PhotoEffect 0xD040 118 | #define PS_DPC_AssistLight 0xD041 119 | #define PS_DPC_FlashQuantityCount 0xD042 120 | #define PS_DPC_RotationAngle 0xD043 121 | #define PS_DPC_RotationScene 0xD044 122 | #define PS_DPC_EventEmulateMode 0xD045 123 | #define PS_DPC_DPOFVersion 0xD046 124 | #define PS_DPC_TypeOfSupportedSlideShow 0xD047 125 | #define PS_DPC_AverageFilesizes 0xD048 126 | #define PS_DPC_ModelID 0xD049 127 | 128 | 129 | class PSStateHandlers : public PTPStateHandlers 130 | { 131 | public: 132 | virtual void OnSessionOpenedState(PTP *ptp); 133 | }; 134 | 135 | 136 | 137 | class CanonPS : public PTP 138 | { 139 | public: 140 | // ISO Speed Values 141 | enum { IsoAuto = 0, Iso80 = 0x45, Iso100 = 0x48, Iso200 = 0x50, Iso400 = 0x58, Iso800=0x60 }; 142 | 143 | // White Balance Values 144 | enum { WbAuto = 0, WbSunny, WbCloudy, WbTungsten, WbFluorescent, WbFlash, WbCustom, WbUnknown }; 145 | 146 | // Exposure Compensation Values (same values for both exposure compensation and flash compensation) 147 | enum { ExpCompDown2 = 0x08, ExpCompDown1_2d3= 0x0B, ExpCompDown1_1d3= 0x0D, ExpCompDown1 = 0x10, ExpCompDown2d3 = 0x13, 148 | ExpCompDown1d3 = 0x15, ExpComp_0 = 18, ExpCompUp1d3 = 0x1B, ExpCompUp2d3 = 0x1D, ExpCompUp1 = 0x20, 149 | ExpCompUp1_1d3 = 0x23, ExpCompUp1_2d3 = 0x25, ExpCompUp2 = 0x28 }; 150 | 151 | // Image Quality Values 152 | enum { ImgQualityNormal = 2, ImageQualityFine = 3, ImageQualitySuperb = 5 }; 153 | 154 | // Image Size Values 155 | enum { ImgSizeLarge, ImgSizeMedium1, ImgSizeSmall, ImgSizeMedium2 }; 156 | 157 | CanonPS(uint8_t addr, uint8_t epin, uint8_t epout, uint8_t epint, uint8_t nconf, PTPStateHandlers *s); 158 | 159 | uint16_t Initialize(bool binit); 160 | 161 | uint16_t Capture(); 162 | uint16_t EventCheck(PTPReadParser *parser); 163 | }; 164 | 165 | #endif // __CANONPS_H__ -------------------------------------------------------------------------------- /copying.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | -------------------------------------------------------------------------------- /examples/EOSBulb/EOSBulb.pde: -------------------------------------------------------------------------------- 1 | /* Bulb mode demo */ 2 | /* Works with cameras which have bulb mode in shutter speed list (in other words, ones that don't have a letter 'B' on mode dial */ 3 | /* Tested with EOS Rebel XSI (450D) */ 4 | /* Camera has to be switched to manual mode */ 5 | 6 | #include 7 | #include 8 | 9 | //#include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #define DEV_ADDR 1 19 | 20 | // Canon EOS 450D 21 | #define DATA_IN_EP 1 22 | #define DATA_OUT_EP 2 23 | #define INTERRUPT_EP 3 24 | #define CONFIG_NUM 1 25 | 26 | #define SHUTTER_SPEED_BULB 0x0c 27 | 28 | class CamStateHandlers : public EOSStateHandlers 29 | { 30 | enum CamStates { stInitial, stDisconnected, stConnected }; 31 | CamStates stateConnected; 32 | 33 | public: 34 | CamStateHandlers() : stateConnected(stInitial) 35 | { 36 | }; 37 | 38 | virtual void OnDeviceDisconnectedState(PTP *ptp); 39 | virtual void OnDeviceInitializedState(PTP *ptp); 40 | } CamStates; 41 | 42 | CanonEOS Eos(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 43 | 44 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 45 | { 46 | if (stateConnected == stConnected || stateConnected == stInitial) 47 | { 48 | stateConnected = stDisconnected; 49 | Notify(PSTR("Camera disconnected\r\n")); 50 | } 51 | } 52 | 53 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 54 | { 55 | if (stateConnected == stDisconnected) 56 | { 57 | stateConnected = stConnected; 58 | 59 | uint16_t rc = Eos.SetProperty(EOS_DPC_ShutterSpeed,SHUTTER_SPEED_BULB); 60 | 61 | if (rc != PTP_RC_OK) 62 | Message(PSTR("Error: "), rc); 63 | } 64 | 65 | Eos.StartBulb(); 66 | delay(6000); 67 | Eos.StopBulb(); 68 | } 69 | 70 | void setup() 71 | { 72 | Serial.begin( 115200 ); 73 | Serial.println("Start"); 74 | Eos.Setup(); 75 | delay( 200 ); 76 | } 77 | 78 | void loop() { 79 | Eos.Task(); 80 | } 81 | -------------------------------------------------------------------------------- /examples/EOSCamController/camcontroller.h: -------------------------------------------------------------------------------- 1 | /* Camera controller header */ 2 | #ifndef __CAMCONTROLLER_H__ 3 | #define __CAMCONTROLLER_H__ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include "menu.h" 11 | 12 | const char msgSetSelf[] PROGMEM = "SELF"; 13 | const char msgSetFrames[] PROGMEM = "FRMS"; 14 | const char msgSetBkt[] PROGMEM = "BKT"; 15 | const char msgSetInterval[] PROGMEM = "INT"; 16 | const char msgExit[] PROGMEM = "EXIT"; 17 | const char msgSetRun[] PROGMEM = "RUN "; 18 | const char msgAbort[] PROGMEM = "ABORT"; 19 | const char msgLeft[] PROGMEM = "LEFT"; 20 | 21 | const char msgError[] PROGMEM = "ERROR:"; 22 | const char msgCamera[] PROGMEM = "CAMERA"; 23 | const char msgDisconnected[] PROGMEM = "DISCONNECTED"; 24 | 25 | const char msgSelfTimer[] PROGMEM = "SELF TIMER h/m/s"; 26 | const char msgBracketing[] PROGMEM = "BKT(RANGE/STEP)"; 27 | const char msgSteps[] PROGMEM = "steps"; 28 | const char msgCntFrames[] PROGMEM = "FRAMES"; 29 | const char msgIntTimer[] PROGMEM = "INT TIMER h/m/s"; 30 | const char msgIntervalometer[] PROGMEM = "INTERVAL"; 31 | const char msgSettings[] PROGMEM = "SETTINGS"; 32 | const char msgClock[] PROGMEM = "CLOCK"; 33 | const char msgEV[] PROGMEM = "EV"; 34 | 35 | typedef KeyValuePairDataItem EXP_COMP_DATA_ITEM; // Exposure compensation data item type 36 | typedef SRAMValueList BKT_STEP_VALUE_LIST; // Bracketing step value list type 37 | 38 | //--- Data Item Types --------------------------------------------------------- 39 | typedef KeyValuePairDataItem DIT_MODE; 40 | typedef KeyValuePairDataItem DIT_APERTURE; 41 | typedef KeyValuePairDataItem DIT_WB; 42 | typedef KeyValuePairDataItem DIT_SHUTTER_SPEED; 43 | typedef KeyValuePairDataItem DIT_PSTYLE; 44 | typedef KeyValuePairDataItem DIT_ISO; 45 | typedef KeyValuePairDataItem DIT_EXPCOMP; 46 | typedef IntDataItem DIT_TIMER_DIGIT_PAIR; 47 | 48 | 49 | #endif //__CAMCONTROLLER_H__ 50 | -------------------------------------------------------------------------------- /examples/EOSCamController/controls.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "controls.h" 3 | 4 | StateMachine* StateMachine::currentState = NULL; 5 | 6 | void GPInRegister::CheckControls() 7 | { 8 | int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; 9 | ControlStates previous = controlStates; 10 | controlStates = (pMax->gpioRd() & (GPIN_ENCODER_MASK | GPIN_ENC_BUT_MASK | GPIN_EXT_BUT_MASK)); 11 | ControlStates changes = (previous ^ controlStates); 12 | 13 | if (previous == controlStates) 14 | return; 15 | 16 | ControlEvents *state_machine = (ControlEvents*)StateMachine::GetState(); 17 | 18 | if ((changes & GPIN_ENCODER_MASK)) 19 | { 20 | uint8_t encoder = (previous & GPIN_ENCODER_MASK); 21 | encoder <<= 2; 22 | encoder |= (controlStates & GPIN_ENCODER_MASK); 23 | encoderValue += enc_states[(encoder & 0x0f)]; 24 | 25 | if (encoderValue > 3 || encoderValue < -3) 26 | { 27 | if (state_machine) 28 | state_machine->OnEncoderChanged(encoderValue >> 2); 29 | encoderValue = 0; 30 | } 31 | } 32 | if (!state_machine) 33 | return; 34 | 35 | if ((changes & GPIN_ENC_BUT_MASK)) 36 | { 37 | if ((controlStates & GPIN_ENC_BUT_MASK)) 38 | state_machine->OnEncButtonUp(); 39 | else 40 | state_machine->OnEncButtonDown(); 41 | } 42 | if ((changes & GPIN_EXT_BUT_MASK)) 43 | { 44 | if ((controlStates & GPIN_EXT_BUT_MASK)) 45 | state_machine->OnExtButtonUp(); 46 | else 47 | state_machine->OnExtButtonDown(); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /examples/EOSCamController/controls.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONTROLS_H__ 2 | #define __CONTROLS_H__ 3 | 4 | #include 5 | #include 6 | 7 | class StateMachine 8 | { 9 | static StateMachine *currentState; 10 | 11 | protected: 12 | virtual bool OnInitialState() { return true; }; 13 | 14 | public: 15 | static void SetState(StateMachine *state) { currentState = state; currentState->OnInitialState(); }; 16 | static StateMachine* GetState() { return StateMachine::currentState; }; 17 | }; 18 | 19 | class ControlEvents : public StateMachine 20 | { 21 | public: 22 | virtual bool OnEncoderChanged(int8_t value) { return true; }; 23 | virtual bool OnEncButtonUp() { return true; }; 24 | virtual bool OnEncButtonDown() { return true; }; 25 | virtual bool OnExtButtonUp() { return true; }; 26 | virtual bool OnExtButtonDown() { return true; }; 27 | }; 28 | 29 | #define GPIN_ENCODER_MASK 0x03 30 | #define GPIN_ENC_BUT_MASK 0x08 31 | #define GPIN_EXT_BUT_MASK 0x10 32 | 33 | #define GPIN_ENC_BUT_MASK 0x04 34 | #define GPIN_EXT_BUT_MASK 0x08 35 | 36 | 37 | typedef uint8_t ControlStates; 38 | 39 | class GPInRegister 40 | { 41 | ControlStates controlStates; 42 | MAX3421E *pMax; 43 | int8_t encoderValue; 44 | 45 | public: 46 | GPInRegister(MAX3421E *pmax) : controlStates(GPIN_ENCODER_MASK | GPIN_ENC_BUT_MASK | GPIN_EXT_BUT_MASK), pMax(pMax), encoderValue(0) {}; 47 | void CheckControls(); 48 | }; 49 | 50 | #endif // __CONTROLS_H__ 51 | -------------------------------------------------------------------------------- /examples/EOSCamController/dataitem.cpp: -------------------------------------------------------------------------------- 1 | #include "dataitem.h" 2 | 3 | char TimeSpanDataItem::textValue[9] = ""; 4 | char TimerDataItem::textValue[9] = ""; 5 | 6 | char* itoa2(int val, uint8_t buf_size, char *buf, int8_t base, char c) 7 | { 8 | char sign = (val < 0) ? '-' : c; 9 | buf[buf_size-1] = 0; 10 | 11 | int8_t i = buf_size-2; 12 | 13 | for(; val && i ; --i, val /= base) 14 | buf[i] = "0123456789abcdef"[(val < 0) ? -(val % base) : val % base]; 15 | 16 | for (; i > 0; i--) 17 | buf[i] = c; 18 | 19 | buf[0] = sign; 20 | return buf; 21 | } 22 | 23 | char* itoa2(uint8_t val, uint8_t buf_size, char *buf, int8_t base, char c) 24 | { 25 | buf[buf_size-1] = 0; 26 | 27 | int8_t i = buf_size-2; 28 | 29 | for(; val && i>=0 ; --i, val /= base) 30 | buf[i] = "0123456789abcdef"[(val < 0) ? -(val % base) : val % base]; 31 | 32 | for (; i >= 0; i--) 33 | buf[i] = c; 34 | 35 | return buf; 36 | } 37 | 38 | char* itoa2(uint16_t val, uint8_t buf_size, char *buf, int8_t base, char c) 39 | { 40 | buf[buf_size-1] = 0; 41 | 42 | int8_t i = buf_size-2; 43 | 44 | for(; val && i>=0 ; --i, val /= base) 45 | buf[i] = "0123456789abcdef"[val % base]; 46 | 47 | for (; i >= 0; i--) 48 | buf[i] = c; 49 | 50 | return buf; 51 | } 52 | -------------------------------------------------------------------------------- /examples/EOSCamController/dataitem.h: -------------------------------------------------------------------------------- 1 | #if !defined(__DATAITEM_H__) 2 | #define __DATAITEM_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define MUL10( a ) (((a) << 3 ) + ((a) << 1 )) 10 | 11 | char* itoa2(int val, uint8_t buf_size, char *buf, int8_t base, char c); 12 | char* itoa2(uint8_t val, uint8_t buf_size, char *buf, int8_t base, char c); 13 | char* itoa2(uint16_t val, uint8_t buf_size, char *buf, int8_t base, char c); 14 | 15 | class DataItemBase 16 | { 17 | protected: 18 | bool isUpdated; 19 | 20 | public: 21 | virtual void GetText(char** str, bool &is_pgm) = 0; 22 | 23 | bool IsUpdated() { return isUpdated; }; 24 | void SetUpdated(bool upd) { isUpdated = upd; }; 25 | }; 26 | 27 | class TimeSpanDataItem : public DataItemBase 28 | { 29 | uint32_t dataValue; 30 | 31 | static char textValue[9]; 32 | 33 | public: 34 | TimeSpanDataItem(uint32_t s) : dataValue(s) {}; 35 | 36 | virtual void GetText(char** str, bool &is_pgm) 37 | { 38 | { 39 | uint16_t h = dataValue / 3600; 40 | itoa2((uint16_t) h, 3, (char*)&textValue, 10, '0'); 41 | } 42 | { 43 | textValue[2] = ':'; 44 | uint16_t s = dataValue % 3600; 45 | itoa2((uint16_t) s / 60, 3, (char*)(textValue+3), 10, '0'); 46 | textValue[5] = ':'; 47 | itoa2((uint16_t) s % 60, 3, (char*)(textValue+6), 10, '0'); 48 | } 49 | *str = textValue; 50 | is_pgm = false; 51 | }; 52 | virtual void Set(uint32_t &val) 53 | { 54 | dataValue = val; 55 | isUpdated = true; 56 | }; 57 | }; 58 | 59 | #define MUL60( a ) (((a) << 6 ) - ((a) << 2 )) 60 | #define MUL3600( a ) (((a) << 12 ) - ((a) << 9 ) + ((a) << 4 )) 61 | 62 | class TimerDataItem : public DataItemBase 63 | { 64 | SimpleTimer &dataValue; 65 | 66 | static char textValue[9]; 67 | 68 | public: 69 | TimerDataItem(SimpleTimer &t) : dataValue(t) {}; 70 | 71 | virtual void GetText(char** str, bool &is_pgm) 72 | { 73 | uint16_t time_left = dataValue.TimeLeft() / 1000; 74 | 75 | uint16_t ss = time_left % 60; 76 | time_left /= 60; 77 | uint16_t mm = time_left % 60; 78 | time_left /= 60; 79 | uint16_t hh = time_left; 80 | 81 | itoa2((uint16_t)hh, 3, (char*)&textValue, 10, '0'); 82 | textValue[2] = ':'; 83 | itoa2((uint16_t)mm, 3, (char*)(textValue+3), 10, '0'); 84 | textValue[5] = ':'; 85 | itoa2((uint16_t)ss, 3, (char*)(textValue+6), 10, '0'); 86 | *str = textValue; 87 | is_pgm = false; 88 | }; 89 | 90 | }; 91 | 92 | template 93 | class KeyValuePairDataItem : public DataItemBase 94 | { 95 | VALUE_TYPE dataValue; 96 | const ValueTitle *ptrTitles; 97 | 98 | public: 99 | KeyValuePairDataItem(VALUE_TYPE val, const ValueTitle *p) : dataValue(val), ptrTitles(p) 100 | {}; 101 | 102 | virtual void GetText(char** str, bool &is_pgm) 103 | { 104 | *str = (char*)FindTitle(TABLE_SIZE, ptrTitles, dataValue); 105 | is_pgm = true; 106 | }; 107 | 108 | VALUE_TYPE Get() { return dataValue; }; 109 | void Set(VALUE_TYPE val) { dataValue = val; isUpdated = true; }; 110 | }; 111 | 112 | template 113 | class IntDataItem : public DataItemBase 114 | { 115 | VALUE_TYPE dataValue; 116 | static char valString[TEXT_LEN]; 117 | 118 | public: 119 | IntDataItem() : dataValue(0) { isUpdated = true; }; 120 | IntDataItem(VALUE_TYPE data) : dataValue(data) {}; 121 | 122 | virtual void Set(VALUE_TYPE data) 123 | { 124 | dataValue = data; 125 | isUpdated = true; 126 | }; 127 | 128 | VALUE_TYPE Get() { return dataValue; }; 129 | 130 | virtual void GetText(char** str, bool &is_pgm) 131 | { 132 | *str = itoa2(dataValue, TEXT_LEN, (char*)&valString, 10, '0'); 133 | is_pgm = false; 134 | }; 135 | void operator ++(int val) 136 | { 137 | dataValue += val; 138 | isUpdated = true; 139 | }; 140 | void operator --(int val) 141 | { 142 | dataValue -= val; 143 | isUpdated = true; 144 | }; 145 | }; 146 | 147 | template 148 | char IntDataItem::valString[TEXT_LEN] = ""; 149 | 150 | class PgmStringDataItem : public DataItemBase 151 | { 152 | const char *pStr; 153 | 154 | public: 155 | PgmStringDataItem(const char *str) : pStr(str) { isUpdated = true; }; 156 | 157 | void SetText(const char *str) { pStr = str; isUpdated = true; }; 158 | 159 | virtual void GetText(char** str, bool &is_pgm) 160 | { 161 | *str = (char*)pStr; 162 | is_pgm = true; 163 | }; 164 | }; 165 | 166 | template 167 | class StringDataItem : public DataItemBase 168 | { 169 | char theString[STRLEN]; 170 | 171 | void CopyString(char *src, char *dst) 172 | { 173 | char *s = src, *d = dst; 174 | 175 | for (uint8_t cnt = 0; *s && cnt < STRLEN-1; cnt++, s++, d++) 176 | *d = *s; 177 | 178 | *d = 0; 179 | }; 180 | public: 181 | StringDataItem() { theString[0] = 0; isUpdated = true; }; 182 | StringDataItem(char *str) { CopyString(str, &theString); isUpdated = true; }; 183 | 184 | void SetText(char *str) { CopyString(str, &theString); isUpdated = true; }; 185 | 186 | virtual void GetText(char** str, bool &is_pgm) 187 | { 188 | *str = &theString; 189 | is_pgm = false; 190 | }; 191 | }; 192 | 193 | 194 | #endif // __DATAITEM_H__ 195 | -------------------------------------------------------------------------------- /examples/EOSCamController/eoseventparser.cpp: -------------------------------------------------------------------------------- 1 | #include "eoseventparser.h" 2 | #include "dataitem.h" 3 | #include "camcontroller.h" 4 | 5 | extern DIT_MODE diMode; 6 | extern DIT_APERTURE diAperture; 7 | extern DIT_WB diWb; 8 | extern DIT_SHUTTER_SPEED diShutterSpeed; 9 | extern DIT_PSTYLE diPStyle; 10 | extern DIT_ISO diIso; 11 | extern DIT_EXPCOMP diExpComp; 12 | 13 | extern EEPROMByteList vlAperture; 14 | extern EEPROMByteList vlShutterSpeed; 15 | extern EEPROMByteList vlWhiteBalance; 16 | extern EEPROMByteList vlPictureStyle; 17 | extern EEPROMByteList vlExpCompensation; 18 | extern EEPROMByteList vlIso; 19 | 20 | bool EOSEventParser::EventRecordParse(uint8_t **pp, uint16_t *pcntdn) 21 | { 22 | switch (nRecStage) 23 | { 24 | case 0: 25 | // Retrieves the size of the event record 26 | if (!valueParser.Parse(pp, pcntdn)) 27 | return false; 28 | 29 | nRecSize = (uint16_t)varBuffer; 30 | 31 | // calculates the number of event parameters ( size / 4 - 1 ) 32 | paramCountdown = (nRecSize >> 2) - 1; 33 | 34 | paramCount = 1; 35 | nRecSize -= 4; 36 | nRecStage ++; 37 | case 1: 38 | for (; paramCountdown; paramCountdown--, paramCount++, nRecSize -= 4) 39 | { 40 | if (!valueParser.Parse(pp, pcntdn)) 41 | return false; 42 | 43 | switch (paramCount) 44 | { 45 | // Event Code 46 | case 1: 47 | eosEvent.eventCode = (uint16_t)varBuffer; 48 | break; 49 | // Property Code 50 | case 2: 51 | // if (eosEvent.eventCode == EOS_EC_ObjectCreated) 52 | // { 53 | // } 54 | eosEvent.propCode = (uint16_t)varBuffer; 55 | break; 56 | // C189 - Property Value, C18A - Enumerator Type 57 | case 3: 58 | eosEvent.propValue = varBuffer; 59 | 60 | if (eosEvent.eventCode == EOS_EC_DevPropChanged) 61 | { 62 | 63 | switch (eosEvent.propCode) 64 | { 65 | case EOS_DPC_Aperture: 66 | diAperture.Set(varBuffer); 67 | break; 68 | case EOS_DPC_ShutterSpeed: 69 | diShutterSpeed.Set(varBuffer); 70 | break; 71 | case EOS_DPC_ShootingMode: 72 | diMode.Set(varBuffer); 73 | break; 74 | case EOS_DPC_WhiteBalance: 75 | diWb.Set(varBuffer); 76 | break; 77 | case EOS_DPC_PictureStyle: 78 | diPStyle.Set(varBuffer); 79 | break; 80 | case EOS_DPC_Iso: 81 | diIso.Set(varBuffer); 82 | break; 83 | case EOS_DPC_ExposureCompensation: 84 | diExpComp.Set(varBuffer); 85 | break; 86 | }; 87 | } 88 | break; 89 | // C18A/enumType == 3 - Size of enumerator array 90 | case 4: 91 | if (eosEvent.eventCode == EOS_EC_DevPropValuesAccepted) 92 | { 93 | switch (eosEvent.propCode) 94 | { 95 | case EOS_DPC_Aperture: 96 | vlAperture.SetSize((uint8_t)varBuffer); 97 | break; 98 | case EOS_DPC_ShutterSpeed: 99 | vlShutterSpeed.SetSize((uint8_t)varBuffer); 100 | break; 101 | case EOS_DPC_WhiteBalance: 102 | vlWhiteBalance.SetSize((uint8_t)varBuffer); 103 | break; 104 | case EOS_DPC_PictureStyle: 105 | vlPictureStyle.SetSize((uint8_t)varBuffer); 106 | break; 107 | case EOS_DPC_Iso: 108 | vlIso.SetSize((uint8_t)varBuffer); 109 | break; 110 | case EOS_DPC_ExposureCompensation: 111 | vlExpCompensation.SetSize((uint8_t)varBuffer); 112 | break; 113 | }; 114 | } 115 | break; 116 | // C18A/enumType == 3 - Enumerator Values 117 | default: 118 | if (eosEvent.eventCode == EOS_EC_DevPropValuesAccepted) 119 | { 120 | switch (eosEvent.propCode) 121 | { 122 | case EOS_DPC_Aperture: 123 | vlAperture.Set(paramCount-5, (uint8_t)varBuffer); 124 | break; 125 | case EOS_DPC_ShutterSpeed: 126 | vlShutterSpeed.Set(paramCount-5, (uint8_t)varBuffer); 127 | break; 128 | case EOS_DPC_WhiteBalance: 129 | vlWhiteBalance.Set(paramCount-5, (uint8_t)varBuffer); 130 | break; 131 | case EOS_DPC_PictureStyle: 132 | vlPictureStyle.Set(paramCount-5, (uint8_t)varBuffer); 133 | break; 134 | case EOS_DPC_ExposureCompensation: 135 | vlExpCompensation.Set(paramCount-5, (uint8_t)varBuffer); 136 | break; 137 | case EOS_DPC_Iso: 138 | vlIso.Set(paramCount-5, (uint8_t)varBuffer); 139 | break; 140 | } // switch (eosEvent.propCode) 141 | } 142 | } // switch (paramCount) 143 | } // for 144 | nRecStage ++; 145 | case 2: 146 | if (nRecSize) 147 | if (!byteSkipper.Skip(pp, pcntdn, nRecSize)) 148 | return false; 149 | 150 | nRecSize = 0; 151 | nRecStage = 0; 152 | } 153 | return true; 154 | } 155 | 156 | void EOSEventParser::InitEOSEventStruct() 157 | { 158 | eosEvent.eventCode = constInitialEventCode; 159 | eosEvent.propCode = 0; 160 | eosEvent.propValue = 0; 161 | } 162 | 163 | 164 | void EOSEventParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) 165 | { 166 | uint8_t *p = (uint8_t*) pbuf; 167 | uint16_t cntdn = len; 168 | 169 | switch (nStage) 170 | { 171 | case 0: 172 | p += 12; 173 | cntdn -= 12; 174 | nStage ++; 175 | case 1: 176 | theBuffer.valueSize = 4; 177 | valueParser.Initialize(&theBuffer); 178 | InitEOSEventStruct(); 179 | nStage ++; 180 | case 2: 181 | while (1) 182 | { 183 | if (!EventRecordParse(&p, &cntdn)) 184 | return; 185 | if (IsLastEventRecord()) 186 | break; 187 | InitEOSEventStruct(); 188 | } 189 | nStage = 0; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /examples/EOSCamController/eoseventparser.h: -------------------------------------------------------------------------------- 1 | #ifndef __EOSEVENTPARSER_H__ 2 | #define __EOSEVENTPARSER_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | struct EOSParamValues 12 | { 13 | uint8_t upperValue; 14 | uint8_t currentValue; 15 | uint8_t lowerValue; 16 | }; 17 | 18 | #define MAX_OBJ_IN_LIST 8 19 | 20 | class EOSEventParser : public PTPReadParser 21 | { 22 | const uint16_t constInitialEventCode; 23 | 24 | uint8_t paramsChanged; 25 | 26 | struct EOSEvent 27 | { 28 | uint16_t eventCode; 29 | uint16_t propCode; 30 | uint32_t propValue; 31 | }; 32 | 33 | uint8_t nStage; 34 | uint8_t nRecStage; 35 | uint16_t nRecSize; 36 | MultiValueBuffer theBuffer; 37 | uint32_t varBuffer; 38 | EOSEvent eosEvent; 39 | uint16_t paramCountdown; 40 | uint16_t paramCount; 41 | 42 | MultiByteValueParser valueParser; 43 | ByteSkipper byteSkipper; 44 | 45 | bool EventRecordParse(uint8_t **pp, uint16_t *pcntdn); 46 | bool IsLastEventRecord() { return (eosEvent.eventCode == 0); }; 47 | void InitEOSEventStruct(); 48 | 49 | public: 50 | EOSEventParser() : 51 | constInitialEventCode(0xFFFF), 52 | nStage(0), 53 | nRecStage(0), 54 | nRecSize(0), 55 | varBuffer(0), 56 | paramCountdown(0), 57 | paramsChanged(0) 58 | { 59 | theBuffer.pValue = &varBuffer; 60 | }; 61 | 62 | void Reset() 63 | { 64 | nStage = 0; 65 | nRecStage = 0; 66 | nRecSize = 0; 67 | varBuffer = 0; 68 | paramCountdown = 0; 69 | paramsChanged = 0; 70 | }; 71 | 72 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 73 | }; 74 | 75 | #endif // __EOSEVENTPARSER_H__ 76 | -------------------------------------------------------------------------------- /examples/EOSCamController/expcomp_macro.h: -------------------------------------------------------------------------------- 1 | extern EEPROMByteList vlExpCompensation; 2 | 3 | #define EXP_COMP_VALUE(i)((uint32_t)vlExpCompensation.Get((i))) 4 | -------------------------------------------------------------------------------- /examples/EOSCamController/hdrcapture.h: -------------------------------------------------------------------------------- 1 | #if !defined(__HDRCAPTURE_H__) 2 | #define __HDRCAPTURE_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define PTP_TIMEOUT 250 13 | 14 | #define TA_PTP_TIMEOUT 0x00 15 | #define TA_SELF_TIMER 0x03 16 | #define TA_INTR_TIMER 0x05 17 | #define TA_BULB_TIMER 0x07 18 | 19 | enum HDRCaptureSignals 20 | { 21 | TICK_MILLIS_SIG = Q_USER_SIG, 22 | SET_FRAMES_SIG, 23 | SET_SELF_TIMEOUT_SIG, 24 | SET_FRAME_TIMEOUT_SIG, 25 | SET_BRACKETING_SIG, 26 | RUN_SIG, 27 | ABORT_SIG, 28 | TIMEOUT_SIG, 29 | SET_TIMEOUT_SIG, 30 | PTP_RC_SIG, 31 | PTP_RC_OK_SIG 32 | }; 33 | 34 | struct SetTimeoutEvt : public QEvent 35 | { 36 | uint32_t timeout; 37 | uint8_t attribs; 38 | }; 39 | 40 | struct SetEvt : public QEvent 41 | { 42 | uint32_t value; 43 | }; 44 | 45 | struct SetBktEvt : public QEvent 46 | { 47 | uint8_t step; 48 | uint8_t negative; 49 | uint8_t positive; 50 | }; 51 | 52 | struct PTP_RC_Evt : public QEvent 53 | { 54 | uint16_t rc; 55 | }; 56 | 57 | class HDRCapture : public QHsm 58 | { 59 | uint16_t frmCntdn; 60 | uint16_t frmCount; 61 | uint32_t selfTimeout; 62 | uint32_t frameTimeout; 63 | uint8_t bktStep; 64 | uint8_t bktNegative; 65 | uint8_t bktPositive; 66 | uint8_t bktCntdn; 67 | uint8_t bktPos; 68 | uint8_t bktOldVal; 69 | 70 | CanonEOS &Eos; 71 | 72 | SetTimeoutEvt toEvt; 73 | PTP_RC_Evt rcEvt; 74 | QEvent qpEvt; 75 | 76 | QStateHandler activeHistory; 77 | 78 | SimpleFIFO theQueue; 79 | 80 | public: 81 | HDRCapture(CanonEOS &eos) : 82 | QHsm((QStateHandler)&HDRCapture::Initial), 83 | frmCount(0), 84 | frmCntdn(0), 85 | selfTimeout(0), 86 | frameTimeout(0), 87 | bktStep(0), 88 | bktNegative(0), 89 | bktPositive(0), 90 | bktCntdn(0), 91 | bktPos(0), 92 | bktOldVal(0), 93 | Eos(eos), 94 | activeHistory(NULL) 95 | { 96 | toEvt.sig = SET_TIMEOUT_SIG; 97 | rcEvt.sig = PTP_RC_SIG; 98 | }; 99 | void PostEvent(QEvent *e) 100 | { 101 | theQueue.Push(e); 102 | }; 103 | void Run() 104 | { 105 | QEvent *e = NULL; 106 | 107 | while ( (e = theQueue.Pop()) ) 108 | dispatch(e); 109 | }; 110 | 111 | protected: 112 | static QState Initial(HDRCapture *me, QEvent const *e); 113 | static QState Inactive(HDRCapture *me, QEvent const *e); 114 | static QState Active(HDRCapture *me, QEvent const *e); 115 | static QState SelfTimer(HDRCapture *me, QEvent const *e); 116 | static QState PreCapture(HDRCapture *me, QEvent const *e); 117 | static QState Capture(HDRCapture *me, QEvent const *e); 118 | static QState PostCapture(HDRCapture *me, QEvent const *e); 119 | static QState ExpCompSet(HDRCapture *me, QEvent const *e); 120 | static QState SaveSettings(HDRCapture *me, QEvent const *e); 121 | static QState RestoreSettings(HDRCapture *me, QEvent const *e); 122 | static QState Timeout(HDRCapture *me, QEvent const *e); 123 | 124 | virtual void OnFrameCaptured(uint16_t left) {}; 125 | virtual void OnBktFrameCaptured(uint16_t left) {}; 126 | virtual void OnSelfTimerProgress(uint32_t left) {}; 127 | virtual void OnIntrTimerProgress(uint32_t left) {}; 128 | }; 129 | 130 | #endif // __HDRCAPTURE_H__ 131 | -------------------------------------------------------------------------------- /examples/EOSCamController/menu.cpp: -------------------------------------------------------------------------------- 1 | #include "menu.h" 2 | 3 | bool Menu::OnInitialState() 4 | { 5 | menuItems[itemSelected].screenItem->Highlight(true); 6 | Screen::Set(screenId); 7 | return true; 8 | }; 9 | 10 | bool Menu::OnEncoderChanged(int8_t value) 11 | { 12 | menuItems[itemSelected].screenItem->Highlight(false); 13 | 14 | int8_t new_val = (int8_t)itemSelected + value; 15 | 16 | if (new_val < 0) 17 | itemSelected = 0; 18 | else if (new_val >= numItems) 19 | itemSelected = numItems - 1; 20 | else 21 | itemSelected = (uint8_t)new_val; 22 | 23 | menuItems[itemSelected].screenItem->Highlight(true); 24 | 25 | return true; 26 | }; 27 | 28 | bool Menu::OnEncButtonDown() 29 | { 30 | if (menuItems[itemSelected].ptrFunction) 31 | (menuItems[itemSelected].ptrFunction)(); 32 | }; 33 | 34 | bool Menu::OnExtButtonDown() 35 | { 36 | if (returnState) 37 | StateMachine::SetState(returnState); 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /examples/EOSCamController/menu.h: -------------------------------------------------------------------------------- 1 | #if !defined(__MENU_H__) 2 | #define __MENU_H__ 3 | 4 | #include 5 | #include "screenitem.h" 6 | #include "screen.h" 7 | #include "controls.h" 8 | 9 | typedef void (*MenuFunctionPtr)(); 10 | 11 | struct MenuItem 12 | { 13 | ScreenItem *screenItem; 14 | MenuFunctionPtr ptrFunction; 15 | }; 16 | 17 | class Menu : public ControlEvents 18 | { 19 | uint8_t numItems; 20 | uint8_t itemSelected; 21 | uint8_t screenId; 22 | MenuItem *menuItems; 23 | StateMachine *returnState; 24 | 25 | public: 26 | Menu(uint8_t scr, uint8_t num_items, MenuItem *items, uint8_t sel = 0, StateMachine *s = NULL) : 27 | screenId(scr), 28 | numItems(num_items), 29 | menuItems(items), 30 | itemSelected(sel), 31 | returnState(s) 32 | {}; 33 | 34 | void SetReturnState(StateMachine *s) { returnState = s; }; 35 | 36 | virtual bool OnInitialState(); 37 | virtual bool OnEncoderChanged(int8_t value); 38 | virtual bool OnEncButtonDown(); 39 | virtual bool OnExtButtonDown(); 40 | }; 41 | 42 | typedef void (*SpinFunction)(DataItemBase *data_item); 43 | 44 | template 45 | class IntSpin : public ControlEvents 46 | { 47 | VALUE_TYPE minValue; 48 | VALUE_TYPE maxValue; 49 | VALUE_TYPE incValue; 50 | 51 | ITEM_TYPE *dataItem; 52 | StateMachine *returnState; 53 | SpinFunction pFunction; 54 | 55 | public: 56 | IntSpin(VALUE_TYPE min_val, VALUE_TYPE max_val, VALUE_TYPE inc_val, ITEM_TYPE *item, SpinFunction f) : 57 | minValue(min_val), 58 | maxValue(max_val), 59 | incValue(inc_val), 60 | dataItem(item), 61 | returnState(NULL), 62 | pFunction(f) 63 | { 64 | }; 65 | 66 | void SetConstraints(VALUE_TYPE min_val, VALUE_TYPE max_val, VALUE_TYPE inc_val) 67 | { 68 | minValue = min_val; 69 | maxValue = max_val; 70 | incValue = inc_val; 71 | }; 72 | 73 | void SetReturnState(StateMachine *s) { returnState = s; }; 74 | 75 | virtual bool OnEncoderChanged(int8_t value) 76 | { 77 | int16_t new_val = dataItem->Get() + value * incValue; 78 | 79 | if (new_val > maxValue) 80 | new_val = maxValue; 81 | else if (new_val < minValue) 82 | new_val = minValue; 83 | 84 | dataItem->Set((VALUE_TYPE)new_val); 85 | dataItem->SetUpdated(true); 86 | 87 | return true; 88 | }; 89 | 90 | virtual bool OnEncButtonDown() 91 | { 92 | if (pFunction) 93 | pFunction((DataItemBase*)dataItem); 94 | 95 | if (returnState) 96 | StateMachine::SetState(returnState); 97 | return true; 98 | }; 99 | }; 100 | 101 | template 102 | class EEPROMListIntSpin : public ControlEvents 103 | { 104 | EEPROMByteList *valueList; 105 | ITEM_TYPE *dataItem; 106 | StateMachine *returnState; 107 | SpinFunction pFunction; 108 | 109 | public: 110 | EEPROMListIntSpin(EEPROMByteList *list, ITEM_TYPE *item, SpinFunction pf) : 111 | valueList(list), 112 | dataItem(item), 113 | returnState(NULL), 114 | pFunction(pf) 115 | { 116 | }; 117 | 118 | void SetReturnState(StateMachine *s) { returnState = s; }; 119 | 120 | virtual bool OnEncoderChanged(int8_t value) 121 | { 122 | if (valueList->GetSize() < 1) 123 | return true; 124 | 125 | VALUE_TYPE new_value; 126 | 127 | if (value < 0) 128 | new_value = valueList->GetPrev(dataItem->Get(), -value); 129 | else 130 | new_value = valueList->GetNext(dataItem->Get(), value); 131 | 132 | dataItem->Set(new_value); 133 | dataItem->SetUpdated(true); 134 | 135 | return true; 136 | }; 137 | 138 | virtual bool OnEncButtonDown() 139 | { 140 | if (pFunction) 141 | pFunction((DataItemBase*)dataItem); 142 | 143 | if (returnState) 144 | StateMachine::SetState(returnState); 145 | 146 | return true; 147 | }; 148 | }; 149 | 150 | 151 | template 152 | class SRAMListIntSpin : public ControlEvents 153 | { 154 | VALUE_LIST_TYPE *valueList; 155 | ITEM_TYPE *dataItem; 156 | StateMachine *returnState; 157 | SpinFunction pFunction; 158 | 159 | public: 160 | SRAMListIntSpin(VALUE_LIST_TYPE *list, ITEM_TYPE *item, SpinFunction pf) : 161 | valueList(list), 162 | dataItem(item), 163 | returnState(NULL), 164 | pFunction(pf) 165 | { 166 | }; 167 | 168 | void SetReturnState(StateMachine *s) { returnState = s; }; 169 | 170 | virtual bool OnEncoderChanged(int8_t value) 171 | { 172 | if (valueList->GetSize() < 1) 173 | return true; 174 | 175 | VALUE_TYPE new_value; 176 | 177 | if (value < 0) 178 | new_value = valueList->GetPrev(dataItem->Get(), -value); 179 | else 180 | new_value = valueList->GetNext(dataItem->Get(), value); 181 | 182 | dataItem->Set(new_value); 183 | dataItem->SetUpdated(true); 184 | 185 | return true; 186 | }; 187 | 188 | virtual bool OnEncButtonDown() 189 | { 190 | if (pFunction) 191 | pFunction((DataItemBase*)dataItem); 192 | 193 | if (returnState) 194 | StateMachine::SetState(returnState); 195 | 196 | return true; 197 | }; 198 | }; 199 | 200 | #endif // __MENU_H__ 201 | -------------------------------------------------------------------------------- /examples/EOSCamController/screen.cpp: -------------------------------------------------------------------------------- 1 | #include "screen.h" 2 | 3 | uint8_t Screen::currentScreen = 0; 4 | uint8_t Screen::totalScreens = 0; 5 | bool Screen::screenChanged = true; 6 | 7 | Screen::Screen(const uint8_t num_items, ScreenItem *pItems) : numItems(num_items) 8 | { 9 | screenItems = (ScreenItem*)pgm_read_word(pItems); 10 | 11 | if (totalScreens < MAX_SCREENS) 12 | screenPool2[totalScreens++] = this; 13 | }; 14 | 15 | void Screen::Update(Max_LCD *pLcd, bool initial) 16 | { 17 | for (uint8_t i=0; i= totalScreens) 24 | return; 25 | 26 | currentScreen = screen_id; 27 | screenChanged = true; 28 | }; 29 | 30 | void Screen::Run(Max_LCD *pLcd) 31 | { 32 | if (screenChanged) 33 | { 34 | pLcd->clear(); 35 | pLcd->home(); 36 | } 37 | if (screenPool2[currentScreen]) 38 | { 39 | screenPool2[currentScreen]->Update(pLcd, (screenChanged) ? true : false); 40 | screenChanged = false; 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /examples/EOSCamController/screen.h: -------------------------------------------------------------------------------- 1 | #if !defined(__SCREEN_H__) 2 | #define __SCREEN_H__ 3 | 4 | #include 5 | #include "screenitem.h" 6 | 7 | #define MAX_SCREENS 12 8 | 9 | class Screen; 10 | 11 | static Screen *screenPool2[MAX_SCREENS]; 12 | 13 | class Screen 14 | { 15 | static uint8_t currentScreen; 16 | static uint8_t totalScreens; 17 | static bool screenChanged; 18 | 19 | ScreenItem *screenItems; 20 | const uint8_t numItems; 21 | 22 | public: 23 | Screen(const uint8_t num_items, ScreenItem *pItems); 24 | 25 | static void Run(Max_LCD *pLcd); 26 | static void Set(uint8_t screen_id); 27 | static uint8_t Get() { return currentScreen; }; 28 | 29 | void Update(Max_LCD *pLcd, bool initial); 30 | }; 31 | 32 | #endif // __SCREEN_H__ 33 | -------------------------------------------------------------------------------- /examples/EOSCamController/screenitem.cpp: -------------------------------------------------------------------------------- 1 | #include "screenitem.h" 2 | 3 | void ScreenItem::SetAttribs(uint8_t left, uint8_t top, uint8_t len, bool highlighted, bool pgm) 4 | { 5 | itemAttribs.bmLeft = left; 6 | itemAttribs.bmTop = top; 7 | itemAttribs.bmLen = len; 8 | itemAttribs.bmHighlighted = (highlighted) ? 1 : 0; 9 | itemAttribs.bmHlChanged = 1; // item highlighting changed flag 10 | itemAttribs.bmPgmString = (pgm) ? 1 : 0; 11 | }; 12 | 13 | ScreenItem::ScreenItem(uint8_t left, uint8_t top, uint8_t len, bool highlighted, DataItemBase *item) : 14 | dataItem(item) 15 | { 16 | SetAttribs(left, top, len, highlighted, 0); 17 | } 18 | 19 | ScreenItem::ScreenItem(uint8_t left, uint8_t top, uint8_t len, bool highlighted, const char *item) : 20 | dataItem((void*)item) 21 | { 22 | SetAttribs(left, top, len, highlighted, 1); 23 | } 24 | 25 | void ScreenItem::Print(Max_LCD *p) 26 | { 27 | char* str; 28 | bool is_pgm = false; 29 | 30 | if (itemAttribs.bmPgmString == 1) 31 | { 32 | is_pgm = true; 33 | str = (char*)dataItem; 34 | } 35 | else 36 | ((DataItemBase*)dataItem)->GetText(&str, is_pgm); 37 | 38 | if(!str) 39 | return; 40 | 41 | uint8_t cnt = 0; 42 | 43 | if (is_pgm) 44 | { 45 | char c; 46 | while((c = pgm_read_byte(str++)) && cnt < itemAttribs.bmLen) 47 | { 48 | p->print(c,BYTE); 49 | cnt ++; 50 | } 51 | } 52 | else 53 | { 54 | char *pc = str; 55 | while(*pc && cnt < itemAttribs.bmLen) 56 | { 57 | p->print(*pc++,BYTE); 58 | cnt ++; 59 | } 60 | } 61 | } 62 | 63 | void ScreenItem::Update(Max_LCD *pLcd, bool initial) 64 | { 65 | if (initial || ( itemAttribs.bmPgmString == 0 && ((DataItemBase*)dataItem)->IsUpdated() ) || itemAttribs.bmHlChanged) 66 | { 67 | pLcd->home(); 68 | 69 | if (itemAttribs.bmLeft > 0) 70 | { 71 | pLcd->setCursor(itemAttribs.bmLeft-1, itemAttribs.bmTop); 72 | 73 | pLcd->print((itemAttribs.bmHighlighted) ? '>' : ' ', BYTE); 74 | } 75 | else 76 | pLcd->setCursor(itemAttribs.bmLeft, itemAttribs.bmTop); 77 | 78 | Print(pLcd); 79 | 80 | if (itemAttribs.bmLeft + itemAttribs.bmLen < 16) 81 | pLcd->print((itemAttribs.bmHighlighted) ? '<' : ' ', BYTE); 82 | 83 | if (itemAttribs.bmPgmString == 0) 84 | ((DataItemBase*)dataItem)->SetUpdated(false); 85 | 86 | itemAttribs.bmHlChanged = 0; 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /examples/EOSCamController/screenitem.h: -------------------------------------------------------------------------------- 1 | #if !defined(__SCREENITEM_H__) 2 | #define __SCREENITEM_H__ 3 | 4 | #include 5 | #include 6 | #include "dataitem.h" 7 | 8 | struct ScreenItemAttributes 9 | { 10 | uint16_t bmLeft : 4; 11 | uint16_t bmTop : 2; 12 | uint16_t bmLen : 5; 13 | uint16_t bmHighlighted : 1; 14 | uint16_t bmHlChanged : 1; 15 | uint16_t bmPgmString : 1; 16 | }; 17 | 18 | class ScreenItem 19 | { 20 | ScreenItemAttributes itemAttribs; 21 | void *dataItem; 22 | 23 | void Print(Max_LCD *p); 24 | 25 | void SetAttribs(uint8_t left, uint8_t top, uint8_t len, bool highlighted, bool pgm); 26 | 27 | public: 28 | ScreenItem(uint8_t left, uint8_t top, uint8_t len, bool highlighted, DataItemBase *item); 29 | ScreenItem(uint8_t left, uint8_t top, uint8_t len, bool highlighted, const char *item); 30 | 31 | void Update(Max_LCD *pLcd, bool initial = true); 32 | void Highlight(bool on) { itemAttribs.bmHighlighted = (on) ? 1 : 0; itemAttribs.bmHlChanged = 1; }; 33 | bool IsHighlighted() { return (itemAttribs.bmHighlighted == 1); }; 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /examples/EOSCapture/EOSCapture.pde: -------------------------------------------------------------------------------- 1 | /* Capture command demo */ 2 | #include 3 | #include 4 | 5 | //#include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #define DEV_ADDR 1 17 | 18 | // Canon EOS 400D 19 | #define DATA_IN_EP 1 20 | #define DATA_OUT_EP 2 21 | #define INTERRUPT_EP 3 22 | #define CONFIG_NUM 1 23 | 24 | class CamStateHandlers : public PTPStateHandlers 25 | { 26 | bool stateConnected; 27 | 28 | public: 29 | CamStateHandlers() : stateConnected(false) {}; 30 | 31 | virtual void OnDeviceDisconnectedState(PTP *ptp); 32 | virtual void OnDeviceInitializedState(PTP *ptp); 33 | } CamStates; 34 | 35 | CanonEOS Eos(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 36 | 37 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 38 | { 39 | if (stateConnected) 40 | { 41 | stateConnected = false; 42 | Notify(PSTR("Camera disconnected\r\n")); 43 | } 44 | } 45 | 46 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 47 | { 48 | if (!stateConnected) 49 | stateConnected = true; 50 | 51 | uint16_t rc = Eos.Capture(); 52 | 53 | if (rc != PTP_RC_OK) 54 | Message(PSTR("Error: "), rc); 55 | 56 | delay(5000); 57 | } 58 | 59 | void setup() 60 | { 61 | Serial.begin( 115200 ); 62 | Serial.println("Start"); 63 | Eos.Setup(); 64 | delay( 200 ); 65 | } 66 | 67 | void loop() 68 | { 69 | Eos.Task(); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /examples/EOSEventLab/EOSEventLab.pde: -------------------------------------------------------------------------------- 1 | /* EOS event visualizer. Connect camera and start pressing some buttons - the events would be printed on the screen */ 2 | /* doesn't work very well with XSI */ 3 | #include 4 | #include 5 | 6 | //#include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #define DEV_ADDR 1 17 | 18 | // Canon EOS 400D 19 | #define DATA_IN_EP 1 20 | #define DATA_OUT_EP 2 21 | #define INTERRUPT_EP 3 22 | #define CONFIG_NUM 1 23 | 24 | class CamStateHandlers : public EOSStateHandlers 25 | { 26 | enum CamStates { stInitial, stDisconnected, stConnected }; 27 | CamStates stateConnected; 28 | 29 | public: 30 | CamStateHandlers() : stateConnected(stInitial) {}; 31 | 32 | virtual void OnDeviceDisconnectedState(PTP *ptp); 33 | virtual void OnDeviceInitializedState(PTP *ptp); 34 | }; 35 | 36 | CamStateHandlers CamStates; 37 | SimpleTimer PTPPollTimer; 38 | CanonEOS Eos(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 39 | 40 | 41 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 42 | { 43 | if (stateConnected == stConnected || stateConnected == stInitial) 44 | { 45 | stateConnected = stDisconnected; 46 | PTPPollTimer.Disable(); 47 | Notify(PSTR("\r\nDevice disconnected.\r\n")); 48 | } 49 | } 50 | 51 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 52 | { 53 | if (stateConnected == stDisconnected) 54 | { 55 | stateConnected = stConnected; 56 | PTPPollTimer.Enable(); 57 | } 58 | } 59 | 60 | void OnPTPPollTimer() 61 | { 62 | EOSEventDump hex; 63 | Eos.EventCheck(&hex); 64 | } 65 | 66 | void setup() 67 | { 68 | Serial.begin( 115200 ); 69 | Serial.println("Start"); 70 | Eos.Setup(); 71 | delay( 200 ); 72 | PTPPollTimer.Set(OnPTPPollTimer, 500); 73 | } 74 | 75 | void loop() 76 | { 77 | Eos.Task(); 78 | PTPPollTimer.Run(); 79 | } 80 | 81 | -------------------------------------------------------------------------------- /examples/EOSEventMonitor/EOSEventMonitor.pde: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //#include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define DEV_ADDR 1 16 | 17 | // Canon EOS 400D 18 | #define DATA_IN_EP 1 19 | #define DATA_OUT_EP 2 20 | #define INTERRUPT_EP 3 21 | #define CONFIG_NUM 1 22 | 23 | class CamStateHandlers : public EOSStateHandlers 24 | { 25 | enum CamStates { stInitial, stDisconnected, stConnected }; 26 | CamStates stateConnected; 27 | 28 | public: 29 | CamStateHandlers() : stateConnected(stInitial) 30 | { 31 | }; 32 | 33 | virtual void OnDeviceDisconnectedState(PTP *ptp); 34 | virtual void OnDeviceInitializedState(PTP *ptp); 35 | }; 36 | 37 | CamStateHandlers CamStates; 38 | SimpleTimer PTPPollTimer; 39 | CanonEOS Eos(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 40 | 41 | 42 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 43 | { 44 | if (stateConnected == stConnected || stateConnected == stInitial) 45 | { 46 | stateConnected = stDisconnected; 47 | PTPPollTimer.Disable(); 48 | Notify(PSTR("\r\nDevice disconnected.\r\n")); 49 | } 50 | } 51 | 52 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 53 | { 54 | if (stateConnected == stDisconnected) 55 | { 56 | stateConnected = stConnected; 57 | PTPPollTimer.Enable(); 58 | } 59 | } 60 | 61 | void OnPTPPollTimer() 62 | { 63 | Serial.println("\r\n"); 64 | 65 | HexDump hex; 66 | Eos.EventCheck(&hex); 67 | } 68 | 69 | void setup() 70 | { 71 | Serial.begin( 115200 ); 72 | Serial.println("Start"); 73 | Eos.Setup(); 74 | delay( 200 ); 75 | PTPPollTimer.Set(OnPTPPollTimer, 1000); 76 | } 77 | 78 | void loop() 79 | { 80 | Eos.Task(); 81 | PTPPollTimer.Run(); 82 | } 83 | 84 | -------------------------------------------------------------------------------- /examples/EOSFocus/EOSFocus.pde: -------------------------------------------------------------------------------- 1 | /* EOS Focus control demo */ 2 | /* Tested with 7D */ 3 | #include 4 | #include 5 | 6 | //#include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #define DEV_ADDR 1 16 | 17 | // Canon EOS 400D 18 | #define DATA_IN_EP 1 19 | #define DATA_OUT_EP 2 20 | #define INTERRUPT_EP 3 21 | #define CONFIG_NUM 1 22 | 23 | class CamStateHandlers : public EOSStateHandlers 24 | { 25 | enum CamStates { stInitial, stDisconnected, stConnected }; 26 | CamStates stateConnected; 27 | 28 | public: 29 | CamStateHandlers() : stateConnected(stInitial) 30 | { 31 | }; 32 | 33 | virtual void OnDeviceDisconnectedState(PTP *ptp); 34 | virtual void OnDeviceInitializedState(PTP *ptp); 35 | }; 36 | 37 | CamStateHandlers CamStates; 38 | CanonEOS Eos(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 39 | 40 | void setup() { 41 | Serial.begin( 115200 ); 42 | Serial.println("Start"); 43 | Eos.Setup(); 44 | delay( 200 ); 45 | } 46 | 47 | void loop() 48 | { 49 | Eos.Task(); 50 | } 51 | 52 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 53 | { 54 | if (stateConnected == stConnected || stateConnected == stInitial) 55 | { 56 | stateConnected = stDisconnected; 57 | Notify(PSTR("Camera disconnected.\r\n")); 58 | } 59 | } 60 | 61 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 62 | { 63 | if (stateConnected == stDisconnected) 64 | { 65 | stateConnected = stConnected; 66 | 67 | // Switch LiveView on 68 | Eos.SwitchLiveView(true); 69 | delay(50); 70 | 71 | for (uint8_t i=0; i<10; i++) 72 | { 73 | if (i > 4) 74 | Eos.MoveFocus(3); 75 | else 76 | Eos.MoveFocus(0x8003); 77 | 78 | delay(100); 79 | Eos.Capture(); 80 | delay(1500); 81 | } 82 | 83 | // Switch LiveView off 84 | Eos.SwitchLiveView(false); 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /examples/EOSHDRCapture/EOSHDRCapture.pde: -------------------------------------------------------------------------------- 1 | /* Exposure compensation change demo */ 2 | #include 3 | #include 4 | 5 | //#include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "hdrcapture.h" 15 | 16 | #define DEV_ADDR 1 17 | 18 | // Canon EOS 400D 19 | #define DATA_IN_EP 1 20 | #define DATA_OUT_EP 2 21 | #define INTERRUPT_EP 3 22 | #define CONFIG_NUM 1 23 | 24 | class CamStateHandlers : public EOSStateHandlers 25 | { 26 | enum CamStates { stInitial, stDisconnected, stConnected }; 27 | CamStates stateConnected; 28 | 29 | public: 30 | CamStateHandlers() : stateConnected(stInitial) 31 | { 32 | }; 33 | 34 | virtual void OnDeviceDisconnectedState(PTP *ptp); 35 | virtual void OnDeviceInitializedState(PTP *ptp); 36 | }; 37 | 38 | CamStateHandlers CamStates; 39 | CanonEOS Eos(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 40 | HDRCapture hdrCapture(Eos); 41 | QEvent msTick; 42 | QEvent secTick; 43 | 44 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 45 | { 46 | if (stateConnected == stConnected || stateConnected == stInitial) 47 | { 48 | stateConnected = stDisconnected; 49 | Notify(PSTR("Camera disconnected\r\n")); 50 | } 51 | } 52 | 53 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 54 | { 55 | if (stateConnected == stDisconnected) 56 | { 57 | stateConnected = stConnected; 58 | 59 | Serial.println("Connected"); 60 | 61 | SetEvt setEvt; 62 | setEvt.sig = RUN_SIG; 63 | 64 | hdrCapture.PostEvent(&setEvt); 65 | } 66 | hdrCapture.Run(); 67 | hdrCapture.PostEvent(&msTick); // post TICK_MILLIS_SIG event 68 | } 69 | 70 | void setup() 71 | { 72 | Serial.begin( 115200 ); 73 | Serial.println("Start"); 74 | 75 | Eos.Setup(); 76 | delay( 200 ); 77 | 78 | hdrCapture.init(); 79 | 80 | SetEvt setEvt; 81 | 82 | setEvt.sig = SET_FRAMES_SIG; 83 | setEvt.value = 3; 84 | 85 | hdrCapture.dispatch(&setEvt); 86 | 87 | setEvt.sig = SET_FRAME_TIMEOUT_SIG; 88 | setEvt.value = 5; 89 | 90 | hdrCapture.dispatch(&setEvt); 91 | 92 | setEvt.sig = SET_SELF_TIMEOUT_SIG; 93 | setEvt.value = 3; 94 | 95 | hdrCapture.dispatch(&setEvt); 96 | 97 | SetBktEvt setBktEvt; 98 | setBktEvt.sig = SET_BRACKETING_SIG; 99 | setBktEvt.step = 2; 100 | setBktEvt.negative = 3; 101 | setBktEvt.positive = 9; 102 | 103 | hdrCapture.dispatch(&setBktEvt); 104 | 105 | 106 | msTick.sig = TICK_MILLIS_SIG; 107 | } 108 | 109 | void loop() 110 | { 111 | Eos.Task(); 112 | delay(1); 113 | } 114 | 115 | -------------------------------------------------------------------------------- /examples/EOSHDRCapture/expcomp_macro.h: -------------------------------------------------------------------------------- 1 | #if !defined(__EXPCOMP_MACRO_H__) 2 | #define __EXPCOMP_MACRO_H__ 3 | 4 | uint8_t expComp[] = { 0xF0, 0xF3, 0xF5, 0xF8, 0xFB, 0xFD, 0, 0x03, 0x05, 0x08, 0x0B, 0x0D, 0x10 }; 5 | 6 | 7 | #define EXP_COMP_VALUE(i)((uint32_t)expComp[(i)]) 8 | 9 | #endif // __EXPCOMP_MACRO_H__ 10 | -------------------------------------------------------------------------------- /examples/EOSHDRCapture/hdrcapture.h: -------------------------------------------------------------------------------- 1 | #if !defined(__HDRCAPTURE_H__) 2 | #define __HDRCAPTURE_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define PTP_TIMEOUT 250 13 | 14 | #define TA_PTP_TIMEOUT 0x00 15 | #define TA_SELF_TIMER 0x03 16 | #define TA_INTR_TIMER 0x05 17 | #define TA_BULB_TIMER 0x07 18 | 19 | enum HDRCaptureSignals 20 | { 21 | TICK_MILLIS_SIG = Q_USER_SIG, 22 | SET_FRAMES_SIG, 23 | SET_SELF_TIMEOUT_SIG, 24 | SET_FRAME_TIMEOUT_SIG, 25 | SET_BRACKETING_SIG, 26 | RUN_SIG, 27 | ABORT_SIG, 28 | TIMEOUT_SIG, 29 | SET_TIMEOUT_SIG, 30 | PTP_RC_SIG, 31 | PTP_RC_OK_SIG 32 | }; 33 | 34 | struct SetTimeoutEvt : public QEvent 35 | { 36 | uint32_t timeout; 37 | uint8_t attribs; 38 | }; 39 | 40 | struct SetEvt : public QEvent 41 | { 42 | uint32_t value; 43 | }; 44 | 45 | struct SetBktEvt : public QEvent 46 | { 47 | uint8_t step; 48 | uint8_t negative; 49 | uint8_t positive; 50 | }; 51 | 52 | struct PTP_RC_Evt : public QEvent 53 | { 54 | uint16_t rc; 55 | }; 56 | 57 | class HDRCapture : public QHsm 58 | { 59 | uint16_t frmCntdn; 60 | uint16_t frmCount; 61 | uint32_t selfTimeout; 62 | uint32_t frameTimeout; 63 | uint8_t bktStep; 64 | uint8_t bktNegative; 65 | uint8_t bktPositive; 66 | uint8_t bktCntdn; 67 | uint8_t bktPos; 68 | uint8_t bktOldVal; 69 | 70 | CanonEOS &Eos; 71 | 72 | SetTimeoutEvt toEvt; 73 | PTP_RC_Evt rcEvt; 74 | QEvent qpEvt; 75 | 76 | QStateHandler activeHistory; 77 | 78 | SimpleFIFO theQueue; 79 | 80 | public: 81 | HDRCapture(CanonEOS &eos) : 82 | QHsm((QStateHandler)&HDRCapture::Initial), 83 | frmCount(0), 84 | frmCntdn(0), 85 | selfTimeout(0), 86 | frameTimeout(0), 87 | bktStep(0), 88 | bktNegative(0), 89 | bktPositive(0), 90 | bktCntdn(0), 91 | bktPos(0), 92 | bktOldVal(0), 93 | Eos(eos), 94 | activeHistory(NULL) 95 | { 96 | toEvt.sig = SET_TIMEOUT_SIG; 97 | rcEvt.sig = PTP_RC_SIG; 98 | }; 99 | void PostEvent(QEvent *e) 100 | { 101 | theQueue.Push(e); 102 | }; 103 | void Run() 104 | { 105 | QEvent *e = NULL; 106 | 107 | while ( (e = theQueue.Pop()) ) 108 | dispatch(e); 109 | }; 110 | 111 | protected: 112 | static QState Initial(HDRCapture *me, QEvent const *e); 113 | static QState Inactive(HDRCapture *me, QEvent const *e); 114 | static QState Active(HDRCapture *me, QEvent const *e); 115 | static QState SelfTimer(HDRCapture *me, QEvent const *e); 116 | static QState PreCapture(HDRCapture *me, QEvent const *e); 117 | static QState Capture(HDRCapture *me, QEvent const *e); 118 | static QState PostCapture(HDRCapture *me, QEvent const *e); 119 | static QState ExpCompSet(HDRCapture *me, QEvent const *e); 120 | static QState SaveSettings(HDRCapture *me, QEvent const *e); 121 | static QState RestoreSettings(HDRCapture *me, QEvent const *e); 122 | static QState Timeout(HDRCapture *me, QEvent const *e); 123 | 124 | virtual void OnFrameCaptured(uint16_t left) {}; 125 | virtual void OnBktFrameCaptured(uint16_t left) {}; 126 | virtual void OnSelfTimerProgress(uint32_t left) {}; 127 | virtual void OnIntrTimerProgress(uint32_t left) {}; 128 | }; 129 | 130 | #endif // __HDRCAPTURE_H__ 131 | -------------------------------------------------------------------------------- /examples/EOSRemote/EOSConsole.h: -------------------------------------------------------------------------------- 1 | #if !defined(__EOSCONSOLE_H__) 2 | #define __EOSCONSOLE_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | enum TextMenuSignals 11 | { 12 | MENU_SELECT_SIG = Q_USER_SIG, 13 | TICK_SIG 14 | }; 15 | 16 | struct TickEvt : public QEvent 17 | { 18 | uint8_t fine_time; // the fine 1/10 s counter 19 | }; 20 | 21 | struct MenuSelectEvt : public QEvent 22 | { 23 | uint8_t item_index; 24 | }; 25 | 26 | class EOSConsole : public QHsm 27 | { 28 | static void PrintMenuTitles(uint8_t count, const char **menu); 29 | static void ShowParams(); 30 | 31 | public: 32 | EOSConsole() 33 | : QHsm((QStateHandler)&EOSConsole::Initial) 34 | {}; 35 | int8_t MenuSelect(); 36 | 37 | protected: 38 | static QState Initial(EOSConsole *me, QEvent const *e); 39 | static QState Inactive(EOSConsole *me, QEvent const *e); 40 | static QState Active(EOSConsole *me, QEvent const *e); 41 | static QState MainMenu(EOSConsole *me, QEvent const *e); 42 | static QState ChangeSettingsMenu(EOSConsole *me, QEvent const *e); 43 | static QState ChangeApertureMenu(EOSConsole *me, QEvent const *e); 44 | static QState ChangeShutterSpeedMenu(EOSConsole *me, QEvent const *e); 45 | static QState ChangeWBMenu(EOSConsole *me, QEvent const *e); 46 | static QState ChangePStyleMenu(EOSConsole *me, QEvent const *e); 47 | static QState ChangeExpCompMenu(EOSConsole *me, QEvent const *e); 48 | static QState ChangeIsoMenu(EOSConsole *me, QEvent const *e); 49 | }; 50 | 51 | #endif // __EOSCONSOLE_H__ 52 | -------------------------------------------------------------------------------- /examples/EOSRemote/EOSRemote.pde: -------------------------------------------------------------------------------- 1 | /* EOS control terminal */ 2 | //#include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "eoseventparser.h" 13 | #include "eosconsole.h" 14 | 15 | #define DEV_ADDR 1 16 | 17 | // Canon EOS 400D 18 | #define DATA_IN_EP 1 19 | #define DATA_OUT_EP 2 20 | #define INTERRUPT_EP 3 21 | #define CONFIG_NUM 1 22 | 23 | #define EEP_APERTURE_LIST_OFFSET 0 24 | #define EEP_APERTURE_LIST_SIZE 32 25 | 26 | #define EEP_SHTSPEED_LIST_OFFSET (EEP_APERTURE_LIST_OFFSET + EEP_APERTURE_LIST_SIZE) 27 | #define EEP_SHTSPEED_LIST_SIZE 64 28 | 29 | #define EEP_WBALANCE_LIST_OFFSET (EEP_SHTSPEED_LIST_OFFSET + EEP_SHTSPEED_LIST_SIZE) 30 | #define EEP_WBALANCE_LIST_SIZE 12 31 | 32 | #define EEP_PICSTYLE_LIST_OFFSET (EEP_WBALANCE_LIST_OFFSET + EEP_WBALANCE_LIST_SIZE) 33 | #define EEP_PICSTYLE_LIST_SIZE 12 34 | 35 | #define EEP_EXPOCOR_LIST_OFFSET (EEP_PICSTYLE_LIST_OFFSET + EEP_PICSTYLE_LIST_SIZE) 36 | #define EEP_EXPOCOR_LIST_SIZE 48 37 | 38 | #define EEP_ISO_LIST_OFFSET (EEP_EXPOCOR_LIST_OFFSET + EEP_EXPOCOR_LIST_SIZE) 39 | #define EEP_ISO_LIST_SIZE 8 40 | 41 | EEPROMByteList vlAperture(EEP_APERTURE_LIST_OFFSET, EEP_APERTURE_LIST_SIZE); 42 | EEPROMByteList vlShutterSpeed(EEP_SHTSPEED_LIST_OFFSET, EEP_SHTSPEED_LIST_SIZE); 43 | EEPROMByteList vlWhiteBalance(EEP_WBALANCE_LIST_OFFSET, EEP_WBALANCE_LIST_SIZE); 44 | EEPROMByteList vlPictureStyle(EEP_PICSTYLE_LIST_OFFSET, EEP_PICSTYLE_LIST_SIZE); 45 | EEPROMByteList vlIso(EEP_EXPOCOR_LIST_OFFSET, EEP_EXPOCOR_LIST_SIZE); 46 | EEPROMByteList vlExpCompensation(EEP_EXPOCOR_LIST_OFFSET, EEP_EXPOCOR_LIST_SIZE); 47 | 48 | class CamStateHandlers : public EOSStateHandlers 49 | { 50 | enum CamStates { stInitial, stDisconnected, stConnected }; 51 | CamStates stateConnected; 52 | 53 | public: 54 | CamStateHandlers() : stateConnected(stInitial) 55 | { 56 | }; 57 | 58 | virtual void OnDeviceDisconnectedState(PTP *ptp); 59 | virtual void OnDeviceInitializedState(PTP *ptp); 60 | }; 61 | 62 | CamStateHandlers CamStates; 63 | SimpleTimer ControlTimer, PTPPollTimer; 64 | 65 | CanonEOS Eos(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 66 | QEvent evtTick, evtAbort; 67 | EOSConsole eosConsole; 68 | 69 | uint8_t dpMode = 0; 70 | uint8_t dpAperture = 0; 71 | uint8_t dpShutterSpeed = 0; 72 | uint8_t dpWb = 0; 73 | uint8_t dpPStyle = 0; 74 | uint8_t dpIso = 0; 75 | uint8_t dpExpComp = 0; 76 | 77 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 78 | { 79 | if (stateConnected == stConnected || stateConnected == stInitial) 80 | { 81 | stateConnected = stDisconnected; 82 | PTPPollTimer.Disable(); 83 | Notify(PSTR("Camera disconnected.\r\n")); 84 | 85 | if (stateConnected == stConnected) 86 | eosConsole.dispatch(&evtTick); 87 | } 88 | } 89 | 90 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 91 | { 92 | if (stateConnected == stDisconnected) 93 | { 94 | stateConnected = stConnected; 95 | PTPPollTimer.Enable(); 96 | eosConsole.dispatch(&evtTick); 97 | } 98 | int8_t index = eosConsole.MenuSelect(); 99 | 100 | if (index >= 0) 101 | { 102 | MenuSelectEvt menu_sel_evt; 103 | menu_sel_evt.sig = MENU_SELECT_SIG; 104 | menu_sel_evt.item_index = index; 105 | eosConsole.dispatch(&menu_sel_evt); // dispatch the event 106 | } 107 | } 108 | 109 | void OnControlTimer() 110 | { 111 | // ExtControls.CheckControls(); 112 | // hdrCapture.PostEvent(&evtTick); 113 | // Screen::Run(&LCD); 114 | } 115 | 116 | void OnPTPPollTimer() 117 | { 118 | EOSEventParser prs; 119 | Eos.EventCheck(&prs); 120 | } 121 | 122 | void setup() 123 | { 124 | Serial.begin(115200); 125 | Eos.Setup(); 126 | delay( 200 ); 127 | 128 | PTPPollTimer.Set(OnPTPPollTimer, 300); 129 | 130 | // 1ms is the perfect interval for encoder polling 131 | ControlTimer.Set(OnControlTimer, 1); 132 | ControlTimer.Enable(); 133 | 134 | evtTick.sig = TICK_SIG; 135 | // evtAbort.sig = ABORT_SIG; 136 | eosConsole.init(); 137 | 138 | Serial.println("Start"); 139 | } 140 | 141 | void loop() 142 | { 143 | Eos.Task(); 144 | PTPPollTimer.Run(); 145 | ControlTimer.Run(); 146 | } 147 | 148 | -------------------------------------------------------------------------------- /examples/EOSRemote/eoseventparser.cpp: -------------------------------------------------------------------------------- 1 | #include "eoseventparser.h" 2 | #include 3 | 4 | extern EEPROMByteList vlAperture; 5 | extern EEPROMByteList vlShutterSpeed; 6 | extern EEPROMByteList vlWhiteBalance; 7 | extern EEPROMByteList vlPictureStyle; 8 | extern EEPROMByteList vlExpCompensation; 9 | extern EEPROMByteList vlIso; 10 | 11 | extern uint8_t dpMode; 12 | extern uint8_t dpAperture; 13 | extern uint8_t dpShutterSpeed; 14 | extern uint8_t dpWb; 15 | extern uint8_t dpPStyle; 16 | extern uint8_t dpIso; 17 | extern uint8_t dpExpComp; 18 | 19 | 20 | bool EOSEventParser::EventRecordParse(uint8_t **pp, uint16_t *pcntdn) 21 | { 22 | switch (nRecStage) 23 | { 24 | case 0: 25 | // Retrieves the size of the event record 26 | if (!valueParser.Parse(pp, pcntdn)) 27 | return false; 28 | 29 | nRecSize = (uint16_t)varBuffer; 30 | 31 | // calculates the number of event parameters ( size / 4 - 1 ) 32 | paramCountdown = (nRecSize >> 2) - 1; 33 | 34 | paramCount = 1; 35 | nRecSize -= 4; 36 | nRecStage ++; 37 | case 1: 38 | for (; paramCountdown; paramCountdown--, paramCount++, nRecSize -= 4) 39 | { 40 | if (!valueParser.Parse(pp, pcntdn)) 41 | return false; 42 | 43 | switch (paramCount) 44 | { 45 | // Event Code 46 | case 1: 47 | eosEvent.eventCode = (uint16_t)varBuffer; 48 | break; 49 | // Property Code 50 | case 2: 51 | // if (eosEvent.eventCode == EOS_EC_ObjectCreated) 52 | // { 53 | // } 54 | eosEvent.propCode = (uint16_t)varBuffer; 55 | break; 56 | // C189 - Property Value, C18A - Enumerator Type 57 | case 3: 58 | eosEvent.propValue = varBuffer; 59 | 60 | if (eosEvent.eventCode == EOS_EC_DevPropChanged) 61 | { 62 | 63 | switch (eosEvent.propCode) 64 | { 65 | case EOS_DPC_Aperture: 66 | dpAperture = (uint8_t) varBuffer; 67 | Notify(PSTR("F:")); 68 | Notify((char*)FindTitle(VT_APT_COUNT, ApertureTitles, dpAperture)); 69 | Notify(PSTR("\r\n")); 70 | break; 71 | case EOS_DPC_ShutterSpeed: 72 | dpShutterSpeed = (uint8_t) varBuffer; 73 | Notify(PSTR("T:")); 74 | Notify((char*)FindTitle(VT_SHSPEED_COUNT, ShutterSpeedTitles, dpShutterSpeed)); 75 | Notify(PSTR("\r\n")); 76 | break; 77 | case EOS_DPC_ShootingMode: 78 | dpMode = (uint8_t) varBuffer; 79 | Notify(PSTR("Mode:")); 80 | Notify((char*)FindTitle(VT_MODE_COUNT, ModeTitles, dpMode)); 81 | Notify(PSTR("\r\n")); 82 | break; 83 | case EOS_DPC_WhiteBalance: 84 | dpWb = (uint8_t) varBuffer; 85 | Notify(PSTR("WB:")); 86 | Notify((char*)FindTitle(VT_WB_COUNT, WbTitles, dpWb)); 87 | Notify(PSTR("\r\n")); 88 | break; 89 | case EOS_DPC_PictureStyle: 90 | dpPStyle = (uint8_t) varBuffer; 91 | Notify(PSTR("Pict Style:")); 92 | Notify((char*)FindTitle(VT_PSTYLE_COUNT, PStyleTitles, dpPStyle)); 93 | Notify(PSTR("\r\n")); 94 | break; 95 | case EOS_DPC_Iso: 96 | dpIso = (uint8_t) varBuffer; 97 | Notify(PSTR("ISO:")); 98 | Notify((char*)FindTitle(VT_ISO_COUNT, IsoTitles, dpIso)); 99 | Notify(PSTR("\r\n")); 100 | break; 101 | case EOS_DPC_ExposureCompensation: 102 | dpExpComp = (uint8_t) varBuffer; 103 | Notify(PSTR("Exp Comp:")); 104 | Notify((char*)FindTitle(VT_EXPCOMP_COUNT, ExpCompTitles, dpExpComp)); 105 | Notify(PSTR("\r\n")); 106 | break; 107 | }; 108 | } 109 | break; 110 | // C18A/enumType == 3 - Size of enumerator array 111 | case 4: 112 | if (eosEvent.eventCode == EOS_EC_DevPropValuesAccepted) 113 | { 114 | switch (eosEvent.propCode) 115 | { 116 | case EOS_DPC_Aperture: 117 | vlAperture.SetSize((uint8_t)varBuffer); 118 | break; 119 | case EOS_DPC_ShutterSpeed: 120 | vlShutterSpeed.SetSize((uint8_t)varBuffer); 121 | break; 122 | case EOS_DPC_WhiteBalance: 123 | vlWhiteBalance.SetSize((uint8_t)varBuffer); 124 | break; 125 | case EOS_DPC_PictureStyle: 126 | vlPictureStyle.SetSize((uint8_t)varBuffer); 127 | break; 128 | case EOS_DPC_Iso: 129 | vlIso.SetSize((uint8_t)varBuffer); 130 | break; 131 | case EOS_DPC_ExposureCompensation: 132 | vlExpCompensation.SetSize((uint8_t)varBuffer); 133 | break; 134 | }; 135 | } 136 | break; 137 | // C18A/enumType == 3 - Enumerator Values 138 | default: 139 | if (eosEvent.eventCode == EOS_EC_DevPropValuesAccepted) 140 | { 141 | switch (eosEvent.propCode) 142 | { 143 | case EOS_DPC_Aperture: 144 | vlAperture.Set(paramCount-5, (uint8_t)varBuffer); 145 | break; 146 | case EOS_DPC_ShutterSpeed: 147 | vlShutterSpeed.Set(paramCount-5, (uint8_t)varBuffer); 148 | break; 149 | case EOS_DPC_WhiteBalance: 150 | vlWhiteBalance.Set(paramCount-5, (uint8_t)varBuffer); 151 | break; 152 | case EOS_DPC_PictureStyle: 153 | vlPictureStyle.Set(paramCount-5, (uint8_t)varBuffer); 154 | break; 155 | case EOS_DPC_ExposureCompensation: 156 | vlExpCompensation.Set(paramCount-5, (uint8_t)varBuffer); 157 | break; 158 | case EOS_DPC_Iso: 159 | vlIso.Set(paramCount-5, (uint8_t)varBuffer); 160 | break; 161 | } // switch (eosEvent.propCode) 162 | } 163 | } // switch (paramCount) 164 | } // for 165 | nRecStage ++; 166 | case 2: 167 | if (nRecSize) 168 | if (!byteSkipper.Skip(pp, pcntdn, nRecSize)) 169 | return false; 170 | 171 | nRecSize = 0; 172 | nRecStage = 0; 173 | } 174 | return true; 175 | } 176 | 177 | void EOSEventParser::InitEOSEventStruct() 178 | { 179 | eosEvent.eventCode = constInitialEventCode; 180 | eosEvent.propCode = 0; 181 | eosEvent.propValue = 0; 182 | } 183 | 184 | 185 | void EOSEventParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) 186 | { 187 | uint8_t *p = (uint8_t*) pbuf; 188 | uint16_t cntdn = len; 189 | 190 | switch (nStage) 191 | { 192 | case 0: 193 | p += 12; 194 | cntdn -= 12; 195 | nStage ++; 196 | case 1: 197 | theBuffer.valueSize = 4; 198 | valueParser.Initialize(&theBuffer); 199 | InitEOSEventStruct(); 200 | nStage ++; 201 | case 2: 202 | while (1) 203 | { 204 | if (!EventRecordParse(&p, &cntdn)) 205 | return; 206 | if (IsLastEventRecord()) 207 | break; 208 | InitEOSEventStruct(); 209 | } 210 | nStage = 0; 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /examples/EOSRemote/eoseventparser.h: -------------------------------------------------------------------------------- 1 | #ifndef __EOSEVENTPARSER_H__ 2 | #define __EOSEVENTPARSER_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | struct EOSParamValues 11 | { 12 | uint8_t upperValue; 13 | uint8_t currentValue; 14 | uint8_t lowerValue; 15 | }; 16 | 17 | #define MAX_OBJ_IN_LIST 8 18 | 19 | class EOSEventParser : public PTPReadParser 20 | { 21 | const uint16_t constInitialEventCode; 22 | 23 | uint8_t paramsChanged; 24 | 25 | struct EOSEvent 26 | { 27 | uint16_t eventCode; 28 | uint16_t propCode; 29 | uint32_t propValue; 30 | }; 31 | 32 | uint8_t nStage; 33 | uint8_t nRecStage; 34 | uint16_t nRecSize; 35 | MultiValueBuffer theBuffer; 36 | uint32_t varBuffer; 37 | EOSEvent eosEvent; 38 | uint16_t paramCountdown; 39 | uint16_t paramCount; 40 | 41 | MultiByteValueParser valueParser; 42 | ByteSkipper byteSkipper; 43 | 44 | bool EventRecordParse(uint8_t **pp, uint16_t *pcntdn); 45 | bool IsLastEventRecord() { return (eosEvent.eventCode == 0); }; 46 | void InitEOSEventStruct(); 47 | 48 | public: 49 | EOSEventParser() : 50 | constInitialEventCode(0xFFFF), 51 | nStage(0), 52 | nRecStage(0), 53 | nRecSize(0), 54 | varBuffer(0), 55 | paramCountdown(0), 56 | paramsChanged(0) 57 | { 58 | theBuffer.pValue = &varBuffer; 59 | }; 60 | 61 | void Reset() 62 | { 63 | nStage = 0; 64 | nRecStage = 0; 65 | nRecSize = 0; 66 | varBuffer = 0; 67 | paramCountdown = 0; 68 | paramsChanged = 0; 69 | }; 70 | 71 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 72 | }; 73 | 74 | #endif // __EOSEVENTPARSER_H__ 75 | -------------------------------------------------------------------------------- /examples/EOSRemote/valuetitles.h: -------------------------------------------------------------------------------- 1 | /* Camera controller header */ 2 | #ifndef __VALUETITLES_H__ 3 | #define __VALUETITLES_H__ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #define VT_MODE_COUNT 16 12 | #define VT_APT_COUNT 54 13 | #define VT_WB_COUNT 7 14 | #define VT_SHSPEED_COUNT 74 15 | #define VT_PSTYLE_COUNT 9 16 | #define VT_ISO_COUNT 19 17 | #define VT_EXPCOR_COUNT 37 18 | 19 | const ValueTitle ApertureTitles[] PROGMEM = 20 | { 21 | {0x00, {' ', ' ', '0', 0 } }, 22 | {0x08, {' ', ' ', '1', 0 } }, 23 | {0x0B, {'1', '.', '1', 0 } }, 24 | {0x0C, {'1', '.', '2', 0 } }, 25 | {0x0D, {'1', '.', '2', 0 } }, 26 | {0x10, {'1', '.', '4', 0 } }, 27 | {0x13, {'1', '.', '6', 0 } }, 28 | {0x14, {'1', '.', '8', 0 } }, 29 | {0x15, {'1', '.', '8', 0 } }, 30 | {0x18, {'2', '.', '0', 0 } }, 31 | {0x1B, {'2', '.', '2', 0 } }, 32 | {0x1C, {'2', '.', '5', 0 } }, 33 | {0x1D, {'2', '.', '5', 0 } }, 34 | {0x20, {'2', '.', '8', 0 } }, 35 | {0x23, {'3', '.', '2', 0 } }, 36 | {0x24, {'3', '.', '5', 0 } }, 37 | {0x25, {'3', '.', '5', 0 } }, 38 | {0x28, {'4', '.', '0', 0 } }, 39 | {0x2B, {'4', '.', '5', 0 } }, 40 | {0x2C, {'4', '.', '5', 0 } }, 41 | {0x2D, {'5', '.', '0', 0 } }, 42 | {0x30, {'5', '.', '6', 0 } }, 43 | {0x33, {'6', '.', '3', 0 } }, 44 | {0x34, {'6', '.', '7', 0 } }, 45 | {0x35, {'7', '.', '1', 0 } }, 46 | {0x38, {'8', '.', '0', 0 } }, 47 | {0x3B, {'9', '.', '0', 0 } }, 48 | {0x3C, {'9', '.', '5', 0 } }, 49 | {0x3D, {' ', '1', '0', 0 } }, 50 | {0x40, {' ', '1', '1', 0 } }, 51 | {0x43, {' ', '1', '3', 0 } }, 52 | {0x44, {' ', '1', '3', 0 } }, 53 | {0x45, {' ', '1', '4', 0 } }, 54 | {0x48, {' ', '1', '6', 0 } }, 55 | {0x4B, {' ', '1', '8', 0 } }, 56 | {0x4C, {' ', '1', '9', 0 } }, 57 | {0x4D, {' ', '2', '0', 0 } }, 58 | {0x50, {' ', '2', '2', 0 } }, 59 | {0x53, {' ', '2', '5', 0 } }, 60 | {0x54, {' ', '2', '7', 0 } }, 61 | {0x55, {' ', '2', '9', 0 } }, 62 | {0x58, {' ', '3', '2', 0 } }, 63 | {0x5B, {' ', '3', '6', 0 } }, 64 | {0x5C, {' ', '3', '8', 0 } }, 65 | {0x5D, {' ', '4', '0', 0 } }, 66 | {0x60, {' ', '4', '5', 0 } }, 67 | {0x63, {' ', '5', '1', 0 } }, 68 | {0x64, {' ', '5', '4', 0 } }, 69 | {0x65, {' ', '5', '7', 0 } }, 70 | {0x68, {' ', '6', '4', 0 } }, 71 | {0x6B, {' ', '7', '2', 0 } }, 72 | {0x6C, {' ', '7', '6', 0 } }, 73 | {0x6D, {' ', '8', '0', 0 } }, 74 | {0x70, {' ', '9', '1', 0 } } 75 | }; 76 | 77 | const ValueTitle ShutterSpeedTitles[] PROGMEM = 78 | { 79 | {0x0c, {'B','u','l','b',0} }, 80 | {0x10, {' ','3','0','"',0} }, 81 | {0x13, {' ','2','5','"',0} }, 82 | {0x14, {' ','2','0','"',0} }, 83 | {0x15, {' ','2','0','"',0} }, 84 | {0x18, {' ','1','5','"',0} }, 85 | {0x1B, {' ','1','3','"',0} }, 86 | {0x1C, {' ','1','0','"',0} }, 87 | {0x1D, {' ','1','0','"',0} }, 88 | {0x20, {' ',' ','8','"',0} }, 89 | {0x23, {' ',' ','6','"',0} }, 90 | {0x24, {' ',' ','6','"',0} }, 91 | {0x25, {' ',' ','5','"',0} }, 92 | {0x28, {' ',' ','4','"',0} }, 93 | {0x2B, {' ','3','"','2',0} }, 94 | {0x2C, {' ',' ','3','"',0} }, 95 | {0x2D, {' ','2','"','5',0} }, 96 | {0x30, {' ',' ','2','"',0} }, 97 | {0x33, {' ','1','"','6',0} }, 98 | {0x34, {' ','1','"','5',0} }, 99 | {0x35, {' ','1','"','3',0} }, 100 | {0x38, {' ',' ','1','"',0} }, 101 | {0x3B, {' ','0','"','8',0} }, 102 | {0x3C, {' ','0','"','7',0} }, 103 | {0x3D, {' ','0','"','6',0} }, 104 | {0x40, {' ','0','"','5',0} }, 105 | {0x43, {' ','0','"','4',0} }, 106 | {0x44, {' ','0','"','3',0} }, 107 | {0x45, {' ','0','"','3',0} }, 108 | {0x48, {' ',' ',' ','4',0} }, 109 | {0x4B, {' ',' ',' ','5',0} }, 110 | {0x4C, {' ',' ',' ','6',0} }, 111 | {0x4D, {' ',' ',' ','6',0} }, 112 | {0x50, {' ',' ',' ','8',0} }, 113 | {0x53, {' ',' ','1','0',0} }, 114 | {0x54, {' ',' ','1','0',0} }, 115 | {0x55, {' ',' ','1','3',0} }, 116 | {0x58, {' ',' ','1','5',0} }, 117 | {0x5B, {' ',' ','2','0',0} }, 118 | {0x5C, {' ',' ','2','0',0} }, 119 | {0x5D, {' ',' ','2','5',0} }, 120 | {0x60, {' ',' ','3','0',0} }, 121 | {0x63, {' ',' ','4','0',0} }, 122 | {0x64, {' ',' ','4','5',0} }, 123 | {0x65, {' ',' ','5','0',0} }, 124 | {0x68, {' ',' ','6','0',0} }, 125 | {0x6B, {' ',' ','8','0',0} }, 126 | {0x6C, {' ',' ','9','0',0} }, 127 | {0x6D, {' ','1','0','0',0} }, 128 | {0x70, {' ','1','2','5',0} }, 129 | {0x73, {' ','1','6','0',0} }, 130 | {0x74, {' ','1','8','0',0} }, 131 | {0x75, {' ','2','0','0',0} }, 132 | {0x78, {' ','2','5','0',0} }, 133 | {0x7B, {' ','3','2','0',0} }, 134 | {0x7C, {' ','3','5','0',0} }, 135 | {0x7D, {' ','4','0','0',0} }, 136 | {0x80, {' ','5','0','0',0} }, 137 | {0x83, {' ','6','4','0',0} }, 138 | {0x84, {' ','7','5','0',0} }, 139 | {0x85, {' ','8','0','0',0} }, 140 | {0x88, {'1','0','0','0',0} }, 141 | {0x8B, {'1','2','5','0',0} }, 142 | {0x8C, {'1','5','0','0',0} }, 143 | {0x8D, {'1','6','0','0',0} }, 144 | {0x90, {'2','0','0','0',0} }, 145 | {0x93, {'2','5','0','0',0} }, 146 | {0x94, {'3','0','0','0',0} }, 147 | {0x95, {'3','2','0','0',0} }, 148 | {0x98, {'4','0','0','0',0} }, 149 | {0x9B, {'5','0','0','0',0} }, 150 | {0x9C, {'6','0','0','0',0} }, 151 | {0x9D, {'6','4','0','0',0} }, 152 | {0xA0, {'8','0','0','0',0} } 153 | }; 154 | 155 | const ValueTitle IsoTitles[] PROGMEM = 156 | { 157 | {0x28, {'6',' ',' ',' ',0} }, 158 | {0x30, {'1','2',' ',' ',0} }, 159 | {0x38, {'2','5',' ',' ',0} }, 160 | {0x40, {'5','0',' ',' ',0} }, 161 | {0x48, {'1','0','0',' ',0} }, 162 | {0x4b, {'1','2','5',' ',0} }, 163 | {0x4d, {'1','6','0',' ',0} }, 164 | {0x50, {'2','0','0',' ',0} }, 165 | {0x53, {'2','5','0',' ',0} }, 166 | {0x55, {'3','2','0',' ',0} }, 167 | {0x58, {'4','0','0',' ',0} }, 168 | {0x5b, {'5','0','0',' ',0} }, 169 | {0x5d, {'6','4','0',' ',0} }, 170 | {0x60, {'8','0','0',' ',0} }, 171 | {0x63, {'1','0','0','0',0} }, 172 | {0x65, {'1','2','5','0',0} }, 173 | {0x68, {'1','6','0','0',0} }, 174 | {0x70, {'3','2','0','0',0} }, 175 | {0x78, {'6','4','0','0',0} } 176 | }; 177 | 178 | const ValueTitle ExpCorTitles[] PROGMEM = 179 | { 180 | {0x28, {'+','5',' ',' ',' ',' ',0} }, 181 | {0x25, {'+','4',' ','2','/','3',0} }, 182 | {0x23, {'+','4',' ','1','/','3',0} }, 183 | {0x20, {'+','4',' ',' ',' ',' ',0} }, 184 | {0x1d, {'+','3',' ','2','/','3',0} }, 185 | {0x1b, {'+','3',' ','1','/','3',0} }, 186 | {0x18, {'+','3',' ',' ',' ',' ',0} }, 187 | {0x15, {'+','2',' ','2','/','3',0} }, 188 | {0x14, {'+','2',' ','1','/','2',0} }, 189 | {0x13, {'+','2',' ','1','/','3',0} }, 190 | {0x10, {'+','2',' ',' ',' ',' ',0} }, 191 | {0x0d, {'+','1',' ','2','/','3',0} }, 192 | {0x0c, {'+','1',' ','1','/','2',0} }, 193 | {0x0b, {'+','1',' ','1','/','3',0} }, 194 | {0x08, {'+','1',' ',' ',' ',' ',0} }, 195 | {0x05, {'+','2','/','3',' ',' ',0} }, 196 | {0x04, {'+','1','/','2',' ',' ',0} }, 197 | {0x03, {'+','1','/','3',' ',' ',0} }, 198 | {0x00, {'0',' ',' ',' ',' ',' ',0} }, 199 | {0xfd, {'-','1','/','3',' ',' ',0} }, 200 | {0xfc, {'-','1','/','2',' ',' ',0} }, 201 | {0xfb, {'-','2','/','3',' ',' ',0} }, 202 | {0xf8, {'-','1',' ',' ',' ',' ',0} }, 203 | {0xf5, {'-','1',' ','1','/','3',0} }, 204 | {0xf4, {'-','1',' ','1','/','2',0} }, 205 | {0xf3, {'-','1',' ','2','/','3',0} }, 206 | {0xf0, {'-','2',' ',' ',' ',' ',0} }, 207 | {0xed, {'-','2',' ','1','/','3',0} }, 208 | {0xec, {'-','2',' ','1','/','2',0} }, 209 | {0xeb, {'-','2',' ','2','/','3',0} }, 210 | {0xe8, {'-','3',' ',' ',' ',' ',0} }, 211 | {0xe5, {'-','3',' ','1','/','3',0} }, 212 | {0xe3, {'-','3',' ','2','/','3',0} }, 213 | {0xe0, {'-','4',' ',' ',' ',' ',0} }, 214 | {0xdd, {'-','4',' ','1','/','3',0} }, 215 | {0xdb, {'-','3',' ','2','/','3',0} }, 216 | {0xd8, {'-','5',' ',' ',' ',' ',0} } 217 | }; 218 | 219 | const ValueTitle ModeTitles[] PROGMEM = 220 | { 221 | {0, {'P',' ',' ',0} }, 222 | {1, {'T','v',' ',0} }, 223 | {2, {'A','v',' ',0} }, 224 | {3, {'M',' ',' ',0} }, 225 | {4, {'B','l','b',0} }, 226 | {5, {'A','-','D',0} }, 227 | {6, {'D','E','P',0} }, 228 | {7, {'C',' ',' ',0} }, 229 | {8, {'L','c','k',0} }, 230 | {9, {'G','r','n',0} }, 231 | {10, {'N','g','h',0} }, 232 | {11, {'S','p','r',0} }, 233 | {13, {'L','n','d',0} }, 234 | {14, {'C','l','s',0} }, 235 | {15, {'N','/','F',0} } 236 | }; 237 | 238 | const ValueTitle WbTitles[] PROGMEM = 239 | { 240 | {0, {'A','W','B',0} }, 241 | {1, {'D','a','y',0} }, 242 | {2, {'C','l','d',0} }, 243 | {3, {'T','n','g',0} }, 244 | {4, {'F','l','r',0} }, 245 | {5, {'S','t','r',0} }, 246 | {6, {'W','/','P',0} }, 247 | {8, {'S','h','d',0} } 248 | }; 249 | 250 | const ValueTitle PStyleTitles[] PROGMEM = 251 | { 252 | {0x21, {'U','s','1',0} }, 253 | {0x22, {'U','s','2',0} }, 254 | {0x23, {'U','s','3',0} }, 255 | {0x81, {'S','t','d',0} }, 256 | {0x82, {'P','r','t',0} }, 257 | {0x83, {'L','n','d',0} }, 258 | {0x84, {'N','t','l',0} }, 259 | {0x85, {'F','t','h',0} }, 260 | {0x86, {'M','o','n',0} } 261 | }; 262 | 263 | #endif //__VALUETITLES_H__ 264 | -------------------------------------------------------------------------------- /examples/PSCapture/PSCapture.pde: -------------------------------------------------------------------------------- 1 | /* Canon Powershot Capture Demo */ 2 | #include 3 | #include 4 | 5 | //#include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "pseventparser.h" 16 | #include "ptpobjinfoparser.h" 17 | 18 | #define DEV_ADDR 1 19 | 20 | // Canon PowerShot S3 IS 21 | #define DATA_IN_EP 1 22 | #define DATA_OUT_EP 2 23 | #define INTERRUPT_EP 3 24 | #define CONFIG_NUM 1 25 | 26 | void setup(); 27 | void loop(); 28 | 29 | class CamStateHandlers : public PSStateHandlers 30 | { 31 | bool stateConnected; 32 | 33 | public: 34 | CamStateHandlers() : stateConnected(false) {}; 35 | 36 | virtual void OnDeviceDisconnectedState(PTP *ptp); 37 | virtual void OnDeviceInitializedState(PTP *ptp); 38 | } CamStates; 39 | 40 | CanonPS Ps(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 41 | SimpleTimer eventTimer, captureTimer; 42 | 43 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 44 | { 45 | if (stateConnected) 46 | { 47 | eventTimer.Disable(); 48 | captureTimer.Disable(); 49 | stateConnected = false; 50 | 51 | Notify(PSTR("Camera disconnected\r\n")); 52 | } 53 | } 54 | 55 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 56 | { 57 | if (!stateConnected) 58 | { 59 | Notify(PSTR("stateConnected\r\n")); 60 | 61 | stateConnected = true; 62 | eventTimer.Enable(); 63 | captureTimer.Enable(); 64 | } 65 | } 66 | 67 | void setup() 68 | { 69 | Serial.begin( 115200 ); 70 | Serial.println("Start"); 71 | Ps.Setup(); 72 | eventTimer.Set(&OnEventTimer, 200); 73 | captureTimer.Set(&OnCaptureTimer, 5000); 74 | delay( 200 ); 75 | } 76 | 77 | void loop() 78 | { 79 | eventTimer.Run(); 80 | captureTimer.Run(); 81 | Ps.Task(); 82 | } 83 | 84 | void OnCaptureTimer() 85 | { 86 | Ps.SetDevicePropValue(PS_DPC_CaptureTransferMode, (uint16_t)0x0D); 87 | 88 | uint16_t rc = Ps.Capture(); 89 | 90 | if (rc != PTP_RC_OK) 91 | Message(PSTR("Error: "), rc); 92 | } 93 | 94 | void OnEventTimer() 95 | { 96 | PSEventParser prs; 97 | Ps.EventCheck(&prs); 98 | 99 | if (uint32_t handle = prs.GetObjHandle()) 100 | { 101 | PTPObjInfoParser inf; 102 | Ps.GetObjectInfo(handle, &inf); 103 | } 104 | } 105 | 106 | 107 | -------------------------------------------------------------------------------- /examples/PSCapture/pseventparser.cpp: -------------------------------------------------------------------------------- 1 | #include "pseventparser.h" 2 | 3 | void PSEventParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) 4 | { 5 | uint16_t cntdn = (uint16_t)len; 6 | uint8_t *p = (uint8_t*)pbuf; 7 | 8 | switch (nStage) 9 | { 10 | case 0: 11 | p += 12; 12 | cntdn -= 12; 13 | 14 | if (!cntdn) 15 | return; 16 | nStage ++; 17 | 18 | case 1: 19 | //Notify(PSTR("\r\nEvent Block Size:\t")); 20 | theBuffer.valueSize = 4; 21 | valueParser.Initialize(&theBuffer); 22 | nStage ++; 23 | case 2: 24 | if (!valueParser.Parse(&p, &cntdn)) 25 | return; 26 | 27 | //PrintHex(*((uint32_t*)theBuffer.pValue)); 28 | nStage ++; 29 | case 3: 30 | //Notify(PSTR("\r\nNumber of Fields:\t")); 31 | theBuffer.valueSize = 2; 32 | valueParser.Initialize(&theBuffer); 33 | nStage ++; 34 | case 4: 35 | if (!valueParser.Parse(&p, &cntdn)) 36 | return; 37 | 38 | //PrintHex(*((uint16_t*)theBuffer.pValue)); 39 | nStage ++; 40 | case 5: 41 | //Notify(PSTR("\r\nEvent Code:\t")); 42 | theBuffer.valueSize = 2; 43 | valueParser.Initialize(&theBuffer); 44 | nStage ++; 45 | case 6: 46 | if (!valueParser.Parse(&p, &cntdn)) 47 | return; 48 | 49 | eventCode = *((uint16_t*)theBuffer.pValue); 50 | //PrintHex(*((uint16_t*)theBuffer.pValue)); 51 | nStage ++; 52 | case 7: 53 | //Notify(PSTR("\r\nTransaction ID:\t")); 54 | theBuffer.valueSize = 4; 55 | valueParser.Initialize(&theBuffer); 56 | nStage ++; 57 | case 8: 58 | if (!valueParser.Parse(&p, &cntdn)) 59 | return; 60 | 61 | //PrintHex(*((uint32_t*)theBuffer.pValue)); 62 | nStage ++; 63 | case 9: 64 | if (eventCode == PTP_EC_ObjectAdded) 65 | Notify(PSTR("\r\nObject Added:\t\t")); 66 | 67 | theBuffer.valueSize = 4; 68 | valueParser.Initialize(&theBuffer); 69 | nStage ++; 70 | case 10: 71 | if (eventCode == PTP_EC_ObjectAdded) 72 | { 73 | if (!valueParser.Parse(&p, &cntdn)) 74 | return; 75 | 76 | objHandle = *((uint32_t*)theBuffer.pValue); 77 | PrintHex(*((uint32_t*)theBuffer.pValue)); 78 | Notify(PSTR("\r\n")); 79 | } 80 | if (eventCode == PTP_EC_CaptureComplete) 81 | Notify(PSTR("\r\nCapture complete.\r\n")); 82 | nStage ++; 83 | case 11: 84 | nStage = 0; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /examples/PSCapture/pseventparser.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSEVENTPARSER_H__ 2 | #define __PSEVENTPARSER_H__ 3 | 4 | #include 5 | #include 6 | #include "ptpcallback.h" 7 | #include "ptpdebug.h" 8 | #include "canonps.h" 9 | 10 | class PSEventParser : public PTPReadParser 11 | { 12 | MultiValueBuffer theBuffer; 13 | uint32_t varBuffer; 14 | uint8_t nStage; 15 | uint16_t eventCode; 16 | uint32_t objHandle; 17 | 18 | MultiByteValueParser valueParser; 19 | 20 | public: 21 | PSEventParser() : nStage(0), varBuffer(0), objHandle(0) 22 | { 23 | theBuffer.pValue = &varBuffer; 24 | }; 25 | uint32_t GetObjHandle() { return objHandle; }; 26 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 27 | }; 28 | 29 | #endif // __PSEVENTPARSER_H__ 30 | -------------------------------------------------------------------------------- /examples/PSCapture/ptpobjinfoparser.cpp: -------------------------------------------------------------------------------- 1 | #include "ptpobjinfoparser.h" 2 | 3 | const char* PTPObjInfoParser::acNames[] PROGMEM = 4 | { 5 | msgUndefined, 6 | msgAssociation, 7 | msgScript, 8 | msgExecutable, 9 | msgText, 10 | msgHTML, 11 | msgDPOF, 12 | msgAIFF, 13 | msgWAV, 14 | msgMP3, 15 | msgAVI, 16 | msgMPEG, 17 | msgASF, 18 | msgQT 19 | }; 20 | 21 | const char* PTPObjInfoParser::imNames[] PROGMEM = 22 | { 23 | msgUndefined, 24 | msgEXIF_JPEG, 25 | msgTIFF_EP, 26 | msgFlashPix, 27 | msgBMP, 28 | msgCIFF, 29 | msgUndefined_0x3806, 30 | msgGIF, 31 | msgJFIF, 32 | msgPCD, 33 | msgPICT, 34 | msgPNG, 35 | msgUndefined_0x380C, 36 | msgTIFF, 37 | msgTIFF_IT, 38 | msgJP2, 39 | msgJPX, 40 | }; 41 | 42 | void PTPObjInfoParser::PrintFormat(uint16_t op) 43 | { 44 | Serial.print(op, HEX); 45 | Serial.print("\t"); 46 | //Notify(msgTab); 47 | 48 | if ((((op >> 8) & 0xFF) == 0x30) && ((op & 0xFF) <= (PTP_OFC_QT & 0xFF))) 49 | Notify((char*)pgm_read_word(&acNames[(op & 0xFF)])); 50 | else 51 | if ((((op >> 8) & 0xFF) == 0x38) && ((op & 0xFF) <= (PTP_OFC_JPX & 0xFF))) 52 | Notify((char*)pgm_read_word(&imNames[(op & 0xFF)])); 53 | else 54 | { 55 | switch (op) 56 | { 57 | case MTP_OFC_Undefined_Firmware: 58 | Notify(msgUndefined_Firmware); 59 | break; 60 | case MTP_OFC_Windows_Image_Format: 61 | Notify(msgWindows_Image_Format); 62 | break; 63 | case MTP_OFC_Undefined_Audio: 64 | Notify(msgUndefined_Audio); 65 | break; 66 | case MTP_OFC_WMA: 67 | Notify(msgWMA); 68 | break; 69 | case MTP_OFC_OGG: 70 | Notify(msgOGG); 71 | break; 72 | case MTP_OFC_AAC: 73 | Notify(msgAAC); 74 | break; 75 | case MTP_OFC_Audible: 76 | Notify(msgAudible); 77 | break; 78 | case MTP_OFC_FLAC: 79 | Notify(msgFLAC); 80 | break; 81 | case MTP_OFC_Undefined_Video: 82 | Notify(msgUndefined_Video); 83 | break; 84 | case MTP_OFC_WMV: 85 | Notify(msgWMV); 86 | break; 87 | case MTP_OFC_MP4_Container: 88 | Notify(msgMP4_Container); 89 | break; 90 | case MTP_OFC_MP2: 91 | Notify(msgMP2); 92 | break; 93 | case MTP_OFC_3GP_Container: 94 | Notify(msg3GP_Container); 95 | break; 96 | default: 97 | Notify(PSTR("Vendor defined")); 98 | } 99 | } 100 | Notify(PSTR("\r\n")); 101 | } 102 | 103 | void PTPObjInfoParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) 104 | { 105 | uint16_t cntdn = (uint16_t)len; 106 | uint8_t *p = (uint8_t*)pbuf; 107 | 108 | switch (nStage) 109 | { 110 | case 0: 111 | p += 12; 112 | cntdn -= 12; 113 | nStage ++; 114 | case 1: 115 | Notify(PSTR("Storage ID:\t\t")); 116 | theBuffer.valueSize = 4; 117 | valueParser.Initialize(&theBuffer); 118 | nStage ++; 119 | case 2: 120 | if (!valueParser.Parse(&p, &cntdn)) 121 | return; 122 | PrintHex(*((uint32_t*)theBuffer.pValue)); 123 | nStage ++; 124 | case 3: 125 | Notify(PSTR("\r\nObject Format:\t\t")); 126 | theBuffer.valueSize = 2; 127 | valueParser.Initialize(&theBuffer); 128 | nStage ++; 129 | case 4: 130 | if (!valueParser.Parse(&p, &cntdn)) 131 | return; 132 | PrintFormat(*((uint16_t*)theBuffer.pValue)); 133 | nStage ++; 134 | case 5: 135 | Notify(PSTR("Protection Status:\t")); 136 | theBuffer.valueSize = 2; 137 | valueParser.Initialize(&theBuffer); 138 | nStage ++; 139 | case 6: 140 | if (!valueParser.Parse(&p, &cntdn)) 141 | return; 142 | PrintHex(*((uint16_t*)theBuffer.pValue)); 143 | nStage ++; 144 | case 7: 145 | Notify(PSTR("\r\nObject Compressed Size:\t")); 146 | theBuffer.valueSize = 4; 147 | valueParser.Initialize(&theBuffer); 148 | nStage ++; 149 | case 8: 150 | if (!valueParser.Parse(&p, &cntdn)) 151 | return; 152 | PrintHex(*((uint32_t*)theBuffer.pValue)); 153 | nStage ++; 154 | case 9: 155 | Notify(PSTR("\r\nThumb Format:\t\t")); 156 | theBuffer.valueSize = 2; 157 | valueParser.Initialize(&theBuffer); 158 | nStage ++; 159 | case 10: 160 | if (!valueParser.Parse(&p, &cntdn)) 161 | return; 162 | PrintFormat(*((uint16_t*)theBuffer.pValue)); 163 | nStage ++; 164 | case 11: 165 | Notify(PSTR("Thumb Compressed Size:\t")); 166 | theBuffer.valueSize = 4; 167 | valueParser.Initialize(&theBuffer); 168 | nStage ++; 169 | case 12: 170 | if (!valueParser.Parse(&p, &cntdn)) 171 | return; 172 | PrintHex(*((uint32_t*)theBuffer.pValue)); 173 | nStage ++; 174 | case 13: 175 | Notify(PSTR("\r\nThumb Pix Width:\t")); 176 | theBuffer.valueSize = 4; 177 | valueParser.Initialize(&theBuffer); 178 | nStage ++; 179 | case 14: 180 | if (!valueParser.Parse(&p, &cntdn)) 181 | return; 182 | PrintHex(*((uint32_t*)theBuffer.pValue)); 183 | nStage ++; 184 | case 15: 185 | Notify(PSTR("\r\nThumb Pix Height:\t")); 186 | theBuffer.valueSize = 4; 187 | valueParser.Initialize(&theBuffer); 188 | nStage ++; 189 | case 16: 190 | if (!valueParser.Parse(&p, &cntdn)) 191 | return; 192 | PrintHex(*((uint32_t*)theBuffer.pValue)); 193 | nStage ++; 194 | case 17: 195 | Notify(PSTR("\r\nImage Pix Width:\t")); 196 | theBuffer.valueSize = 4; 197 | valueParser.Initialize(&theBuffer); 198 | nStage ++; 199 | case 18: 200 | if (!valueParser.Parse(&p, &cntdn)) 201 | return; 202 | PrintHex(*((uint32_t*)theBuffer.pValue)); 203 | nStage ++; 204 | case 19: 205 | Notify(PSTR("\r\nImage Pix Height:\t")); 206 | theBuffer.valueSize = 4; 207 | valueParser.Initialize(&theBuffer); 208 | nStage ++; 209 | case 20: 210 | if (!valueParser.Parse(&p, &cntdn)) 211 | return; 212 | PrintHex(*((uint32_t*)theBuffer.pValue)); 213 | nStage ++; 214 | case 21: 215 | Notify(PSTR("\r\nImage Bit Depth:\t")); 216 | theBuffer.valueSize = 4; 217 | valueParser.Initialize(&theBuffer); 218 | nStage ++; 219 | case 22: 220 | if (!valueParser.Parse(&p, &cntdn)) 221 | return; 222 | PrintHex(*((uint32_t*)theBuffer.pValue)); 223 | nStage ++; 224 | case 23: 225 | Notify(PSTR("\r\nParent Object:\t\t")); 226 | theBuffer.valueSize = 4; 227 | valueParser.Initialize(&theBuffer); 228 | nStage ++; 229 | case 24: 230 | if (!valueParser.Parse(&p, &cntdn)) 231 | return; 232 | PrintHex(*((uint32_t*)theBuffer.pValue)); 233 | nStage ++; 234 | case 25: 235 | Notify(PSTR("\r\nAssociation Type:\t")); 236 | theBuffer.valueSize = 2; 237 | valueParser.Initialize(&theBuffer); 238 | nStage ++; 239 | case 26: 240 | if (!valueParser.Parse(&p, &cntdn)) 241 | return; 242 | PrintHex(*((uint16_t*)theBuffer.pValue)); 243 | nStage ++; 244 | case 27: 245 | Notify(PSTR("\r\nAssociation Desc:\t")); 246 | theBuffer.valueSize = 4; 247 | valueParser.Initialize(&theBuffer); 248 | nStage ++; 249 | case 28: 250 | if (!valueParser.Parse(&p, &cntdn)) 251 | return; 252 | PrintHex(*((uint32_t*)theBuffer.pValue)); 253 | nStage ++; 254 | case 29: 255 | Notify(PSTR("\r\nSequence Number:\t")); 256 | theBuffer.valueSize = 4; 257 | valueParser.Initialize(&theBuffer); 258 | nStage ++; 259 | case 30: 260 | if (!valueParser.Parse(&p, &cntdn)) 261 | return; 262 | PrintHex(*((uint32_t*)theBuffer.pValue)); 263 | nStage ++; 264 | case 31: 265 | Notify(PSTR("\r\nFile Name:\t\t")); 266 | arrayParser.Initialize(1, 2, &theBuffer); 267 | nStage ++; 268 | case 32: 269 | if (!arrayParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PrintChar)) 270 | return; 271 | nStage ++; 272 | case 33: 273 | Notify(PSTR("\r\nCapture Date:\t\t")); 274 | arrayParser.Initialize(1, 2, &theBuffer); 275 | nStage ++; 276 | case 34: 277 | if (!arrayParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PrintChar)) 278 | return; 279 | nStage ++; 280 | case 35: 281 | Notify(PSTR("\r\nModification Date:\t")); 282 | arrayParser.Initialize(1, 2, &theBuffer); 283 | nStage ++; 284 | case 36: 285 | if (!arrayParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PrintChar)) 286 | return; 287 | nStage ++; 288 | case 37: 289 | Notify(PSTR("\r\nKeywords:\t")); 290 | arrayParser.Initialize(1, 2, &theBuffer); 291 | nStage ++; 292 | case 38: 293 | if (!arrayParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PrintChar)) 294 | return; 295 | Notify(PSTR("\r\n")); 296 | nStage = 0; 297 | } 298 | } 299 | -------------------------------------------------------------------------------- /examples/PSCapture/ptpobjinfoparser.h: -------------------------------------------------------------------------------- 1 | #ifndef __PTPOBJINFOPARSER_H__ 2 | #define __PTPOBJINFOPARSER_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | const char msgUndefined [] PROGMEM = "Undefined"; 9 | 10 | // Ancillary formats 11 | const char msgAssociation [] PROGMEM = "Association"; 12 | const char msgScript [] PROGMEM = "Script"; 13 | const char msgExecutable [] PROGMEM = "Executable"; 14 | const char msgText [] PROGMEM = "Text"; 15 | const char msgHTML [] PROGMEM = "HTML"; 16 | const char msgDPOF [] PROGMEM = "DPOF"; 17 | const char msgAIFF [] PROGMEM = "AIFF"; 18 | const char msgWAV [] PROGMEM = "WAV"; 19 | const char msgMP3 [] PROGMEM = "MP3"; 20 | const char msgAVI [] PROGMEM = "AVI"; 21 | const char msgMPEG [] PROGMEM = "MPEG"; 22 | const char msgASF [] PROGMEM = "ASF"; 23 | const char msgQT [] PROGMEM = "QT"; 24 | 25 | // Image formats 26 | const char msgEXIF_JPEG [] PROGMEM = "EXIF_JPEG"; 27 | const char msgTIFF_EP [] PROGMEM = "TIFF_EP"; 28 | const char msgFlashPix [] PROGMEM = "FlashPix"; 29 | const char msgBMP [] PROGMEM = "BMP"; 30 | const char msgCIFF [] PROGMEM = "CIFF"; 31 | const char msgUndefined_0x3806 [] PROGMEM = "Undefined_0x3806"; 32 | const char msgGIF [] PROGMEM = "GIF"; 33 | const char msgJFIF [] PROGMEM = "JFIF"; 34 | const char msgPCD [] PROGMEM = "PCD"; 35 | const char msgPICT [] PROGMEM = "PICT"; 36 | const char msgPNG [] PROGMEM = "PNG"; 37 | const char msgUndefined_0x380C [] PROGMEM = "Undefined_0x380C"; 38 | const char msgTIFF [] PROGMEM = "TIFF"; 39 | const char msgTIFF_IT [] PROGMEM = "TIFF_IT"; 40 | const char msgJP2 [] PROGMEM = "JP2"; 41 | const char msgJPX [] PROGMEM = "JPX"; 42 | 43 | // MTP Object Formats 44 | const char msgUndefined_Firmware [] PROGMEM = "Undefined_Firmware"; 45 | const char msgWindows_Image_Format [] PROGMEM = "Windows_Image_Format"; 46 | const char msgUndefined_Audio [] PROGMEM = "Undefined_Audio"; 47 | const char msgWMA [] PROGMEM = "WMA"; 48 | const char msgOGG [] PROGMEM = "OGG"; 49 | const char msgAAC [] PROGMEM = "AAC"; 50 | const char msgAudible [] PROGMEM = "Audible"; 51 | const char msgFLAC [] PROGMEM = "FLAC"; 52 | const char msgUndefined_Video [] PROGMEM = "Undefined_Video"; 53 | const char msgWMV [] PROGMEM = "WMV"; 54 | const char msgMP4_Container [] PROGMEM = "MP4_Container"; 55 | const char msgMP2 [] PROGMEM = "MP2"; 56 | const char msg3GP_Container [] PROGMEM = "3GP_Container"; 57 | 58 | 59 | class PTPObjInfoParser : public PTPReadParser 60 | { 61 | static const char* acNames[]; 62 | static const char* imNames[]; 63 | 64 | MultiValueBuffer theBuffer; 65 | uint32_t varBuffer; 66 | uint8_t nStage; 67 | 68 | MultiByteValueParser valueParser; 69 | PTPListParser arrayParser; 70 | 71 | static void PrintChar(MultiValueBuffer *p) 72 | { 73 | if (((unsigned char*)p->pValue)[0]) 74 | Serial.print(((unsigned char*)p->pValue)[0]); 75 | }; 76 | void PrintFormat(uint16_t op); 77 | 78 | public: 79 | PTPObjInfoParser() : nStage(0) { theBuffer.pValue = (uint8_t*)&varBuffer; }; 80 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 81 | }; 82 | 83 | #endif // __PTPOBJINFOPARSER_H__ 84 | -------------------------------------------------------------------------------- /examples/PSCapture/sample_output.txt: -------------------------------------------------------------------------------- 1 | Session opened 2 | stateConnected 3 | 4 | Object Added: 00000005 5 | Storage ID: 00010001 6 | Object Format: 3801 EXIF_JPEG 7 | Protection Status: 0000 8 | Object Compressed Size: 00315A1A 9 | Thumb Format: 3808 JFIF 10 | Thumb Compressed Size: 0000107A 11 | Thumb Pix Width: 000000A0 12 | Thumb Pix Height: 00000078 13 | Image Pix Width: 00000E40 14 | Image Pix Height: 00000AB0 15 | Image Bit Depth: 00000000 16 | Parent Object: 00000004 17 | Association Type: 0000 18 | Association Desc: 00000001 19 | Sequence Number: 00000000 20 | File Name: IMG_0991.JPG 21 | Capture Date: 20110115T010141.0 22 | Modification Date: 23 | Keywords: 24 | 25 | Capture complete. 26 | 27 | Object Added: 00000006 28 | Storage ID: 00010001 29 | Object Format: 3801 EXIF_JPEG 30 | Protection Status: 0000 31 | Object Compressed Size: 002F6B25 32 | Thumb Format: 3808 JFIF 33 | Thumb Compressed Size: 0000106B 34 | Thumb Pix Width: 000000A0 35 | Thumb Pix Height: 00000078 36 | Image Pix Width: 00000E40 37 | Image Pix Height: 00000AB0 38 | Image Bit Depth: 00000000 39 | Parent Object: 00000004 40 | Association Type: 0000 41 | Association Desc: 00000001 42 | Sequence Number: 00000000 43 | File Name: IMG_0992.JPG 44 | Capture Date: 20110115T010146.0 45 | Modification Date: 46 | Keywords: 47 | 48 | Capture complete. 49 | 50 | Object Added: 00000007 51 | Storage ID: 00010001 52 | Object Format: 3801 EXIF_JPEG 53 | Protection Status: 0000 54 | Object Compressed Size: 002FE0BF 55 | Thumb Format: 3808 JFIF 56 | Thumb Compressed Size: 00001085 57 | Thumb Pix Width: 000000A0 58 | Thumb Pix Height: 00000078 59 | Image Pix Width: 00000E40 60 | Image Pix Height: 00000AB0 61 | Image Bit Depth: 00000000 62 | Parent Object: 00000004 63 | Association Type: 0000 64 | Association Desc: 00000001 65 | Sequence Number: 00000000 66 | File Name: IMG_0993.JPG 67 | Capture Date: 20110115T010151.0 68 | Modification Date: 69 | Keywords: 70 | 71 | Capture complete. 72 | 73 | Object Added: 00000008 74 | Storage ID: 00010001 75 | Object Format: 3801 EXIF_JPEG 76 | Protection Status: 0000 77 | Object Compressed Size: 002EDF53 78 | Thumb Format: 3808 JFIF 79 | Thumb Compressed Size: 00001082 80 | Thumb Pix Width: 000000A0 81 | Thumb Pix Height: 00000078 82 | Image Pix Width: 00000E40 83 | Image Pix Height: 00000AB0 84 | Image Bit Depth: 00000000 85 | Parent Object: 00000004 86 | Association Type: 0000 87 | Association Desc: 00000001 88 | Sequence Number: 00000000 89 | File Name: IMG_0994.JPG 90 | Capture Date: 20110115T010157.0 91 | Modification Date: 92 | Keywords: 93 | 94 | Capture complete. 95 | Camera disconnected 96 | 97 | -------------------------------------------------------------------------------- /examples/PSDevProp/PSDevProp.pde: -------------------------------------------------------------------------------- 1 | /* Canon Powershot Device Property Parser */ 2 | #include 3 | #include 4 | 5 | //#include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "devpropparser.h" 17 | 18 | #define DEV_ADDR 1 19 | 20 | // Canon PowerShot S3 IS 21 | #define DATA_IN_EP 1 22 | #define DATA_OUT_EP 2 23 | #define INTERRUPT_EP 3 24 | #define CONFIG_NUM 1 25 | 26 | class CamStateHandlers : public PSStateHandlers 27 | { 28 | enum CamStates { stInitial, stDisconnected, stConnected }; 29 | CamStates stateConnected; 30 | 31 | public: 32 | CamStateHandlers() : stateConnected(stInitial) 33 | { 34 | }; 35 | 36 | virtual void OnDeviceDisconnectedState(PTP *ptp); 37 | virtual void OnDeviceInitializedState(PTP *ptp); 38 | }; 39 | 40 | CamStateHandlers CamStates; 41 | CanonPS Ps(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 42 | 43 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 44 | { 45 | if (stateConnected == stConnected || stateConnected == stInitial) 46 | { 47 | stateConnected = stDisconnected; 48 | Notify(PSTR("Camera disconnected\r\n")); 49 | } 50 | } 51 | 52 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 53 | { 54 | if (stateConnected == stDisconnected || stateConnected == stInitial) 55 | { 56 | stateConnected = stConnected; 57 | 58 | uint16_t prefix = 0xD000; 59 | 60 | uint16_t shoot_mode[] = {0x01, 0x02, 0x03, 0x04}; 61 | 62 | for (uint8_t i=0; i<4; i++) 63 | { 64 | Ps.SetDevicePropValue(PS_DPC_ShootingMode, (uint16_t)shoot_mode[i]); 65 | delay(10); 66 | 67 | Notify(PSTR("Mode:")); 68 | PrintValueTitle((PTP*)ptp, PS_DPC_ShootingMode, ModeTitles); 69 | Notify(PSTR("\r\n")); 70 | 71 | for (uint8_t j=0; j<128; j++) 72 | { 73 | HexDump dmp; 74 | 75 | if (Ps.GetDevicePropDesc((prefix | j), &dmp) == PTP_RC_OK) 76 | { 77 | Notify(PSTR("\r\n")); 78 | 79 | DevPropParser prs; 80 | 81 | if (Ps.GetDevicePropDesc((prefix | j), &prs) == PTP_RC_OK) 82 | Notify(PSTR("\r\n")); 83 | } 84 | } 85 | 86 | Notify(PSTR("\r\n")); 87 | 88 | } // for (uint8_t i=0; i<4; i++) 89 | 90 | } // if (stateConnected == stDisconnected || stateConnected == stInitial) 91 | } 92 | 93 | void setup() 94 | { 95 | Serial.begin( 115200 ); 96 | Serial.println("Start"); 97 | Ps.Setup(); 98 | delay( 200 ); 99 | } 100 | 101 | void loop() 102 | { 103 | Ps.Task(); 104 | } 105 | 106 | -------------------------------------------------------------------------------- /examples/PSDevProp/devpropparser.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEVPROPPARSER_H__ 2 | #define __DEVPROPPARSER_H__ 3 | 4 | #include 5 | #include 6 | #include <../ptp/ptpconst.h> 7 | #include <../ptp/ptp.h> 8 | 9 | // Device properties 10 | const char msgUndefined [] PROGMEM = "Undefined"; 11 | const char msgBatteryLevel [] PROGMEM = "BatteryLevel"; 12 | const char msgFunctionalMode [] PROGMEM = "FunctionalMode"; 13 | const char msgImageSize [] PROGMEM = "ImageSize"; 14 | const char msgCompressionSetting [] PROGMEM = "CompressionSetting"; 15 | const char msgWhiteBalance [] PROGMEM = "WhiteBalance"; 16 | const char msgRGBGain [] PROGMEM = "RGBGain"; 17 | const char msgFNumber [] PROGMEM = "FNumber"; 18 | const char msgFocalLength [] PROGMEM = "FocalLength"; 19 | const char msgFocusDistance [] PROGMEM = "FocusDistance"; 20 | const char msgFocusMode [] PROGMEM = "FocusMode"; 21 | const char msgExposureMeteringMode [] PROGMEM = "ExposureMeteringMode"; 22 | const char msgFlashMode [] PROGMEM = "FlashMode"; 23 | const char msgExposureTime [] PROGMEM = "ExposureTime"; 24 | const char msgExposureProgramMode [] PROGMEM = "ExposureProgramMode"; 25 | const char msgExposureIndex [] PROGMEM = "ExposureIndex"; 26 | const char msgExposureBiasCompensation [] PROGMEM = "ExposureBiasCompensation"; 27 | const char msgDateTime [] PROGMEM = "DateTime"; 28 | const char msgCaptureDelay [] PROGMEM = "CaptureDelay"; 29 | const char msgStillCaptureMode [] PROGMEM = "StillCaptureMode"; 30 | const char msgContrast [] PROGMEM = "Contrast"; 31 | const char msgSharpness [] PROGMEM = "Sharpness"; 32 | const char msgDigitalZoom [] PROGMEM = "DigitalZoom"; 33 | const char msgEffectMode [] PROGMEM = "EffectMode"; 34 | const char msgBurstNumber [] PROGMEM = "BurstNumber"; 35 | const char msgBurstInterval [] PROGMEM = "BurstInterval"; 36 | const char msgTimelapseNumber [] PROGMEM = "TimelapseNumber"; 37 | const char msgTimelapseInterval [] PROGMEM = "TimelapseInterval"; 38 | const char msgFocusMeteringMode [] PROGMEM = "FocusMeteringMode"; 39 | const char msgUploadURL [] PROGMEM = "UploadURL"; 40 | const char msgArtist [] PROGMEM = "Artist"; 41 | const char msgCopyrightInfo [] PROGMEM = "CopyrightInfo"; 42 | 43 | // Data Types 44 | const char msgUNDEF [] PROGMEM = "UNDEF"; 45 | const char msgINT8 [] PROGMEM = "INT8"; 46 | const char msgUINT8 [] PROGMEM = "UINT8"; 47 | const char msgINT16 [] PROGMEM = "INT16"; 48 | const char msgUINT16 [] PROGMEM = "UINT16"; 49 | const char msgINT32 [] PROGMEM = "INT32"; 50 | const char msgUINT32 [] PROGMEM = "UINT32"; 51 | const char msgINT64 [] PROGMEM = "INT64"; 52 | const char msgUINT64 [] PROGMEM = "UINT64"; 53 | const char msgINT128 [] PROGMEM = "INT128"; 54 | const char msgUINT128 [] PROGMEM = "UINT128"; 55 | const char msgAINT8 [] PROGMEM = "AINT8"; 56 | const char msgAUINT8 [] PROGMEM = "AUINT8"; 57 | const char msgAINT16 [] PROGMEM = "AINT16"; 58 | const char msgAUINT16 [] PROGMEM = "AUINT16"; 59 | const char msgAINT32 [] PROGMEM = "AINT32"; 60 | const char msgAUINT32 [] PROGMEM = "AUINT32"; 61 | const char msgAINT64 [] PROGMEM = "AINT64"; 62 | const char msgAUINT64 [] PROGMEM = "AUINT64"; 63 | const char msgAINT128 [] PROGMEM = "AINT128"; 64 | const char msgAUINT128 [] PROGMEM = "AUINT128"; 65 | const char msgSTR [] PROGMEM = "STR"; 66 | 67 | 68 | class DevPropParser : public PTPReadParser 69 | { 70 | static const char* dtNames1[]; 71 | static const char* dtNames2[]; 72 | static const char* prNames[]; 73 | 74 | uint8_t nStage; 75 | uint8_t enStage; 76 | uint16_t dataType; 77 | uint8_t formFlag; 78 | uint8_t bytesSize; 79 | MultiValueBuffer theBuffer; 80 | uint8_t varBuffer[16]; 81 | uint16_t enLen; 82 | uint16_t enLenCntdn; 83 | 84 | MultiByteValueParser valParser; 85 | 86 | void PrintDevProp (uint8_t **pp, uint16_t *pcntdn); 87 | void PrintDataType (uint8_t **pp, uint16_t *pcntdn); 88 | void PrintGetSet (uint8_t **pp, uint16_t *pcntdn); 89 | bool PrintValue (uint8_t **pp, uint16_t *pcntdn); 90 | bool PrintEnum (uint8_t **pp, uint16_t *pcntdn); 91 | bool ParseEnum (uint8_t **pp, uint16_t *pcntdn); 92 | bool ParseEnumSingle (uint8_t **pp, uint16_t *pcntdn); 93 | bool ParseEnumArray (uint8_t **pp, uint16_t *pcntdn); 94 | 95 | static void PrintChar(const MultiValueBuffer * const p, uint32_t count, const void *me) 96 | { 97 | if (((unsigned char*)p->pValue)[0]) 98 | Serial.print(((unsigned char*)p->pValue)[0]); 99 | }; 100 | static void PrintByte(const MultiValueBuffer * const p, uint32_t count, const void *me) 101 | { 102 | if (count) 103 | Notify(PSTR(",")); 104 | PrintHex(((uint8_t*)p->pValue)[0]); 105 | }; 106 | static void PrintTwoBytes(const MultiValueBuffer * const p, uint32_t count, const void *me) 107 | { 108 | if (count) 109 | Notify(PSTR(",")); 110 | PrintHex(((uint16_t*)p->pValue)[0]); 111 | }; 112 | static void PrintFourBytes(const MultiValueBuffer * const p, uint32_t count, const void *me) 113 | { 114 | if (count) 115 | Notify(PSTR(",")); 116 | PrintHex(((uint32_t*)p->pValue)[0]); 117 | }; 118 | static void PrintEightBytes(const MultiValueBuffer * const p, uint32_t count, const void *me) 119 | { 120 | if (count) 121 | Notify(PSTR(",")); 122 | for (uint8_t i=p->valueSize; i; i--) 123 | PrintHex(((uint8_t*)p->pValue)[i-1]); 124 | }; 125 | static void PrintEnumValue(const MultiValueBuffer * const p, uint32_t count, const void *me) 126 | { 127 | if (count) 128 | Serial.print(", "); 129 | 130 | switch (((MultiValueBuffer*)p)->valueSize) 131 | { 132 | case 1: 133 | PrintHex(*((uint8_t*)p->pValue)); 134 | break; 135 | case 2: 136 | PrintHex(*((uint16_t*)p->pValue)); 137 | break; 138 | case 4: 139 | PrintHex(*((uint32_t*)p->pValue)); 140 | break; 141 | default: 142 | for (uint8_t i=p->valueSize; i; i--) 143 | PrintHex(((uint8_t*)p->pValue)[i-1]); 144 | } 145 | count++; 146 | }; 147 | 148 | PTPListParser enumParser; 149 | 150 | uint8_t GetDataSize(); 151 | 152 | public: 153 | DevPropParser() : 154 | nStage(0), 155 | enStage(0), 156 | dataType(0), 157 | formFlag(0), 158 | bytesSize(0), 159 | enLen(0), 160 | enLenCntdn(0) 161 | { 162 | theBuffer.pValue = varBuffer; 163 | } 164 | virtual void Parse(const uint16_t len, const uint8_t * const pbuf, const uint32_t &offset); 165 | }; 166 | 167 | #endif // __DEVPROPPARSER_H__ 168 | -------------------------------------------------------------------------------- /examples/PSRemote/PSRemote.pde: -------------------------------------------------------------------------------- 1 | /* Canon Powershot control terminal */ 2 | //#include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "ptpdpparser.h" 13 | #include "ptpobjinfoparser.h" 14 | #include "pseventparser.h" 15 | #include "psconsole.h" 16 | 17 | #define DEV_ADDR 1 18 | 19 | // Canon PowerShot S3 IS 20 | #define DATA_IN_EP 1 21 | #define DATA_OUT_EP 2 22 | #define INTERRUPT_EP 3 23 | #define CONFIG_NUM 1 24 | 25 | class CamStateHandlers : public PSStateHandlers 26 | { 27 | enum CamStates { stInitial, stDisconnected, stConnected }; 28 | CamStates stateConnected; 29 | 30 | public: 31 | CamStateHandlers() : stateConnected(stInitial) 32 | { 33 | }; 34 | 35 | virtual void OnDeviceDisconnectedState(PTP *ptp); 36 | virtual void OnDeviceInitializedState(PTP *ptp); 37 | }; 38 | 39 | CamStateHandlers CamStates; 40 | SimpleTimer ControlTimer, PTPPollTimer; 41 | 42 | CanonPS Ps(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 43 | QEvent evtTick, evtAbort; 44 | PSConsole psConsole; 45 | 46 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 47 | { 48 | if (stateConnected == stConnected || stateConnected == stInitial) 49 | { 50 | stateConnected = stDisconnected; 51 | PTPPollTimer.Disable(); 52 | Notify(PSTR("Camera disconnected.\r\n")); 53 | 54 | if (stateConnected == stConnected) 55 | psConsole.dispatch(&evtTick); 56 | } 57 | } 58 | 59 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 60 | { 61 | if (stateConnected == stDisconnected || stateConnected == stInitial) 62 | { 63 | stateConnected = stConnected; 64 | PTPPollTimer.Enable(); 65 | psConsole.dispatch(&evtTick); 66 | } 67 | int8_t index = psConsole.MenuSelect(); 68 | 69 | if (index >= 0) 70 | { 71 | MenuSelectEvt menu_sel_evt; 72 | menu_sel_evt.sig = MENU_SELECT_SIG; 73 | menu_sel_evt.item_index = index; 74 | psConsole.dispatch(&menu_sel_evt); // dispatch the event 75 | } 76 | } 77 | 78 | void OnPTPPollTimer() 79 | { 80 | PSEventParser prs; 81 | Ps.EventCheck(&prs); 82 | 83 | if (uint32_t handle = prs.GetObjHandle()) 84 | { 85 | PTPObjInfoParser inf; 86 | Ps.GetObjectInfo(handle, &inf); 87 | } 88 | } 89 | 90 | void setup() 91 | { 92 | Serial.begin(115200); 93 | Ps.Setup(); 94 | delay( 200 ); 95 | 96 | PTPPollTimer.Set(OnPTPPollTimer, 300); 97 | 98 | evtTick.sig = TICK_SIG; 99 | // evtAbort.sig = ABORT_SIG; 100 | psConsole.init(); 101 | 102 | Serial.println("Start"); 103 | } 104 | 105 | void loop() 106 | { 107 | Ps.Task(); 108 | PTPPollTimer.Run(); 109 | } 110 | 111 | -------------------------------------------------------------------------------- /examples/PSRemote/psconsole.h: -------------------------------------------------------------------------------- 1 | #if !defined(__PSCONSOLE_H__) 2 | #define __PSCONSOLE_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "ptpdpparser.h" 11 | 12 | enum TextMenuSignals 13 | { 14 | MENU_SELECT_SIG = Q_USER_SIG, 15 | TICK_SIG 16 | }; 17 | 18 | struct TickEvt : public QEvent 19 | { 20 | uint8_t fine_time; // the fine 1/10 s counter 21 | }; 22 | 23 | struct MenuSelectEvt : public QEvent 24 | { 25 | uint8_t item_index; 26 | }; 27 | 28 | class PSConsole : public QHsm 29 | { 30 | static void PrintMenuTitles(uint8_t count, const char **menu); 31 | static void ShowParams(); 32 | 33 | public: 34 | PSConsole() 35 | : QHsm((QStateHandler)&PSConsole::Initial) 36 | {}; 37 | int8_t MenuSelect(); 38 | 39 | protected: 40 | static QState Initial(PSConsole *me, QEvent const *e); 41 | static QState Inactive(PSConsole *me, QEvent const *e); 42 | static QState Active(PSConsole *me, QEvent const *e); 43 | static QState MainMenu(PSConsole *me, QEvent const *e); 44 | static QState ChangeSettingsMenu(PSConsole *me, QEvent const *e); 45 | static QState ChangeModeMenu(PSConsole *me, QEvent const *e); 46 | static QState ChangeApertureMenu(PSConsole *me, QEvent const *e); 47 | static QState ChangeShutterSpeedMenu(PSConsole *me, QEvent const *e); 48 | static QState ChangeWBMenu(PSConsole *me, QEvent const *e); 49 | static QState ChangeImageModeMenu(PSConsole *me, QEvent const *e); 50 | static QState ChangeExpCompMenu(PSConsole *me, QEvent const *e); 51 | static QState ChangeIsoMenu(PSConsole *me, QEvent const *e); 52 | static QState ChangeCamOutputMenu(PSConsole *me, QEvent const *e); 53 | static QState ChangeZoomMenu(PSConsole *me, QEvent const *e); 54 | }; 55 | 56 | #endif // __PSCONSOLE_H__ 57 | -------------------------------------------------------------------------------- /examples/PSRemote/pseventparser.cpp: -------------------------------------------------------------------------------- 1 | #include "pseventparser.h" 2 | 3 | void PSEventParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) 4 | { 5 | uint16_t cntdn = (uint16_t)len; 6 | uint8_t *p = (uint8_t*)pbuf; 7 | 8 | switch (nStage) 9 | { 10 | case 0: 11 | p += 12; 12 | cntdn -= 12; 13 | 14 | if (!cntdn) 15 | return; 16 | nStage ++; 17 | 18 | case 1: 19 | theBuffer.valueSize = 4; 20 | valueParser.Initialize(&theBuffer); 21 | nStage ++; 22 | case 2: 23 | if (!valueParser.Parse(&p, &cntdn)) 24 | return; 25 | 26 | //PrintHex(*((uint32_t*)theBuffer.pValue)); 27 | nStage ++; 28 | case 3: 29 | //Notify(PSTR("\r\nNumber of Fields:\t")); 30 | theBuffer.valueSize = 2; 31 | valueParser.Initialize(&theBuffer); 32 | nStage ++; 33 | case 4: 34 | if (!valueParser.Parse(&p, &cntdn)) 35 | return; 36 | 37 | //PrintHex(*((uint16_t*)theBuffer.pValue)); 38 | nStage ++; 39 | case 5: 40 | //Notify(PSTR("\r\nEvent Code:\t")); 41 | theBuffer.valueSize = 2; 42 | valueParser.Initialize(&theBuffer); 43 | nStage ++; 44 | case 6: 45 | if (!valueParser.Parse(&p, &cntdn)) 46 | return; 47 | 48 | eventCode = *((uint16_t*)theBuffer.pValue); 49 | //PrintHex(*((uint16_t*)theBuffer.pValue)); 50 | nStage ++; 51 | case 7: 52 | //Notify(PSTR("\r\nTransaction ID:\t")); 53 | theBuffer.valueSize = 4; 54 | valueParser.Initialize(&theBuffer); 55 | nStage ++; 56 | case 8: 57 | if (!valueParser.Parse(&p, &cntdn)) 58 | return; 59 | 60 | //PrintHex(*((uint32_t*)theBuffer.pValue)); 61 | nStage ++; 62 | case 9: 63 | if (eventCode == PTP_EC_ObjectAdded) 64 | Notify(PSTR("\r\nObject Added:\t\t")); 65 | 66 | theBuffer.valueSize = 4; 67 | valueParser.Initialize(&theBuffer); 68 | nStage ++; 69 | case 10: 70 | if (eventCode == PTP_EC_ObjectAdded) 71 | { 72 | if (!valueParser.Parse(&p, &cntdn)) 73 | return; 74 | 75 | objHandle = *((uint32_t*)theBuffer.pValue); 76 | PrintHex(*((uint32_t*)theBuffer.pValue)); 77 | Notify(PSTR("\r\n")); 78 | } 79 | if (eventCode == PTP_EC_CaptureComplete) 80 | Notify(PSTR("\r\nCapture complete.\r\n")); 81 | nStage ++; 82 | case 11: 83 | nStage = 0; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /examples/PSRemote/pseventparser.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSEVENTPARSER_H__ 2 | #define __PSEVENTPARSER_H__ 3 | 4 | #include 5 | #include 6 | #include "ptpcallback.h" 7 | #include "ptpdebug.h" 8 | #include "canonps.h" 9 | 10 | class PSEventParser : public PTPReadParser 11 | { 12 | MultiValueBuffer theBuffer; 13 | uint32_t varBuffer; 14 | uint8_t nStage; 15 | uint16_t eventCode; 16 | uint32_t objHandle; 17 | 18 | MultiByteValueParser valueParser; 19 | 20 | public: 21 | PSEventParser() : nStage(0), varBuffer(0), objHandle(0) 22 | { 23 | theBuffer.pValue = &varBuffer; 24 | }; 25 | uint32_t GetObjHandle() { return objHandle; }; 26 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 27 | }; 28 | 29 | #endif // __PSEVENTPARSER_H__ 30 | -------------------------------------------------------------------------------- /examples/PSRemote/ptpobjinfoparser.cpp: -------------------------------------------------------------------------------- 1 | #include "ptpobjinfoparser.h" 2 | 3 | const char* PTPObjInfoParser::acNames[] PROGMEM = 4 | { 5 | msgUndefined, 6 | msgAssociation, 7 | msgScript, 8 | msgExecutable, 9 | msgText, 10 | msgHTML, 11 | msgDPOF, 12 | msgAIFF, 13 | msgWAV, 14 | msgMP3, 15 | msgAVI, 16 | msgMPEG, 17 | msgASF, 18 | msgQT 19 | }; 20 | 21 | const char* PTPObjInfoParser::imNames[] PROGMEM = 22 | { 23 | msgUndefined, 24 | msgEXIF_JPEG, 25 | msgTIFF_EP, 26 | msgFlashPix, 27 | msgBMP, 28 | msgCIFF, 29 | msgUndefined_0x3806, 30 | msgGIF, 31 | msgJFIF, 32 | msgPCD, 33 | msgPICT, 34 | msgPNG, 35 | msgUndefined_0x380C, 36 | msgTIFF, 37 | msgTIFF_IT, 38 | msgJP2, 39 | msgJPX, 40 | }; 41 | 42 | void PTPObjInfoParser::PrintFormat(uint16_t op) 43 | { 44 | Serial.print(op, HEX); 45 | Serial.print("\t"); 46 | //Notify(msgTab); 47 | 48 | if ((((op >> 8) & 0xFF) == 0x30) && ((op & 0xFF) <= (PTP_OFC_QT & 0xFF))) 49 | Notify((char*)pgm_read_word(&acNames[(op & 0xFF)])); 50 | else 51 | if ((((op >> 8) & 0xFF) == 0x38) && ((op & 0xFF) <= (PTP_OFC_JPX & 0xFF))) 52 | Notify((char*)pgm_read_word(&imNames[(op & 0xFF)])); 53 | else 54 | { 55 | switch (op) 56 | { 57 | case MTP_OFC_Undefined_Firmware: 58 | Notify(msgUndefined_Firmware); 59 | break; 60 | case MTP_OFC_Windows_Image_Format: 61 | Notify(msgWindows_Image_Format); 62 | break; 63 | case MTP_OFC_Undefined_Audio: 64 | Notify(msgUndefined_Audio); 65 | break; 66 | case MTP_OFC_WMA: 67 | Notify(msgWMA); 68 | break; 69 | case MTP_OFC_OGG: 70 | Notify(msgOGG); 71 | break; 72 | case MTP_OFC_AAC: 73 | Notify(msgAAC); 74 | break; 75 | case MTP_OFC_Audible: 76 | Notify(msgAudible); 77 | break; 78 | case MTP_OFC_FLAC: 79 | Notify(msgFLAC); 80 | break; 81 | case MTP_OFC_Undefined_Video: 82 | Notify(msgUndefined_Video); 83 | break; 84 | case MTP_OFC_WMV: 85 | Notify(msgWMV); 86 | break; 87 | case MTP_OFC_MP4_Container: 88 | Notify(msgMP4_Container); 89 | break; 90 | case MTP_OFC_MP2: 91 | Notify(msgMP2); 92 | break; 93 | case MTP_OFC_3GP_Container: 94 | Notify(msg3GP_Container); 95 | break; 96 | default: 97 | Notify(PSTR("Vendor defined")); 98 | } 99 | } 100 | Notify(PSTR("\r\n")); 101 | } 102 | 103 | void PTPObjInfoParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) 104 | { 105 | uint16_t cntdn = (uint16_t)len; 106 | uint8_t *p = (uint8_t*)pbuf; 107 | 108 | switch (nStage) 109 | { 110 | case 0: 111 | p += 12; 112 | cntdn -= 12; 113 | nStage ++; 114 | case 1: 115 | Notify(PSTR("Storage ID:\t\t")); 116 | theBuffer.valueSize = 4; 117 | valueParser.Initialize(&theBuffer); 118 | nStage ++; 119 | case 2: 120 | if (!valueParser.Parse(&p, &cntdn)) 121 | return; 122 | PrintHex(*((uint32_t*)theBuffer.pValue)); 123 | nStage ++; 124 | case 3: 125 | Notify(PSTR("\r\nObject Format:\t\t")); 126 | theBuffer.valueSize = 2; 127 | valueParser.Initialize(&theBuffer); 128 | nStage ++; 129 | case 4: 130 | if (!valueParser.Parse(&p, &cntdn)) 131 | return; 132 | PrintFormat(*((uint16_t*)theBuffer.pValue)); 133 | nStage ++; 134 | case 5: 135 | Notify(PSTR("Protection Status:\t")); 136 | theBuffer.valueSize = 2; 137 | valueParser.Initialize(&theBuffer); 138 | nStage ++; 139 | case 6: 140 | if (!valueParser.Parse(&p, &cntdn)) 141 | return; 142 | PrintHex(*((uint16_t*)theBuffer.pValue)); 143 | nStage ++; 144 | case 7: 145 | Notify(PSTR("\r\nObject Compressed Size:\t")); 146 | theBuffer.valueSize = 4; 147 | valueParser.Initialize(&theBuffer); 148 | nStage ++; 149 | case 8: 150 | if (!valueParser.Parse(&p, &cntdn)) 151 | return; 152 | PrintHex(*((uint32_t*)theBuffer.pValue)); 153 | nStage ++; 154 | case 9: 155 | Notify(PSTR("\r\nThumb Format:\t\t")); 156 | theBuffer.valueSize = 2; 157 | valueParser.Initialize(&theBuffer); 158 | nStage ++; 159 | case 10: 160 | if (!valueParser.Parse(&p, &cntdn)) 161 | return; 162 | PrintFormat(*((uint16_t*)theBuffer.pValue)); 163 | nStage ++; 164 | case 11: 165 | Notify(PSTR("Thumb Compressed Size:\t")); 166 | theBuffer.valueSize = 4; 167 | valueParser.Initialize(&theBuffer); 168 | nStage ++; 169 | case 12: 170 | if (!valueParser.Parse(&p, &cntdn)) 171 | return; 172 | PrintHex(*((uint32_t*)theBuffer.pValue)); 173 | nStage ++; 174 | case 13: 175 | Notify(PSTR("\r\nThumb Pix Width:\t")); 176 | theBuffer.valueSize = 4; 177 | valueParser.Initialize(&theBuffer); 178 | nStage ++; 179 | case 14: 180 | if (!valueParser.Parse(&p, &cntdn)) 181 | return; 182 | PrintHex(*((uint32_t*)theBuffer.pValue)); 183 | nStage ++; 184 | case 15: 185 | Notify(PSTR("\r\nThumb Pix Height:\t")); 186 | theBuffer.valueSize = 4; 187 | valueParser.Initialize(&theBuffer); 188 | nStage ++; 189 | case 16: 190 | if (!valueParser.Parse(&p, &cntdn)) 191 | return; 192 | PrintHex(*((uint32_t*)theBuffer.pValue)); 193 | nStage ++; 194 | case 17: 195 | Notify(PSTR("\r\nImage Pix Width:\t")); 196 | theBuffer.valueSize = 4; 197 | valueParser.Initialize(&theBuffer); 198 | nStage ++; 199 | case 18: 200 | if (!valueParser.Parse(&p, &cntdn)) 201 | return; 202 | PrintHex(*((uint32_t*)theBuffer.pValue)); 203 | nStage ++; 204 | case 19: 205 | Notify(PSTR("\r\nImage Pix Height:\t")); 206 | theBuffer.valueSize = 4; 207 | valueParser.Initialize(&theBuffer); 208 | nStage ++; 209 | case 20: 210 | if (!valueParser.Parse(&p, &cntdn)) 211 | return; 212 | PrintHex(*((uint32_t*)theBuffer.pValue)); 213 | nStage ++; 214 | case 21: 215 | Notify(PSTR("\r\nImage Bit Depth:\t")); 216 | theBuffer.valueSize = 4; 217 | valueParser.Initialize(&theBuffer); 218 | nStage ++; 219 | case 22: 220 | if (!valueParser.Parse(&p, &cntdn)) 221 | return; 222 | PrintHex(*((uint32_t*)theBuffer.pValue)); 223 | nStage ++; 224 | case 23: 225 | Notify(PSTR("\r\nParent Object:\t\t")); 226 | theBuffer.valueSize = 4; 227 | valueParser.Initialize(&theBuffer); 228 | nStage ++; 229 | case 24: 230 | if (!valueParser.Parse(&p, &cntdn)) 231 | return; 232 | PrintHex(*((uint32_t*)theBuffer.pValue)); 233 | nStage ++; 234 | case 25: 235 | Notify(PSTR("\r\nAssociation Type:\t")); 236 | theBuffer.valueSize = 2; 237 | valueParser.Initialize(&theBuffer); 238 | nStage ++; 239 | case 26: 240 | if (!valueParser.Parse(&p, &cntdn)) 241 | return; 242 | PrintHex(*((uint16_t*)theBuffer.pValue)); 243 | nStage ++; 244 | case 27: 245 | Notify(PSTR("\r\nAssociation Desc:\t")); 246 | theBuffer.valueSize = 4; 247 | valueParser.Initialize(&theBuffer); 248 | nStage ++; 249 | case 28: 250 | if (!valueParser.Parse(&p, &cntdn)) 251 | return; 252 | PrintHex(*((uint32_t*)theBuffer.pValue)); 253 | nStage ++; 254 | case 29: 255 | Notify(PSTR("\r\nSequence Number:\t")); 256 | theBuffer.valueSize = 4; 257 | valueParser.Initialize(&theBuffer); 258 | nStage ++; 259 | case 30: 260 | if (!valueParser.Parse(&p, &cntdn)) 261 | return; 262 | PrintHex(*((uint32_t*)theBuffer.pValue)); 263 | nStage ++; 264 | case 31: 265 | Notify(PSTR("\r\nFile Name:\t\t")); 266 | arrayParser.Initialize(1, 2, &theBuffer); 267 | nStage ++; 268 | case 32: 269 | if (!arrayParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PrintChar)) 270 | return; 271 | nStage ++; 272 | case 33: 273 | Notify(PSTR("\r\nCapture Date:\t\t")); 274 | arrayParser.Initialize(1, 2, &theBuffer); 275 | nStage ++; 276 | case 34: 277 | if (!arrayParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PrintChar)) 278 | return; 279 | nStage ++; 280 | case 35: 281 | Notify(PSTR("\r\nModification Date:\t")); 282 | arrayParser.Initialize(1, 2, &theBuffer); 283 | nStage ++; 284 | case 36: 285 | if (!arrayParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PrintChar)) 286 | return; 287 | nStage ++; 288 | case 37: 289 | Notify(PSTR("\r\nKeywords:\t")); 290 | arrayParser.Initialize(1, 2, &theBuffer); 291 | nStage ++; 292 | case 38: 293 | if (!arrayParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PrintChar)) 294 | return; 295 | Notify(PSTR("\r\n")); 296 | nStage = 0; 297 | } 298 | } 299 | -------------------------------------------------------------------------------- /examples/PSRemote/ptpobjinfoparser.h: -------------------------------------------------------------------------------- 1 | #ifndef __PTPOBJINFOPARSER_H__ 2 | #define __PTPOBJINFOPARSER_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | const char msgUndefined [] PROGMEM = "Undefined"; 9 | 10 | // Ancillary formats 11 | const char msgAssociation [] PROGMEM = "Association"; 12 | const char msgScript [] PROGMEM = "Script"; 13 | const char msgExecutable [] PROGMEM = "Executable"; 14 | const char msgText [] PROGMEM = "Text"; 15 | const char msgHTML [] PROGMEM = "HTML"; 16 | const char msgDPOF [] PROGMEM = "DPOF"; 17 | const char msgAIFF [] PROGMEM = "AIFF"; 18 | const char msgWAV [] PROGMEM = "WAV"; 19 | const char msgMP3 [] PROGMEM = "MP3"; 20 | const char msgAVI [] PROGMEM = "AVI"; 21 | const char msgMPEG [] PROGMEM = "MPEG"; 22 | const char msgASF [] PROGMEM = "ASF"; 23 | const char msgQT [] PROGMEM = "QT"; 24 | 25 | // Image formats 26 | const char msgEXIF_JPEG [] PROGMEM = "EXIF_JPEG"; 27 | const char msgTIFF_EP [] PROGMEM = "TIFF_EP"; 28 | const char msgFlashPix [] PROGMEM = "FlashPix"; 29 | const char msgBMP [] PROGMEM = "BMP"; 30 | const char msgCIFF [] PROGMEM = "CIFF"; 31 | const char msgUndefined_0x3806 [] PROGMEM = "Undefined_0x3806"; 32 | const char msgGIF [] PROGMEM = "GIF"; 33 | const char msgJFIF [] PROGMEM = "JFIF"; 34 | const char msgPCD [] PROGMEM = "PCD"; 35 | const char msgPICT [] PROGMEM = "PICT"; 36 | const char msgPNG [] PROGMEM = "PNG"; 37 | const char msgUndefined_0x380C [] PROGMEM = "Undefined_0x380C"; 38 | const char msgTIFF [] PROGMEM = "TIFF"; 39 | const char msgTIFF_IT [] PROGMEM = "TIFF_IT"; 40 | const char msgJP2 [] PROGMEM = "JP2"; 41 | const char msgJPX [] PROGMEM = "JPX"; 42 | 43 | // MTP Object Formats 44 | const char msgUndefined_Firmware [] PROGMEM = "Undefined_Firmware"; 45 | const char msgWindows_Image_Format [] PROGMEM = "Windows_Image_Format"; 46 | const char msgUndefined_Audio [] PROGMEM = "Undefined_Audio"; 47 | const char msgWMA [] PROGMEM = "WMA"; 48 | const char msgOGG [] PROGMEM = "OGG"; 49 | const char msgAAC [] PROGMEM = "AAC"; 50 | const char msgAudible [] PROGMEM = "Audible"; 51 | const char msgFLAC [] PROGMEM = "FLAC"; 52 | const char msgUndefined_Video [] PROGMEM = "Undefined_Video"; 53 | const char msgWMV [] PROGMEM = "WMV"; 54 | const char msgMP4_Container [] PROGMEM = "MP4_Container"; 55 | const char msgMP2 [] PROGMEM = "MP2"; 56 | const char msg3GP_Container [] PROGMEM = "3GP_Container"; 57 | 58 | 59 | class PTPObjInfoParser : public PTPReadParser 60 | { 61 | static const char* acNames[]; 62 | static const char* imNames[]; 63 | 64 | MultiValueBuffer theBuffer; 65 | uint32_t varBuffer; 66 | uint8_t nStage; 67 | 68 | MultiByteValueParser valueParser; 69 | PTPListParser arrayParser; 70 | 71 | static void PrintChar(MultiValueBuffer *p) 72 | { 73 | if (((unsigned char*)p->pValue)[0]) 74 | Serial.print(((unsigned char*)p->pValue)[0]); 75 | }; 76 | void PrintFormat(uint16_t op); 77 | 78 | public: 79 | PTPObjInfoParser() : nStage(0) { theBuffer.pValue = (uint8_t*)&varBuffer; }; 80 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 81 | }; 82 | 83 | #endif // __PTPOBJINFOPARSER_H__ 84 | -------------------------------------------------------------------------------- /examples/PTPCapture/PTPCapture.pde: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #define DEV_ADDR 1 12 | 13 | // Nikon CoolPix P100 14 | #define DATA_IN_EP 2 15 | #define DATA_OUT_EP 1 16 | #define INTERRUPT_EP 3 17 | #define CONFIG_NUM 1 18 | 19 | // Canon 20 | //#define DATA_IN_EP 1 21 | //#define DATA_OUT_EP 2 22 | //#define INTERRUPT_EP 3 23 | //#define CONFIG_NUM 1 24 | 25 | #define MAX_USB_STRING_LEN 64 26 | 27 | class CamStateHandlers : public PTPStateHandlers 28 | { 29 | bool stateConnected; 30 | 31 | public: 32 | CamStateHandlers() : stateConnected(false) {}; 33 | 34 | virtual void OnDeviceDisconnectedState(PTP *ptp); 35 | virtual void OnDeviceInitializedState(PTP *ptp); 36 | } CamStates; 37 | 38 | PTP Ptp(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 39 | 40 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 41 | { 42 | if (stateConnected) 43 | { 44 | stateConnected = false; 45 | Notify(PSTR("Camera disconnected\r\n")); 46 | } 47 | } 48 | 49 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 50 | { 51 | if (!stateConnected) 52 | { 53 | stateConnected = true; 54 | 55 | Ptp.CaptureImage(); 56 | delay(1000); 57 | } 58 | } 59 | 60 | void setup() { 61 | Serial.begin( 115200 ); 62 | Serial.println("Start"); 63 | Ptp.Setup(); 64 | delay( 200 ); 65 | } 66 | 67 | void loop() 68 | { 69 | Ptp.Task(); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /examples/PTPDevInfo/PTPDevInfo.pde: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //#include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include "devinfoparser.h" 13 | 14 | #define DEV_ADDR 1 15 | 16 | // Canon EOS 400D 17 | #define DATA_IN_EP 1 18 | #define DATA_OUT_EP 2 19 | #define INTERRUPT_EP 3 20 | #define CONFIG_NUM 1 21 | 22 | //Nikon Coolpix L110, P100 23 | //#define DATA_IN_EP 2 24 | //#define DATA_OUT_EP 1 25 | 26 | void setup(); 27 | void loop(); 28 | 29 | class CamStateHandlers : public PTPStateHandlers 30 | { 31 | bool stateConnected; 32 | 33 | public: 34 | CamStateHandlers() : stateConnected(false) {}; 35 | 36 | virtual void OnDeviceDisconnectedState(PTP *ptp); 37 | virtual void OnDeviceInitializedState(PTP *ptp); 38 | } CamStates; 39 | 40 | PTP Ptp(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); 41 | 42 | void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) 43 | { 44 | if (stateConnected) 45 | { 46 | stateConnected = false; 47 | Notify(PSTR("Camera disconnected\r\n")); 48 | } 49 | } 50 | 51 | void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) 52 | { 53 | if (!stateConnected) 54 | { 55 | stateConnected = true; 56 | { 57 | HexDump dmp; 58 | Ptp.GetDeviceInfo(&dmp); 59 | Notify(PSTR("\n")); 60 | } 61 | { 62 | DevInfoParser prs; 63 | Ptp.GetDeviceInfo(&prs); 64 | } 65 | } 66 | } 67 | 68 | void setup() { 69 | Serial.begin( 115200 ); 70 | Serial.println("Start"); 71 | Ptp.Setup(); 72 | delay( 200 ); 73 | } 74 | 75 | void loop() { 76 | Ptp.Task(); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /ptp.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #ifndef __PTP_H__ 18 | #define __PTP_H__ 19 | 20 | #define PTPDEBUG 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "ptpconst.h" 27 | #include "ptpmsgstr.h" 28 | #include "ptpcallback.h" 29 | #include "ptpdebug.h" 30 | 31 | // Buffer size should NEVER be less than USB packet size!!!!!!!!!!!!!!!!!!!!! 32 | #define PTP_MAX_RX_BUFFER_LEN 64 33 | #define PTP_MAX_EV_BUFFER_LEN 8 34 | 35 | typedef void (*PTPMAIN)(); 36 | 37 | // States 38 | #define PTP_STATE_DEVICE_DISCONNECTED 1 39 | #define PTP_STATE_SESSION_NOT_OPENED 2 40 | #define PTP_STATE_SESSION_OPENED 3 41 | #define PTP_STATE_DEVICE_INITIALIZED 4 42 | #define PTP_STATE_DEVICE_NOT_RESPONDING 5 43 | #define PTP_STATE_DEVICE_BUSY 6 44 | 45 | #define FAILED(rc)(rc != PTP_RC_OK) 46 | 47 | class PTP; 48 | 49 | class PTPStateHandlers 50 | { 51 | public: 52 | virtual void OnDeviceDisconnectedState(PTP *ptp); 53 | virtual void OnSessionNotOpenedState(PTP *ptp); 54 | virtual void OnSessionOpenedState(PTP *ptp); 55 | virtual void OnDeviceInitializedState(PTP *ptp); 56 | virtual void OnDeviceNotRespondingState(PTP *ptp); 57 | virtual void OnDeviceBusyState(PTP *ptp); 58 | }; 59 | 60 | class PTP 61 | { 62 | uint8_t theState; 63 | uint8_t busyTime; 64 | uint8_t hangTime; 65 | 66 | protected: 67 | void SetInitialState(); 68 | void Task2(); 69 | 70 | private: 71 | uint8_t devAddress; // Device address 72 | uint8_t epDataIn; // DataIN endpoint number 73 | uint8_t epDataOut; // DataOUT endpoint number 74 | uint8_t epInterrupt; // Interrupt endpoint number 75 | uint8_t numConf; // Number of the configuration 76 | 77 | MAX3421E Max; 78 | USB Usb; 79 | 80 | uint16_t idTransaction; // Transaction ID 81 | uint16_t idSession; // Session ID 82 | 83 | PTPStateHandlers *stateMachine; 84 | 85 | protected: 86 | EP_RECORD epRecord[ 4 ]; 87 | 88 | struct OperFlags 89 | { 90 | uint16_t opParams : 3; // 7 - maximum number of operation parameters 91 | uint16_t rsParams : 3; // 7 - maximum number of response parameters 92 | uint16_t txOperation : 1; // I->R operation if the flag is set 93 | uint16_t dataStage : 1; // operation has data stage if the flag is set 94 | uint16_t typeOfVoid : 2; // 0 - NULL, 1 - PTPReadParser/PTPDataSupplyer, 2 - WRITEPARSER, 3 - buffer pointer 95 | uint16_t dataSize : 6; // size of data buffer (64 bytes maximum) 96 | }; 97 | typedef void (*READPARSER)(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 98 | 99 | void ZerroMemory(uint8_t size, uint8_t *mem) { for (uint8_t i=0; ivalueSize = lenSize; 43 | theParser.Initialize(pBuf); 44 | nStage = 1; 45 | 46 | case 1: 47 | if (!theParser.Parse(pp, pcntdn)) 48 | return false; 49 | 50 | arLen = 0; 51 | arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue)); 52 | arLenCntdn = arLen; 53 | nStage = 2; 54 | 55 | case 2: 56 | pBuf->valueSize = valSize; 57 | theParser.Initialize(pBuf); 58 | nStage = 3; 59 | 60 | case 3: 61 | for (; arLenCntdn; arLenCntdn--) 62 | { 63 | if (!theParser.Parse(pp, pcntdn)) 64 | return false; 65 | 66 | if (pf) 67 | pf(pBuf, (arLen - arLenCntdn), me); 68 | } 69 | 70 | nStage = 0; 71 | } 72 | return true; 73 | } 74 | -------------------------------------------------------------------------------- /ptpcallback.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #ifndef __PTPCALLBACK_H__ 18 | #define __PTPCALLBACK_H__ 19 | 20 | #include 21 | #include 22 | #include "WProgram.h" 23 | 24 | // Base class for incomming data parser 25 | class PTPReadParser 26 | { 27 | public: 28 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) = 0; 29 | }; 30 | 31 | struct MultiValueBuffer 32 | { 33 | uint8_t valueSize; 34 | void *pValue; 35 | }; 36 | 37 | class MultiByteValueParser 38 | { 39 | uint8_t * pBuf; 40 | uint8_t countDown; 41 | uint8_t valueSize; 42 | 43 | public: 44 | MultiByteValueParser() : pBuf(NULL), countDown(0), valueSize(0) {}; 45 | 46 | const uint8_t* GetBuffer() { return pBuf; }; 47 | 48 | void Initialize(MultiValueBuffer * const pbuf) 49 | { 50 | pBuf = (uint8_t*)pbuf->pValue; 51 | countDown = valueSize = pbuf->valueSize; 52 | }; 53 | 54 | bool Parse(uint8_t **pp, uint16_t *pcntdn); 55 | }; 56 | 57 | class ByteSkipper 58 | { 59 | uint8_t *pBuf; 60 | uint8_t nStage; 61 | uint16_t countDown; 62 | 63 | public: 64 | ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) {}; 65 | 66 | void Initialize(MultiValueBuffer *pbuf) 67 | { 68 | pBuf = (uint8_t*)pbuf->pValue; 69 | countDown = 0; 70 | }; 71 | 72 | bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip) 73 | { 74 | switch (nStage) 75 | { 76 | case 0: 77 | countDown = bytes_to_skip; 78 | nStage ++; 79 | case 1: 80 | for (; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--); 81 | 82 | if (!countDown) 83 | nStage = 0; 84 | }; 85 | return (!countDown); 86 | }; 87 | }; 88 | 89 | // Pointer to a callback function triggered for each element of PTP array when used with PTPArrayParser 90 | typedef void (*PTP_ARRAY_EL_FUNC)(const MultiValueBuffer * const p, uint32_t count, const void *me); 91 | 92 | class PTPListParser 93 | { 94 | public: 95 | enum ParseMode { modeArray, modeRange/*, modeEnum*/ }; 96 | 97 | private: 98 | uint8_t nStage; 99 | uint8_t enStage; 100 | 101 | uint32_t arLen; 102 | uint32_t arLenCntdn; 103 | 104 | uint8_t lenSize; // size of the array length field in bytes 105 | uint8_t valSize; // size of the array element in bytes 106 | 107 | MultiValueBuffer *pBuf; 108 | 109 | // The only parser for both size and array element parsing 110 | MultiByteValueParser theParser; 111 | 112 | uint8_t /*ParseMode*/ prsMode; 113 | 114 | public: 115 | PTPListParser() : 116 | pBuf(NULL), 117 | nStage(0), 118 | enStage(0), 119 | arLenCntdn(0), 120 | arLen(0), 121 | lenSize(0), 122 | valSize(0), 123 | prsMode(modeArray) 124 | {}; 125 | 126 | void Initialize(const uint8_t len_size, const uint8_t val_size, MultiValueBuffer * const p, const uint8_t mode = modeArray) 127 | { 128 | pBuf = p; 129 | lenSize = len_size; 130 | valSize = val_size; 131 | prsMode = mode; 132 | 133 | if (prsMode == modeRange) 134 | { 135 | arLenCntdn = arLen = 3; 136 | nStage = 2; 137 | } 138 | else 139 | { 140 | arLenCntdn = arLen = 0; 141 | nStage = 0; 142 | } 143 | enStage = 0; 144 | theParser.Initialize(p); 145 | }; 146 | 147 | bool Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me = NULL); 148 | }; 149 | 150 | 151 | // Base class for outgoing data supplier 152 | class PTPDataSupplier 153 | { 154 | public: 155 | virtual uint32_t GetDataSize() = 0; 156 | virtual void GetData(const uint16_t len, uint8_t *pbuf) = 0; 157 | }; 158 | 159 | #endif // __PTPCALLBACK_H__ 160 | -------------------------------------------------------------------------------- /ptpdebug.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #include "ptpdebug.h" 18 | 19 | void HexDump::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) 20 | { 21 | for (uint16_t j=0; j(byteTotal); 26 | Serial.print(": "); 27 | } 28 | PrintHex(pbuf[j]); 29 | Serial.print(" "); 30 | 31 | if (byteCount == 15) 32 | { 33 | Serial.println(""); 34 | byteCount = 0xFF; 35 | } 36 | } 37 | } 38 | 39 | void EOSEventDump::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) 40 | { 41 | uint8_t *p = (uint8_t*)pbuf; 42 | uint16_t cntdn = (uint16_t)len; 43 | 44 | switch (parseStage) 45 | { 46 | case 0: 47 | // Get PTP data packet size 48 | ptppktSize = *((uint32_t*)p); 49 | 50 | // Return if the packet has only one empty record 51 | if (ptppktSize == 0x14) 52 | return; 53 | 54 | Serial.println("\r\n"); 55 | 56 | for (uint8_t i=0; i<4; i++) 57 | { 58 | PrintHex(((uint8_t*)&ptppktSize)[i]); 59 | Serial.print(" "); 60 | } 61 | 62 | // Skip PTP packet header 63 | p += 12; 64 | cntdn -= 12; 65 | parseStage ++; 66 | case 1: 67 | parseSubstage = 0; 68 | parseStage ++; 69 | case 2: 70 | while (1) 71 | { 72 | switch (parseSubstage) 73 | { 74 | // CR after each event record 75 | case 0: 76 | Serial.println(""); 77 | valueParser.Initialize(&valueBuffer); 78 | parseSubstage ++; 79 | 80 | // Parse record size value 81 | case 1: 82 | //Serial.println("1"); 83 | if (!valueParser.Parse(&p, &cntdn)) 84 | return; 85 | recordSize = (uint32_t)theBuffer; 86 | for (uint8_t i=0; i<4; i++) 87 | { 88 | PrintHex(((uint8_t*)&theBuffer)[i]); 89 | Serial.print(" "); 90 | } 91 | recordSize -= 4; 92 | valueParser.Initialize(&valueBuffer); 93 | parseSubstage ++; 94 | 95 | // Parse the first uint32_t value 96 | case 2: 97 | //Serial.println("2"); 98 | if (!valueParser.Parse(&p, &cntdn)) 99 | return; 100 | 101 | for (uint8_t i=0; i<4; i++) 102 | { 103 | PrintHex(((uint8_t*)&theBuffer)[i]); 104 | Serial.print(" "); 105 | } 106 | recordSize -= 4; 107 | 108 | // Return if empty(last) record 109 | if (recordSize == 0x08 && (uint32_t)theBuffer == 0) 110 | { 111 | parseSubstage = 0; 112 | parseStage = 0; 113 | return; 114 | } 115 | parseSubstage ++; 116 | 117 | // Print the rest of the record 118 | case 3: 119 | //Serial.println("3"); 120 | for (; recordSize && cntdn; recordSize--, cntdn--, p++) 121 | { 122 | PrintHex(*p); 123 | Serial.print(" "); 124 | } 125 | if (!recordSize) 126 | parseSubstage = 0; 127 | if (!cntdn) 128 | return; 129 | 130 | } // switch (parseSubstage) 131 | } // while(1) 132 | } // switch (parseStage) 133 | } 134 | -------------------------------------------------------------------------------- /ptpdebug.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #ifndef __PTPDEBUG_H__ 18 | #define __PTPDEBUG_H__ 19 | 20 | #include 21 | #include 22 | #include "ptpcallback.h" 23 | 24 | void Notify(const char* msg); 25 | void Message(const char* msg, uint16_t rcode); 26 | 27 | template 28 | void PrintHex(T val) 29 | { 30 | T mask = (((T)1) << (((sizeof(T) << 1) - 1) << 2)); 31 | 32 | while (mask > 1) 33 | { 34 | if (val < mask) 35 | Serial.print("0"); 36 | 37 | mask >>= 4; 38 | } 39 | Serial.print((T)val, HEX); 40 | } 41 | 42 | template 43 | void PrintHex2(Print *prn, T val) 44 | { 45 | T mask = (((T)1) << (((sizeof(T) << 1) - 1) << 2)); 46 | 47 | while (mask > 1) 48 | { 49 | if (val < mask) 50 | prn->print("0"); 51 | 52 | mask >>= 4; 53 | } 54 | prn->print((T)val, HEX); 55 | } 56 | 57 | class HexDump : public PTPReadParser 58 | { 59 | uint8_t byteCount; 60 | uint16_t byteTotal; 61 | 62 | public: 63 | HexDump() : byteCount(0), byteTotal(0) {}; 64 | void Initialize() { byteCount = 0; byteTotal = 0; }; 65 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 66 | }; 67 | 68 | #include "ptpcallback.h" 69 | 70 | class EOSEventDump : public PTPReadParser 71 | { 72 | uint32_t ptppktSize; 73 | uint16_t recordSize; 74 | uint8_t parseStage; 75 | uint8_t parseSubstage; 76 | 77 | MultiByteValueParser valueParser; 78 | MultiValueBuffer valueBuffer; 79 | uint32_t theBuffer; 80 | public: 81 | EOSEventDump() : ptppktSize(0), recordSize(0), parseStage(0), parseSubstage(0) 82 | { valueBuffer.valueSize = 4; valueBuffer.pValue = &theBuffer; }; 83 | void Initialize() { ptppktSize = 0; recordSize = 0; parseStage = 0; valueParser.Initialize(&valueBuffer); }; 84 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 85 | }; 86 | #endif // __PTPDEBUG_H__ -------------------------------------------------------------------------------- /ptpdpparser.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #ifndef __PTPDPPARSER_H__ 18 | #define __PTPDPPARSER_H__ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | template 27 | struct PTPDevicePropValue 28 | { 29 | VALUE_TYPE valCurrent; 30 | uint8_t listForm; 31 | VALUE_TYPE arrValues[3]; 32 | 33 | static void SaveEnumValue(MultiValueBuffer *p, uint32_t count, void *me) 34 | { 35 | PTPDevicePropValue *dp = (PTPDevicePropValue*)me; 36 | 37 | if (!dp) 38 | { 39 | PTPTRACE("NULL pointer!!!\r\n"); 40 | return; 41 | } 42 | switch (dp->listForm) 43 | { 44 | case 2: 45 | if (dp->arrValues[1] != dp->valCurrent || (dp->arrValues[1] == dp->valCurrent && dp->arrValues[2] <= dp->valCurrent)) 46 | { 47 | dp->arrValues[0] = dp->arrValues[1]; 48 | dp->arrValues[1] = dp->arrValues[2]; 49 | dp->arrValues[2] = *((VALUE_TYPE*)p->pValue); 50 | } 51 | break; 52 | case 1: 53 | dp->arrValues[count] = *((VALUE_TYPE*)p->pValue); 54 | break; 55 | } 56 | }; 57 | }; 58 | 59 | template 60 | class PTPDevPropParser : public PTPReadParser 61 | { 62 | uint8_t nStage; 63 | uint8_t enStage; 64 | uint8_t formFlag; 65 | MultiValueBuffer theBuffer; 66 | uint8_t varBuffer[sizeof(VALUE_TYPE)]; 67 | uint16_t enLen; 68 | uint16_t enLenCntdn; 69 | 70 | MultiByteValueParser valParser; 71 | PTPDevicePropValue *pDPValue; 72 | 73 | bool ParseValue (uint8_t **pp, uint16_t *pcntdn, VALUE_TYPE&); 74 | bool ParseEnumSingle(uint8_t **pp, uint16_t *pcntdn); 75 | 76 | PTPListParser enumParser; 77 | 78 | uint8_t GetDataSize(); 79 | 80 | public: 81 | PTPDevPropParser(PTPDevicePropValue *p) : 82 | pDPValue(p), 83 | nStage(0), 84 | enStage(0), 85 | formFlag(0), 86 | enLen(0), 87 | enLenCntdn(0) 88 | { 89 | theBuffer.valueSize = sizeof(VALUE_TYPE); 90 | theBuffer.pValue = varBuffer; 91 | } 92 | virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset); 93 | }; 94 | 95 | template 96 | bool PTPDevPropParser::ParseValue(uint8_t **pp, uint16_t *pcntdn, VALUE_TYPE &val) 97 | { 98 | val = *((VALUE_TYPE*)*pp); 99 | (*pp) += sizeof(VALUE_TYPE); 100 | (*pcntdn) -= sizeof(VALUE_TYPE); 101 | return true; 102 | } 103 | 104 | template 105 | bool PTPDevPropParser::ParseEnumSingle(uint8_t **pp, uint16_t *pcntdn) 106 | { 107 | switch(enStage) 108 | { 109 | case 0: 110 | enumParser.Initialize(2, sizeof(VALUE_TYPE), &theBuffer); 111 | enStage ++; 112 | case 1: 113 | if (!enumParser.Parse(pp, pcntdn, (PTP_ARRAY_EL_FUNC)&PTPDevicePropValue::SaveEnumValue, pDPValue)) 114 | return false; 115 | enStage = 0; 116 | } // switch 117 | return true; 118 | } 119 | 120 | template 121 | void PTPDevPropParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset) 122 | { 123 | uint16_t cntdn = (uint16_t)len; 124 | uint8_t *p = (uint8_t*)pbuf; 125 | 126 | VALUE_TYPE vt = 1; 127 | 128 | switch (nStage) 129 | { 130 | case 0: 131 | p += 17; 132 | cntdn -= 17; 133 | nStage = 1; 134 | case 1: 135 | if (!ParseValue(&p, &cntdn, vt)) 136 | return; 137 | nStage = 2; 138 | case 2: 139 | if (!ParseValue(&p, &cntdn, pDPValue->valCurrent)) 140 | return; 141 | nStage = 3; 142 | case 3: 143 | for (uint8_t i=0; i<3; i++) 144 | pDPValue->arrValues[i] = pDPValue->valCurrent; 145 | 146 | formFlag = (*p); 147 | pDPValue->listForm = formFlag; 148 | p ++; 149 | cntdn --; 150 | nStage = 4; 151 | case 4: 152 | if (formFlag == 1) 153 | enumParser.Initialize(2, sizeof(VALUE_TYPE), &theBuffer, PTPListParser::modeRange); 154 | nStage = 5; 155 | case 5: 156 | if (formFlag == 1) 157 | if (!enumParser.Parse(&p, &cntdn, (PTP_ARRAY_EL_FUNC)&PTPDevicePropValue::SaveEnumValue, pDPValue)) 158 | return; 159 | 160 | if (formFlag == 2) 161 | if (!ParseEnumSingle(&p, &cntdn)) 162 | return; 163 | 164 | nStage = 0; 165 | } 166 | } 167 | 168 | template 169 | uint16_t StepUp(PTP *ptp, uint16_t prop) 170 | { 171 | PTPDevicePropValue val; 172 | PTPDevPropParser prs(&val); 173 | 174 | uint16_t ret = ptp->GetDevicePropDesc(prop, &prs); 175 | 176 | if (ret != PTP_RC_OK) 177 | return ret; 178 | 179 | if (val.listForm == 2) 180 | if (val.arrValues[1] == val.valCurrent) 181 | return ptp->SetDevicePropValue(prop, (VALUE_TYPE)val.arrValues[2]); 182 | 183 | if (val.listForm == 1) 184 | if (val.valCurrent + val.arrValues[2] <= val.arrValues[1]) 185 | return ptp->SetDevicePropValue(prop, (VALUE_TYPE)(val.valCurrent + val.arrValues[2])); 186 | 187 | return PTP_RC_OK; 188 | } 189 | 190 | template 191 | uint16_t StepDown(PTP *ptp, uint16_t prop) 192 | { 193 | PTPDevicePropValue val; 194 | PTPDevPropParser prs(&val); 195 | 196 | uint16_t ret = ptp->GetDevicePropDesc(prop, &prs); 197 | 198 | if (ret != PTP_RC_OK) 199 | return ret; 200 | 201 | if (val.listForm == 2) 202 | { 203 | if (val.arrValues[1] == val.valCurrent && val.arrValues[0] < val.arrValues[1]) 204 | return ptp->SetDevicePropValue(prop, (VALUE_TYPE)val.arrValues[0]); 205 | 206 | if (val.arrValues[2] == val.valCurrent) 207 | return ptp->SetDevicePropValue(prop, (VALUE_TYPE)val.arrValues[1]); 208 | } 209 | if (val.listForm == 1) 210 | { 211 | VALUE_TYPE new_val = val.valCurrent - val.arrValues[2]; 212 | if (new_val >= val.arrValues[0] && new_val < val.valCurrent) 213 | return ptp->SetDevicePropValue(prop, (VALUE_TYPE)(val.valCurrent - val.arrValues[2])); 214 | } 215 | return PTP_RC_OK; 216 | } 217 | 218 | template 219 | uint16_t GetValueTitle(PTP *ptp, uint16_t prop, const ValueTitle *p, const char **t) 220 | { 221 | VALUE_TYPE val; 222 | uint16_t ret = ptp->GetDevicePropValue(prop, val); 223 | 224 | if (ret != PTP_RC_OK) 225 | return ret; 226 | 227 | *t = (char*)FindTitle(TABLE_SIZE, p, (LIST_VALUE_TYPE)val); 228 | return ret; 229 | } 230 | 231 | template 232 | uint16_t PrintValueTitle(PTP *ptp, uint16_t prop, const ValueTitle *p ) 233 | { 234 | const char *title; 235 | 236 | if (GetValueTitle(ptp, prop, p, &title) == PTP_RC_OK) 237 | Notify(title); 238 | } 239 | 240 | #endif // __PTPDPPARSER_H__ 241 | -------------------------------------------------------------------------------- /ptpmsgstr.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #ifndef __PTPMSGSTR_H__ 18 | #define __PTPMSGSTR_H__ 19 | 20 | const char MsgErrDeviceConf[] PROGMEM = "Error configuring device. Returned:"; 21 | const char MsgErrProtoConf[] PROGMEM = "Error configuring boot protocol. Returned:"; 22 | const char MsgDeviceInitialized[] PROGMEM = "Device initialized"; 23 | 24 | #ifdef PTP_HANDLE_RESPONSES 25 | //const char msgUndefined[] PROGMEM = "Undefined"; 26 | const char msgOK[] PROGMEM = "OK"; 27 | const char msgGeneralError[] PROGMEM = "GeneralError"; 28 | const char msgSessionNotOpen[] PROGMEM = "SessionNotOpen"; 29 | const char msgInvalidTransactionID[] PROGMEM = "InvalidTransactionID"; 30 | const char msgOperationNotSupported[] PROGMEM = "OperationNotSupported"; 31 | const char msgParameterNotSupported[] PROGMEM = "ParameterNotSupported"; 32 | const char msgIncompleteTransfer[] PROGMEM = "IncompleteTransfer"; 33 | const char msgInvalidStorageId[] PROGMEM = "InvalidStorageId"; 34 | const char msgInvalidObjectHandle[] PROGMEM = "InvalidObjectHandle"; 35 | const char msgDevicePropNotSupported[] PROGMEM = "DevicePropNotSupported"; 36 | const char msgInvalidObjectFormatCode[] PROGMEM = "InvalidObjectFormatCode"; 37 | const char msgStoreFull[] PROGMEM = "StoreFull"; 38 | const char msgObjectWriteProtected[] PROGMEM = "ObjectWriteProtected"; 39 | const char msgStoreReadOnly[] PROGMEM = "StoreReadOnly"; 40 | const char msgAccessDenied[] PROGMEM = "AccessDenied"; 41 | const char msgNoThumbnailPresent[] PROGMEM = "NoThumbnailPresent"; 42 | const char msgSelfTestFailed[] PROGMEM = "SelfTestFailed"; 43 | const char msgPartialDeletion[] PROGMEM = "PartialDeletion"; 44 | const char msgStoreNotAvailable[] PROGMEM = "StoreNotAvailable"; 45 | const char msgSpecificationByFormatUnsupported [] PROGMEM = "SpecificationByFormatUnsupported"; 46 | const char msgNoValidObjectInfo[] PROGMEM = "NoValidObjectInfo"; 47 | const char msgInvalidCodeFormat[] PROGMEM = "InvalidCodeFormat"; 48 | const char msgUnknownVendorCode[] PROGMEM = "UnknownVendorCode"; 49 | const char msgCaptureAlreadyTerminated[] PROGMEM = "CaptureAlreadyTerminated"; 50 | const char msgDeviceBusy[] PROGMEM = "DeviceBusy"; 51 | const char msgInvalidParentObject[] PROGMEM = "InvalidParentObject"; 52 | const char msgInvalidDevicePropFormat[] PROGMEM = "InvalidDevicePropFormat"; 53 | const char msgInvalidDevicePropValue[] PROGMEM = "InvalidDevicePropValue"; 54 | const char msgInvalidParameter[] PROGMEM = "InvalidParameter"; 55 | const char msgSessionAlreadyOpened[] PROGMEM = "SessionAlreadyOpened"; 56 | const char msgTransactionCanceled[] PROGMEM = "TransactionCanceled"; 57 | const char msgSpecificationOfDestinationUnsupported[] PROGMEM = "SpecificationOfDestinationUnsupported"; 58 | #endif 59 | 60 | #if 0 61 | const char msgUndefined[] PROGMEM = "Undefined"; 62 | const char msgBatteryLevel[] PROGMEM = "BatteryLevel"; 63 | const char msgFunctionalMode[] PROGMEM = "FunctionalMode"; 64 | const char msgImageSize[] PROGMEM = "ImageSize"; 65 | const char msgCompressionSetting[] PROGMEM = "CompressionSetting"; 66 | const char msgWhiteBalance[] PROGMEM = "WhiteBalance"; 67 | const char msgRGBGain[] PROGMEM = "RGBGain"; 68 | const char msgFNumber[] PROGMEM = "FNumber"; 69 | const char msgFocalLength[] PROGMEM = "FocalLength"; 70 | const char msgFocusDistance[] PROGMEM = "FocusDistance"; 71 | const char msgFocusMode[] PROGMEM = "FocusMode"; 72 | const char msgExposureMeteringMode[] PROGMEM = "ExposureMeteringMode"; 73 | const char msgFlashMode[] PROGMEM = "FlashMode"; 74 | const char msgExposureTime[] PROGMEM = "ExposureTime"; 75 | const char msgExposureProgramMode[] PROGMEM = "ExposureProgramMode"; 76 | const char msgExposureIndex[] PROGMEM = "ExposureIndex"; 77 | const char msgExposureBiasCompensation[] PROGMEM = "ExposureBiasCompensation"; 78 | const char msgDateTime[] PROGMEM = "DateTime"; 79 | const char msgCaptureDelay[] PROGMEM = "CaptureDelay"; 80 | const char msgStillCaptureMode[] PROGMEM = "StillCaptureMode"; 81 | const char msgContrast[] PROGMEM = "Contrast"; 82 | const char msgSharpness[] PROGMEM = "Sharpness"; 83 | const char msgDigitalZoom[] PROGMEM = "DigitalZoom"; 84 | const char msgEffectMode[] PROGMEM = "EffectMode"; 85 | const char msgBurstNumber[] PROGMEM = "BurstNumber"; 86 | const char msgBurstInterval[] PROGMEM = "BurstInterval"; 87 | const char msgTimelapseNumber[] PROGMEM = "TimelapseNumber"; 88 | const char msgTimelapseInterval[] PROGMEM = "TimelapseInterval"; 89 | const char msgFocusMeteringMode[] PROGMEM = "FocusMeteringMode"; 90 | const char msgUploadURL[] PROGMEM = "UploadURL"; 91 | const char msgArtist[] PROGMEM = "Artist"; 92 | const char msgCopyrightInfo[] PROGMEM = "CopyrightInfo"; 93 | #endif 94 | 95 | #endif //__PTPMSGSTR_H__ -------------------------------------------------------------------------------- /scheduler.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #include "scheduler.h" 18 | 19 | 20 | uint8_t DaysPerMonth(time_t t) 21 | { 22 | uint8_t mon = month(t); 23 | switch (mon) 24 | { 25 | case 4: 26 | case 6: 27 | case 9: 28 | case 11: 29 | return 30; 30 | case 2: 31 | return (IS_LEAP_YEAR(year(t))) ? 29 : 28; 32 | default: 33 | return 31; 34 | } 35 | } 36 | 37 | bool SchedulerTask::Set(TaskCallback pfunc, uint8_t pt, time_t time, uint8_t num) 38 | { 39 | timeToFire = time; 40 | taskAttribs.bmTaskSet = 1; 41 | taskAttribs.bmEnabled = 0; 42 | taskAttribs.bmPeriodType = pt; 43 | pCallback = pfunc; 44 | countDown = num; 45 | return true; 46 | } 47 | 48 | bool SchedulerTask::Run(time_t time) 49 | { 50 | if (!IsSet() || !IsEnabled()) 51 | return true; 52 | 53 | if (time >= timeToFire) 54 | { 55 | pCallback(); 56 | 57 | if (countDown != DO_IT_FOREVER) 58 | countDown --; 59 | 60 | UpdateTime(); 61 | } 62 | return true; 63 | } 64 | 65 | bool SchedulerTask::UpdateTime() 66 | { 67 | if (!countDown) 68 | return true; 69 | switch (taskAttribs.bmPeriodType) 70 | { 71 | case enHourly: 72 | timeToFire += SECS_PER_HOUR; 73 | break; 74 | case enDaily: 75 | timeToFire += SECS_PER_DAY; 76 | break; 77 | case enWeekly: 78 | timeToFire += SECS_PER_WEEK; 79 | break; 80 | case enMonthly: 81 | timeToFire += DaysPerMonth(timeToFire) * SECS_PER_DAY; 82 | break; 83 | case enYearly: 84 | timeToFire += DAYS_PER_YEAR(year(timeToFire)); 85 | break; 86 | } 87 | return true; 88 | } 89 | -------------------------------------------------------------------------------- /scheduler.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #ifndef __SCHEDULER_H__ 18 | #define __SCHEDULER_H__ 19 | 20 | #include 21 | #include 22 | #include <../Time/Time.h> 23 | #include "WProgram.h" 24 | 25 | #define DO_IT_FOREVER 0xFF 26 | #define INVALID_TASK_ID 0xFF 27 | #define IS_LEAP_YEAR(Y) ( ((Y)>0) && !((Y)%4) && ( ((Y)%100) || !((Y)%400) ) ) 28 | #define DAYS_PER_YEAR(Y) ( ((IS_LEAP_YEAR((Y))) ? 366 : 365) ) 29 | 30 | typedef void (*TaskCallback)(); 31 | 32 | uint8_t DaysPerMonth(time_t t); 33 | 34 | class SimpleClock 35 | { 36 | time_t unixTime; 37 | 38 | public: 39 | SimpleClock() : unixTime(0) {}; 40 | SimpleClock(time_t time) : unixTime(time) {}; 41 | bool SetTime(time_t time) { if (!time) return false; unixTime = time; return true; }; 42 | time_t GetTime() { return unixTime; }; 43 | void IncrementTime() { ++unixTime; }; 44 | }; 45 | 46 | class SchedulerTask 47 | { 48 | public: 49 | enum PeriodTypes { enOnce, enHourly, enDaily, enWeekly, enMonthly, enYearly }; 50 | 51 | struct TaskAttributes 52 | { 53 | uint8_t bmAllocated : 1; 54 | uint8_t bmTaskSet : 1; 55 | uint8_t bmEnabled : 1; 56 | uint8_t bmPeriodType : 3; 57 | }; 58 | 59 | TaskAttributes taskAttribs; 60 | 61 | uint8_t countDown; 62 | time_t timeToFire; 63 | TaskCallback pCallback; 64 | 65 | bool IsAllocated() { return (taskAttribs.bmAllocated == 1); }; 66 | bool IsEnabled() { return (taskAttribs.bmEnabled == 1); }; 67 | bool IsSet() { return (taskAttribs.bmTaskSet == 1); }; 68 | 69 | protected: 70 | virtual bool UpdateTime(); // updates time for the next extcution time 71 | 72 | public: 73 | SchedulerTask() : 74 | countDown(0), 75 | timeToFire(0), 76 | pCallback(NULL) 77 | { *((uint8_t*)&taskAttribs) = 0; }; 78 | 79 | void SetAllocated(bool bAllocated) { taskAttribs.bmAllocated = (bAllocated) ? 1 : 0; }; 80 | void SetEnabled(bool bEnabled) { taskAttribs.bmEnabled = (bEnabled) ? 1 : 0; }; 81 | bool Set(TaskCallback pfunc, uint8_t pt, time_t time, uint8_t num = DO_IT_FOREVER); 82 | bool Reset() { timeToFire = 0; *((uint8_t*)&taskAttribs) = 0; pCallback = NULL; countDown = 0; }; 83 | virtual bool Run(time_t time); 84 | }; 85 | 86 | template 87 | class Scheduler : public SimpleClock 88 | { 89 | TASK_TYPE taskList[MAX_TASKS]; 90 | 91 | uint8_t AllocateTask(); 92 | void DeallocateTask(uint8_t task_id); 93 | uint8_t CreateTask(const TaskCallback task, uint8_t type, time_t time, uint8_t num); 94 | 95 | public: 96 | uint8_t DailyTask(TaskCallback task, uint8_t hours = 0, uint8_t mins = 0, uint8_t secs = 0, uint8_t num = DO_IT_FOREVER); 97 | uint8_t WeeklyTask(TaskCallback task, uint8_t dow = 1, uint8_t hours = 0, uint8_t mins = 0, uint8_t secs = 0, uint8_t num = DO_IT_FOREVER); 98 | uint8_t MonthlyTask(TaskCallback task, uint8_t day = 0, uint8_t hours = 0, uint8_t mins = 0, uint8_t secs = 0, uint8_t num = DO_IT_FOREVER); 99 | uint8_t YearlyTask(TaskCallback task, uint8_t mon, uint8_t day = 1, uint8_t hours = 0, uint8_t mins = 0, uint8_t secs = 0, uint8_t num = DO_IT_FOREVER); 100 | void KillTask(uint8_t task_id) { DeallocateTask(task_id); }; 101 | bool Run(); 102 | }; 103 | 104 | template 105 | uint8_t Scheduler::AllocateTask() 106 | { 107 | for (uint8_t i=0; i 117 | void Scheduler::DeallocateTask(uint8_t id) 118 | { 119 | taskList[id].Reset(); 120 | taskList[id].SetAllocated(false); 121 | } 122 | 123 | template 124 | uint8_t Scheduler::CreateTask(const TaskCallback task, uint8_t type, time_t time, uint8_t num) 125 | { 126 | uint8_t id = AllocateTask(); 127 | 128 | if (id == INVALID_TASK_ID) 129 | return INVALID_TASK_ID; 130 | 131 | if (taskList[id].Set(task, type, time, num)) 132 | { 133 | taskList[id].SetEnabled(true); 134 | return id; 135 | } 136 | else 137 | DeallocateTask(id); 138 | 139 | return INVALID_TASK_ID; 140 | } 141 | 142 | template 143 | uint8_t Scheduler::DailyTask(TaskCallback task, uint8_t hours, uint8_t mins, uint8_t secs, uint8_t num) 144 | { 145 | if (hours > 23 || mins > 59 || secs > 59) 146 | return INVALID_TASK_ID; 147 | 148 | time_t time = GetTime(); 149 | 150 | tmElements_t tm; 151 | tm.Hour = hours; 152 | tm.Minute = mins; 153 | tm.Second = secs; 154 | tm.Day = day(time); 155 | tm.Month = month(time); 156 | tm.Year = year(time); 157 | time_t t = makeTime(tm); 158 | 159 | if (t < time) 160 | t += SECS_PER_DAY; 161 | 162 | return CreateTask(task, SchedulerTask::enDaily, t, num); 163 | } 164 | 165 | template 166 | uint8_t Scheduler::WeeklyTask(TaskCallback task, uint8_t dow, uint8_t hours, uint8_t mins, uint8_t secs, uint8_t num) 167 | { 168 | if (hours > 23 || mins > 59 || secs > 59 || dow < 1 || dow > 7) 169 | return INVALID_TASK_ID; 170 | 171 | time_t time = GetTime(); 172 | 173 | tmElements_t tm; 174 | tm.Hour = hours; 175 | tm.Minute = mins; 176 | tm.Second = secs; 177 | tm.Day = day(time); 178 | tm.Month = month(time); 179 | tm.Year = year(time); 180 | time_t t = makeTime(tm); 181 | 182 | uint8_t wd = weekday(time); 183 | uint8_t days_to_add = (wd < dow) ? dow - wd : 7 - wd + dow; 184 | 185 | if (days_to_add) 186 | t += days_to_add * SECS_PER_DAY; 187 | 188 | if (t < time) 189 | t+= SECS_PER_WEEK; 190 | 191 | return CreateTask(task, SchedulerTask::enWeekly, t, num); 192 | } 193 | 194 | template 195 | uint8_t Scheduler::MonthlyTask(TaskCallback task, uint8_t day, uint8_t hours, uint8_t mins, uint8_t secs, uint8_t num) 196 | { 197 | if (hours > 23 || mins > 59 || secs > 59 || day > 31) 198 | return INVALID_TASK_ID; 199 | 200 | time_t time = GetTime(); 201 | 202 | tmElements_t tm; 203 | tm.Hour = hours; 204 | tm.Minute = mins; 205 | tm.Second = secs; 206 | tm.Day = day; 207 | tm.Month = month(time); 208 | tm.Year = year(time); 209 | time_t t = makeTime(tm); 210 | 211 | if (t < time) 212 | t += DaysPerMonth(t) * SECS_PER_DAY; 213 | 214 | return CreateTask((const TaskCallback)task, SchedulerTask::enMonthly, t, (uint8_t)num); 215 | } 216 | 217 | template 218 | uint8_t Scheduler::YearlyTask(TaskCallback task, uint8_t mon, uint8_t day, uint8_t hours, uint8_t mins, uint8_t secs, uint8_t num) 219 | { 220 | if (hours > 23 || mins > 59 || secs > 59 || day > 31 || mon > 12) 221 | return INVALID_TASK_ID; 222 | 223 | time_t time = GetTime(); 224 | uint16_t y = year(time); 225 | 226 | tmElements_t tm; 227 | tm.Hour = hours; 228 | tm.Minute = mins; 229 | tm.Second = secs; 230 | tm.Day = day; 231 | tm.Month = mon; 232 | tm.Year = y; 233 | time_t t = makeTime(tm); 234 | 235 | if (t < time) 236 | t += DAYS_PER_YEAR(y) * SECS_PER_DAY; 237 | 238 | return CreateTask(task, SchedulerTask::enYearly, t, num); 239 | } 240 | 241 | template 242 | bool Scheduler::Run() 243 | { 244 | IncrementTime(); 245 | time_t time = GetTime(); 246 | 247 | for (uint8_t i=0; i 21 | class SimpleFIFO 22 | { 23 | TYPE theBuffer[SIZE]; 24 | uint8_t tail, head; 25 | 26 | private: 27 | void inc(uint8_t &val) 28 | { 29 | val ++; 30 | 31 | if (val >= SIZE) 32 | val = 0; 33 | }; 34 | public: 35 | SimpleFIFO() : 36 | tail(0), 37 | head(0) 38 | { 39 | }; 40 | uint8_t Size() 41 | { 42 | if (tail == head) 43 | return 0; 44 | 45 | if (tail > head) 46 | return (tail - head); 47 | else 48 | return (SIZE - head + tail); 49 | }; 50 | void Empty() 51 | { 52 | tail = head = 0; 53 | }; 54 | void Push(TYPE val) 55 | { 56 | if (Size() >= SIZE-1) 57 | return; 58 | 59 | theBuffer[tail] = val; 60 | inc(tail); 61 | // Serial.print(">"); 62 | // Serial.print(head,DEC); 63 | // Serial.print(":"); 64 | // Serial.print(tail,DEC); 65 | // Serial.print(":"); 66 | // Serial.println(Size(),DEC); 67 | }; 68 | TYPE Pop() 69 | { 70 | if (head == tail) 71 | return (TYPE)0; 72 | 73 | TYPE ret = theBuffer[head]; 74 | inc(head); 75 | // Serial.print("<"); 76 | // Serial.print(head,DEC); 77 | // Serial.print(":"); 78 | // Serial.print(tail,DEC); 79 | // Serial.print(":"); 80 | // Serial.println(Size(),DEC); 81 | return ret; 82 | }; 83 | }; 84 | 85 | 86 | #endif // __SIMPLEFIFO_H__ -------------------------------------------------------------------------------- /simpletimer.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #include "simpletimer.h" 18 | 19 | bool SimpleTimer::Set(TimerCallback task, uint32_t timeout, bool once) 20 | { 21 | if (!task) 22 | return false; 23 | 24 | timeOut = timeout; 25 | pCallback = task; 26 | timerAttribs.bmOneTime = (once) ? 1 : 0; 27 | timerAttribs.bmTimerSet = 1; 28 | timerAttribs.bmEnabled = 0; 29 | return true; 30 | } 31 | 32 | void SimpleTimer::Reset() 33 | { 34 | timerAttribs.bmTimerSet = 0; 35 | timerAttribs.bmEnabled = 0; 36 | timerAttribs.bmOneTime = 0; 37 | timerAttribs.bmSign = 0; 38 | 39 | pCallback = NULL; 40 | } 41 | 42 | bool SimpleTimer::Enable() 43 | { 44 | if (!pCallback || !timeOut) 45 | return false; 46 | 47 | uint32_t time = millis(); 48 | 49 | timeToFire = time + timeOut; 50 | 51 | timerAttribs.bmEnabled = 1; 52 | timerAttribs.bmSign = time & MSB_MASK; 53 | return true; 54 | } 55 | 56 | void SimpleTimer::Disable() 57 | { 58 | timerAttribs.bmEnabled = 0; 59 | } 60 | 61 | void SimpleTimer::Run() 62 | { 63 | if (timerAttribs.bmEnabled == 0) 64 | return; 65 | 66 | if (TimeoutEllapsed()) 67 | { 68 | if (pCallback) 69 | pCallback(); 70 | 71 | if (timerAttribs.bmOneTime == 1) 72 | timerAttribs.bmEnabled = 0; 73 | } 74 | } 75 | 76 | bool SimpleTimer::TimeoutEllapsed() 77 | { 78 | bool ret = false; 79 | uint32_t time = millis(); 80 | 81 | if (time >= timeToFire || (time < timeToFire && timerAttribs.bmSign == 1) ) 82 | { 83 | timeToFire = time + timeOut; 84 | ret = true; 85 | } 86 | timerAttribs.bmSign = (time & MSB_MASK) ? 1 : 0; 87 | return ret; 88 | } 89 | -------------------------------------------------------------------------------- /simpletimer.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. 2 | 3 | This software may be distributed and modified under the terms of the GNU 4 | General Public License version 2 (GPL2) as published by the Free Software 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of 6 | this file. Please note that GPL2 Section 2[b] requires that all works based 7 | on this software must also be made publicly available under the terms of 8 | the GPL2 ("Copyleft"). 9 | 10 | Contact information 11 | ------------------- 12 | 13 | Circuits At Home, LTD 14 | Web : http://www.circuitsathome.com 15 | e-mail : support@circuitsathome.com 16 | */ 17 | #ifndef __SIMPLETIMER_H__ 18 | #define __SIMPLETIMER_H__ 19 | 20 | #include 21 | #include 22 | #include "WProgram.h" 23 | 24 | #define MSB_MASK 0x80000000 25 | 26 | typedef void (*TimerCallback)(); 27 | 28 | class SimpleTimer 29 | { 30 | struct TimerAttributes 31 | { 32 | uint8_t bmAllocated : 1; // 1 if allocated for some routine 33 | uint8_t bmTimerSet : 1; // 1 if all data for the timer is set 34 | uint8_t bmEnabled : 1; // 1 if enabled and running 35 | uint8_t bmOneTime : 1; // 1 if the task should be executed onece 36 | uint8_t bmSign : 1; // necessary to handle millis() rollovers 37 | }; 38 | 39 | TimerAttributes timerAttribs; 40 | uint32_t timeOut; 41 | uint32_t timeToFire; 42 | TimerCallback pCallback; 43 | 44 | bool TimeoutEllapsed(); 45 | 46 | public: 47 | SimpleTimer() : timeOut(0), timeToFire(0), pCallback(NULL) { *((uint8_t*)&timerAttribs) = 0; }; 48 | 49 | void SetAllocated(bool yes) { timerAttribs.bmAllocated = (yes) ? 1 : 0; }; 50 | bool IsAllocated() { return timerAttribs.bmAllocated == 1; }; 51 | bool IsEnabled() { return timerAttribs.bmEnabled == 1; }; 52 | 53 | bool Set(TimerCallback task, uint32_t timeout, bool once = false); 54 | void Reset(); 55 | bool Enable(); 56 | void Disable(); 57 | void Run(); 58 | 59 | uint32_t TimeLeft() 60 | { 61 | if (timerAttribs.bmEnabled != 1) 62 | return 0; 63 | 64 | int32_t time_left = timeToFire - millis(); 65 | return (time_left > 0) ? time_left : 0; 66 | }; 67 | }; 68 | 69 | #define INVALID_TIMER_ID 0 70 | 71 | template 72 | class TimerPool 73 | { 74 | TIMER_TYPE thePool[POOL_SIZE]; 75 | 76 | public: 77 | TimerPool() {}; 78 | 79 | uint8_t SetTimer(TimerCallback pfunc, uint32_t msec, bool once); 80 | bool EnableTimer(uint8_t timer_id) { if (!timer_id) return false; thePool[timer_id-1].Enable(); return true; }; 81 | bool DisableTimer(uint8_t timer_id) { if (!timer_id) return false; thePool[timer_id-1].Disable(); return true; }; 82 | bool ReleaseTimer(uint8_t &timer_id){ if (!timer_id) return false; thePool[timer_id-1].SetAllocated(false); thePool[timer_id-1].Reset(); timer_id = 0; return true; }; 83 | void Run(); 84 | }; 85 | 86 | template 87 | uint8_t TimerPool::SetTimer(TimerCallback pfunc, uint32_t msec, bool once) 88 | { 89 | for (uint8_t i=0; i 102 | void TimerPool::Run() 103 | { 104 | for (uint8_t i=0; i 21 | #include "WProgram.h" 22 | 23 | 24 | template 25 | struct ValueTitle 26 | { 27 | ValueType value; 28 | const char title[TitleSize]; 29 | }; 30 | 31 | template 32 | class ValueList 33 | { 34 | public: 35 | uint16_t listSize; 36 | ValueType valueList[ListSize]; 37 | ValueType currentValue; 38 | 39 | ValueType GetNext() 40 | { 41 | for (uint16_t i=0; i= 0) ? valueList[i-1] : currentValue); 53 | 54 | return currentValue; 55 | }; 56 | }; 57 | 58 | 59 | 60 | template 61 | const char* FindTitle(uint8_t size, const ValueTitle *p, ValueType val) 62 | { 63 | for (int i=0; i tail) ? tail : addr)); 143 | }; 144 | 145 | uint8_t GetPrev(uint8_t val, uint8_t di=1) 146 | { 147 | uint16_t addr = GetValueAddress(val); 148 | 149 | if (addr == 0xffff) 150 | return eeprom_read_byte((uint8_t*)(listOffset+1)); 151 | 152 | addr -= di; 153 | 154 | return eeprom_read_byte((uint8_t*)((addr <= listOffset) ? listOffset+1 : addr)); 155 | }; 156 | }; 157 | 158 | 159 | 160 | template 161 | class SRAMValueList 162 | { 163 | VALUE_TYPE theList[MAX_LIST_SIZE]; 164 | uint16_t listSize; 165 | 166 | uint16_t GetValueAddress(VALUE_TYPE val) 167 | { 168 | for (uint16_t i=0; i