StillImageHost Controlling camera by USART. trying to understand PIMA etc

85 views
Skip to first unread message

Tim Pope

unread,
Feb 6, 2012, 4:44:20 PM2/6/12
to lufa-s...@googlegroups.com

Hi Guys,

First AVR project (and generally not used to working at such a low level) with a simple premise for a project, but a challenging one for a newbie to implement:

Control the functionality of my Canon EOS T1i with my usbkey based on commands sent to avr via uart.

I've got my serial comms working nicely with interrupts and ring buffer and I have implemented a command parser that is working rather well… Now I just have the more complex part of comms with the camera to deal with.

I've done some general reading around PIMA and found some useful references at http://www.circuitsathome.com/canon-eos-cameras-principles-of-interfacing-and-library-description (the guy implemented EOS control for arduino with usb host shield)

I started with the classdriver stillimagehost demo as my start point and (a big) if i've understood the program flow correctly then the attached flowchart is roughly what i need to implement.


So my questions:

1. does all the above make sense, does the flow work in terms of how LUFA and PTP work?

2. Skimming the PIMA documentation (http://www.broomscloset.com/closet/photo/exif/PIMA15740-2000.PDF) I note on page 40 that the response consists of a uint16 response code followed by uint32 sessionID, transactionID and 5 optional parameters. the lufa supplied SI_Host_ReceiveResponse only returns a uint8 and so does not have the ability to look at the full response… so I'm guessing to retrieve this would I use SI_Host_ReceiveBlockHeader in place of receive response thus leaving me with a PIMA_Container struct with the data i may need (subnote I notice the PIMA_Container struct only has 3 params but the spec says 5 are possible?)?

3. PIMA events are handled by checking SI_Host_IsEventReceived and if the result is true then we use SI_Host_ReceiveEventHeader to get the data. Reading http://www.circuitsathome.com/canon-eos-cameras-principles-of-interfacing-and-library-description it seems to suggest EOS cameras don't use the typical PIMA event mechanism for all events - Can anyone confirm this? 

Looking at the deviceInfo for the camera (http://www.circuitsathome.com/ptpusb-control-camera-data#EOS500D) operation 9116 is EOS_GetEvent. the first link seems to suggest there can be quite a bit of data returned for one of these events (more than just what would fit in a response) - does that mean I need to read additional data with something like SI_Host_ReadData and if so how do I know the number of bytes to read?

If someone has some experience in this area and can make sense of my tired ramblings I'd very much appreciate any direction you have to offer

Regards

Tim

Dean Camera

unread,
Feb 12, 2012, 10:27:32 AM2/12/12
to LUFA Library Support List
Tim,

There's a great Norwegian student project that is located here:

http://hekta.org/~hpe1119/

Which uses LUFA to control an attached Nikon camera using PIMA - but
unfortunately at least at the moment the site it is hosted on appears
to be down. Still, try it from your end and perhaps you will be able
to access it.

> 1. does all the above make sense, does the flow work in terms of how LUFA
> and PTP work?

Yes, that looks to be the correct sequence for sending/processing data
over the Still Image device class.

> 2. Skimming the PIMA documentation (http://www.broomscloset.com/closet/photo/exif/PIMA15740-2000.PDF) I note on
> page 40 that the response consists of a uint16 response code followed by
> uint32 sessionID, transactionID and 5 optional parameters. the lufa
> supplied SI_Host_ReceiveResponse only returns a uint8 and so does not have
> the ability to look at the full response… so I'm guessing to retrieve this
> would I use SI_Host_ReceiveBlockHeader in place of receive response thus
> leaving me with a PIMA_Container struct with the data i may need (subnote I
> notice the PIMA_Container struct only has 3 params but the spec says 5 are
> possible?)?

I believe that may actually be an oversight on my behalf - the
response PIMA block should be user-accessable to pull out the
parameters as you say. I'll double check the specifications and update
the code if this is incorrect. As for the parameters, IIRC this is
limited to 3 for USB connected PIMA devices, and not the usual 5.

> 3. PIMA events are handled by checking SI_Host_IsEventReceived and if the
> result is true then we use SI_Host_ReceiveEventHeader to get the data.
> Readinghttp://www.circuitsathome.com/canon-eos-cameras-principles-of-interfa...seems to suggest EOS cameras don't use the typical PIMA event mechanism
> for all events - Can anyone confirm this?

Haven't a clue here.

> Looking at the deviceInfo for the camera (http://www.circuitsathome.com/ptpusb-control-camera-data#EOS500D) operation
> 9116 is EOS_GetEvent. the first link seems to suggest there can be quite a
> bit of data returned for one of these events (more than just what would fit
> in a response) - does that mean I need to read additional data with
> something like SI_Host_ReadData and if so how do I know the number of bytes
> to read?

Yes - you send the command header with SI_Host_SendCommand(), then
transfer any data associated with the command via SI_Host_SendData().
Finally, clean up with SI_Host_ReceiveResponse(). Again, I'll have to
double check the specs again as it's not one of the classes I've used
myself much, and I just assumed from the lack of complaints that my
implementation was adequate.

Cheers!
- Dean

On Feb 6, 10:44 pm, Tim Pope <timpope.program...@gmail.com> wrote:
> Hi Guys,
>
> First AVR project (and generally not used to working at such a low level)
> with a simple premise for a project, but a challenging one for a newbie to
> implement:
>
> Control the functionality of my Canon EOS T1i with my usbkey based on
> commands sent to avr via uart.
>
> I've got my serial comms working nicely with interrupts and ring buffer and
> I have implemented a command parser that is working rather well… Now I just
> have the more complex part of comms with the camera to deal with.
>
> I've done some general reading around PIMA and found some useful references
> athttp://www.circuitsathome.com/canon-eos-cameras-principles-of-interfa...(the
> guy implemented EOS control for arduino with usb host shield)
>
> I started with the classdriver stillimagehost demo as my start point and (a
> big) if i've understood the program flow correctly then the attached
> flowchart is roughly what i need to implement.
>
> <https://lh4.googleusercontent.com/-3jW-waFiSq4/TzBJHgOtSFI/AAAAAAAAAH...>
>
> So my questions:
>
> 1. does all the above make sense, does the flow work in terms of how LUFA
> and PTP work?
>
> 2. Skimming the PIMA documentation (http://www.broomscloset.com/closet/photo/exif/PIMA15740-2000.PDF) I note on
> page 40 that the response consists of a uint16 response code followed by
> uint32 sessionID, transactionID and 5 optional parameters. the lufa
> supplied SI_Host_ReceiveResponse only returns a uint8 and so does not have
> the ability to look at the full response… so I'm guessing to retrieve this
> would I use SI_Host_ReceiveBlockHeader in place of receive response thus
> leaving me with a PIMA_Container struct with the data i may need (subnote I
> notice the PIMA_Container struct only has 3 params but the spec says 5 are
> possible?)?
>
> 3. PIMA events are handled by checking SI_Host_IsEventReceived and if the
> result is true then we use SI_Host_ReceiveEventHeader to get the data.
> Readinghttp://www.circuitsathome.com/canon-eos-cameras-principles-of-interfa...seems to suggest EOS cameras don't use the typical PIMA event mechanism

Dean Camera

unread,
Apr 15, 2012, 9:08:25 AM4/15/12
to lufa-s...@googlegroups.com
Hi Tim,

Just got a small amount of time to look into this again some more. I found an old thread which shows the logic behind the current API I "designed" for the Still Image Host class driver:

https://groups.google.com/group/lufa-support/browse_thread/thread/a0da7aa36d6163a5/c56ecc669b97d4b4?lnk=gst&q=PIMA_COMMAND_SIZE#c56ecc669b97d4b4

So it would seem the three use-cases for controlling a Still Image Class compliant device would be:


PIMA Command (No Data):
  1. Call SI_Host_SendCommand()
  2. Call SI_Host_ReceiveResponse(), which will indicate either no error (PIPE_RWSTREAM_NoError), command failed (SI_ERROR_LOGICAL_CMD_FAILED) or no response received yet (PIPE_RWSTREAM_DeviceDisconnected).
PIMA Command (Data from LUFA->Camera):
  1. Call SI_Host_SendCommand()
  2. Call SI_Host_SendBlockHeader() with the data PIMA block header
  3. Call SI_Host_SendData() with the buffer of data to send to the device
  4. Call SI_Host_ReceiveResponse(), which will indicate either no error (PIPE_RWSTREAM_NoError), command failed (SI_ERROR_LOGICAL_CMD_FAILED) or no response received yet (PIPE_RWSTREAM_DeviceDisconnected).

PIMA Command (Data from Camera->LUFA):
  1. Call SI_Host_SendCommand()
  2. Call SI_Host_SendBlockHeader() with the data PIMA block header
  3. Call SI_Host_ReceiveData() with the buffer for data received from the device
  4. Call SI_Host_ReceiveResponse(), which will indicate either no error (PIPE_RWSTREAM_NoError), command failed (SI_ERROR_LOGICAL_CMD_FAILED) or no response received yet (PIPE_RWSTREAM_DeviceDisconnected).

A data PIMA block header would look something like this:

PIMA_Container_t PIMABlock = (PIMA_Container_t)
{
.DataLength = CPU_TO_LE32(PIMA_DATA_SIZE(Data_Length)),
.Type = CPU_TO_LE16(PIMA_CONTAINER_DataBlock),
.Code = CPU_TO_LE16(PIMA_Parameter_Code),
.Params = {CPU_TO_LE32(PIMA_Parameter1)},
};

Substituting in values for Data_Length, PIMA_Parameter_Code and PIMA_Parameter1.


Cheers!
- Dean
Reply all
Reply to author
Forward
0 new messages