Serial Communication

Serial Communication —

Synopsis


#include <serial.h>


int         canon_serial_change_speed       (GPPort *gdev,
                                             int speed);
unsigned char* canon_serial_dialogue        (Camera *camera,
                                             GPContext *context,
                                             unsigned char mtype,
                                             unsigned char dir,
                                             int *len,
                                             ...);
void        canon_serial_error_type         (Camera *camera);
int         canon_serial_get_byte           (GPPort *gdev);
int         canon_serial_get_cts            (GPPort *gdev);
int         canon_serial_get_dirents        (Camera *camera,
                                             unsigned char **dirent_data,
                                             unsigned int *dirents_length,
                                             const char *path,
                                             GPContext *context);
unsigned char* canon_serial_get_file        (Camera *camera,
                                             const char *name,
                                             int *length,
                                             GPContext *context);
int         canon_serial_get_thumbnail      (Camera *camera,
                                             const char *name,
                                             unsigned char **data,
                                             int *length,
                                             GPContext *context);
int         canon_serial_init               (Camera *camera);
int         canon_serial_put_file           (Camera *camera,
                                             CameraFile *file,
                                             char *destname,
                                             char *destpath,
                                             GPContext *context);
int         canon_serial_ready              (Camera *camera,
                                             GPContext *context);
unsigned char* canon_serial_recv_frame      (Camera *camera,
                                             int *len);
unsigned char* canon_serial_recv_msg        (Camera *camera,
                                             unsigned char mtype,
                                             unsigned char dir,
                                             int *total,
                                             GPContext *context);
unsigned char* canon_serial_recv_packet     (Camera *camera,
                                             unsigned char *type,
                                             unsigned char *seq,
                                             int *len);
int         canon_serial_send               (Camera *camera,
                                             unsigned char *buf,
                                             int len,
                                             int sleep);
int         canon_serial_send_frame         (Camera *camera,
                                             unsigned char *pkt,
                                             int len);
int         canon_serial_send_packet        (Camera *camera,
                                             unsigned char type,
                                             unsigned char seq,
                                             unsigned char *pkt,
                                             int len);
int         canon_serial_wait_for_ack       (Camera *camera);
int         canon_psa50_chk_crc             (unsigned char *pkt,
                                             int len,
                                             unsigned short crc);
unsigned short canon_psa50_gen_crc          (unsigned char *pkt,
                                             int len);
void        serial_flush_input              (GPPort *gdev);
void        serial_flush_output             (GPPort *gdev);
void        serial_set_timeout              (GPPort *gdev,
                                             int to);
#define     MAX_TRIES
#define     USLEEP1
#define     USLEEP2
#define     HDR_FIXED_LEN
#define     DATA_BLOCK

enum        canonSerialErrorCode;

enum        canonSerialFramingByte;

enum        canonPacketThirdByte;
enum        canonPacketType;
enum        canonPacketOffset;
#define     MAX_PKT_PAYLOAD

enum        canonSerialMsgHeader;
#define     MAX_MSG_SIZE
#define     DIR_REVERSE
#define     UPLOAD_DATA_BLOCK

#define     SPEED_9600
#define     SPEED_19200
#define     SPEED_38400
#define     SPEED_57600
#define     SPEED_115200

Description

Details

canon_serial_change_speed ()

int         canon_serial_change_speed       (GPPort *gdev,
                                             int speed);

Changes the speed of the communication.

gdev : serial port to use
speed : the new speed
Returns : 1 on success. 0 on any error.

canon_serial_dialogue ()

unsigned char* canon_serial_dialogue        (Camera *camera,
                                             GPContext *context,
                                             unsigned char mtype,
                                             unsigned char dir,
                                             int *len,
                                             ...);

Higher level function: sends a message and waits for a reply from the camera.

Payload: each argument after "len" goes by 2: the variable itself, and the next argument has to be its length. You also have to finish the list by a "NULL".

Example: To send a string called "name" : canon_serial_dialogue(0x05,0x12,&len,name,strlen(name)+1,NULL);

camera : camera with which to communicate
context : context for error reporting
mtype : type
dir : direction
len : length of the received payload
... : The rest of the arguments will be put together to fill up the payload of the request message.
Returns : buffer received from canon_serial_recv_msg(), NULL if failure

canon_serial_error_type ()

void        canon_serial_error_type         (Camera *camera);

logs a debug message corresponding to the error encountered

camera : Camera object to work with

canon_serial_get_byte ()

int         canon_serial_get_byte           (GPPort *gdev);

Gets the next byte from the serial line. Actually the function reads chunks of data and keeps them in a cache. Only one byte per call will be returned.

gdev : serial port to use
Returns : the byte on success, -1 on error.

canon_serial_get_cts ()

int         canon_serial_get_cts            (GPPort *gdev);

Gets the status of the CTS (Clear To Send) line on the serial port.

CTS is "1" when the camera is ON, and "0" when it is OFF.

gdev : serial port to use
Returns : 1 on CTS high. 0 on CTS low.

canon_serial_get_dirents ()

int         canon_serial_get_dirents        (Camera *camera,
                                             unsigned char **dirent_data,
                                             unsigned int *dirents_length,
                                             const char *path,
                                             GPContext *context);

Lists a directory.

camera : camera to initialize
dirent_data : to receive directory data
dirents_length : to receive length of dirent_data
path : pathname of directory to list
context : context for error reporting
Returns : gphoto2 error code

canon_serial_get_file ()

unsigned char* canon_serial_get_file        (Camera *camera,
                                             const char *name,
                                             int *length,
                                             GPContext *context);

Get a file from a USB_connected Canon camera.

camera : camera to lock keys on
name : name of file to fetch
length : to receive length of image data
context : context for error reporting
Returns : buffer containing file data (or NULL on failure); length in length.

canon_serial_get_thumbnail ()

int         canon_serial_get_thumbnail      (Camera *camera,
                                             const char *name,
                                             unsigned char **data,
                                             int *length,
                                             GPContext *context);

This is just the serial specific part extracted from the older canon_get_thumbnail() routine.

camera : camera to work on
name : file name (complete canon path) of file to get thumbnail for
data : pointer to data pointer
length : pointer to data length
context : context for error reporting
Returns : gphoto2 error code

canon_serial_init ()

int         canon_serial_init               (Camera *camera);

Initializes the given serial device by setting speed, parity, etc.

camera : Camera object to initialize
Returns : GP_OK

canon_serial_put_file ()

int         canon_serial_put_file           (Camera *camera,
                                             CameraFile *file,
                                             char *destname,
                                             char *destpath,
                                             GPContext *context);

Uploads file to camera via serial port

camera : Camera object to work with
file : CameraFile object to upload
destname : name file should have on camera
destpath : pathname for directory to put file
context : context for error reporting
Returns : gphoto2 error code

canon_serial_ready ()

int         canon_serial_ready              (Camera *camera,
                                             GPContext *context);

serial part of canon_int_ready

camera : camera to get ready
context : context for error reporting
Returns : gphoto2 error code

canon_serial_recv_frame ()

unsigned char* canon_serial_recv_frame      (Camera *camera,
                                             int *len);

Receive a frame from the camera

camera : Camera object to work with
len : to receive the length of the buffer
Returns : a buffer containing a frame from the camera, or NULL on error. On success, len will contain the length of the buffer.

canon_serial_recv_msg ()

unsigned char* canon_serial_recv_msg        (Camera *camera,
                                             unsigned char mtype,
                                             unsigned char dir,
                                             int *total,
                                             GPContext *context);

Receives a message from the camera.

See the "Protocol" file for an explanation of the various elements needed to handle a message.

camera : Camera object to work with
mtype : message type.
dir : direction.
total : payload length (set by this function).
context : context for error reporting
Returns : char* pointer to the message payload; NULL on failure.

canon_serial_recv_packet ()

unsigned char* canon_serial_recv_packet     (Camera *camera,
                                             unsigned char *type,
                                             unsigned char *seq,
                                             int *len);

Receives a packet from the serial port using canon_serial_send_frame(), decodes frame information (type, sequence number, and length), and returns it stripped of frame information.

camera : Camera object to work with
type : Type of packet
seq : Sequence number of packet
len : length of data received
Returns : packet data (or NULL if failure). Type in type, sequence number in seq, and length in len.

canon_serial_send ()

int         canon_serial_send               (Camera *camera,
                                             unsigned char *buf,
                                             int len,
                                             int sleep);

Send the given buffer with given length over the serial line.

camera : Camera object to work with
buf : the raw data buffer to send
len : the length of the buffer
sleep : time in usec to wait between characters
Returns : 0 on success, -1 on error.

canon_serial_send_frame ()

int         canon_serial_send_frame         (Camera *camera,
                                             unsigned char *pkt,
                                             int len);

Sends a frame of data to camera

camera : Camera object to work with
pkt : Data to send to camera
len : Length of packet
Returns : 1 if canon_serial_send() succeeds, 0 if it fails

canon_serial_send_packet ()

int         canon_serial_send_packet        (Camera *camera,
                                             unsigned char type,
                                             unsigned char seq,
                                             unsigned char *pkt,
                                             int len);

frames a packet (generates CRC, packs with sequence number and length) and sends it to the camera through the serial port using canon_serial_send_frame().

camera : Camera object to work with
type :
seq :
pkt : data to send to camera
len : length of data
Returns : status from canon_serial_send_frame()

canon_serial_wait_for_ack ()

int         canon_serial_wait_for_ack       (Camera *camera);

Waits for an "ACK" from the camera.

camera : Camera object to work with
Returns : 1 : ACK received 0 : communication error (no reply received for example) -1 : NACK received.

canon_psa50_chk_crc ()

int         canon_psa50_chk_crc             (unsigned char *pkt,
                                             int len,
                                             unsigned short crc);

Calculate a new checksum for the packet and compare it with an existing checksum to detect transmission errors.

pkt : packet
len : length of pkt
Param3 :
Returns : 1 on success or if checksum calculation would fail 0 if checksums don't match

canon_psa50_gen_crc ()

unsigned short canon_psa50_gen_crc          (unsigned char *pkt,
                                             int len);

Calculate a CRC on a Canon packet

pkt : packet data on which to calculate checksum
len : length of pkt
Returns : CRC value. On error doesn't return at all but exits program with a message to stderr.

serial_flush_input ()

void        serial_flush_input              (GPPort *gdev);

Dummy function.

gdev : serial port to use

serial_flush_output ()

void        serial_flush_output             (GPPort *gdev);

Dummy function.

gdev : serial port to use

serial_set_timeout ()

void        serial_set_timeout              (GPPort *gdev,
                                             int to);

Sets the timeout, in miliseconds.

gdev : serial port to use
to : timeout in milliseconds

MAX_TRIES

#define MAX_TRIES 10

Maximum number of retries for a serial send operation.


USLEEP1

#define USLEEP1 0

Number of microseconds to wait between characters when trying to contact the camera by sending "U" characters. Currently zero (i.e. no pause between characters).


USLEEP2

#define USLEEP2 1

Number of microseconds to wait between characters under all other circumstances. Currently 1.


HDR_FIXED_LEN

#define HDR_FIXED_LEN 30

Length of fixed part of header for uploading a file.


DATA_BLOCK

#define DATA_BLOCK 1536

Maximum length of a data block to upload through the serial port.


enum canonSerialErrorCode

typedef enum {
	NOERROR		= 0,
	ERROR_RECEIVED	= 1,
	ERROR_ADDRESSED	= 2,
	FATAL_ERROR	= 3,
	ERROR_LOWBATT   = 4
} canonSerialErrorCode;

Used within serial code to signal various error conditions.

NOERROR No error
ERROR_RECEIVED Packet length doesn't match received packet
ERROR_ADDRESSED Problem receiving EOT
FATAL_ERROR Fatal error
ERROR_LOWBATT Battery is low

enum canonSerialFramingByte

typedef enum {
	CANON_FBEG    = 0xc0,		     /* Beginning of frame */
	CANON_FEND    = 0xc1,		     /* End of frame */
	CANON_ESC     = 0x7e,		     /* XOR next byte with 0x20 */
	CANON_XOR     = 0x20
} canonSerialFramingByte;

Enumeration of all "special" byte codes on the frame level.

CANON_FBEG Beginning of frame
CANON_FEND End of frame
CANON_ESC XOR next byte with 0x20
CANON_XOR value to use with CANON_ESC

enum canonPacketThirdByte

typedef enum {
	PKTACK_NACK    = 0x01,
	PKT_UPLOAD_EOT = 3,
	PKT_NACK       = 255
} canonPacketThirdByte;

Codes to go in the third byte of an ACK or EOT message. Unfortunately, these are mixed with canonPacketType codes to tell canon_serial_send_packet what to do.

PKTACK_NACK This ACK is a NACK (not acknowledged) message
PKT_UPLOAD_EOT This EOT is to end an upload
PKT_NACK this ACK is a request to retransmit

enum canonPacketType

typedef enum {
	PKT_MSG       = 0,
	PKT_SPD       = 3,
	PKT_EOT       = 4,
	PKT_ACK       = 5
} canonPacketType;

Packet type for byte 2 of packet header. Unfortunately, these are mixed with canonPacketThirdByte codes to tell canon_serial_send_packet what to do.

PKT_MSG Message fragment
PKT_SPD Speed message from computer sent once, early in the initialization for the computer to ask the camera to switch to a higher speed.
PKT_EOT EOT
PKT_ACK ACK (or NAK)

enum canonPacketOffset

typedef enum {
	PKT_SEQ       = 0,
	PKT_TYPE      = 1,
	PKT_LEN_LSB   = 2,
	PKT_LEN_MSB   = 3,
	PKT_HDR_LEN   = 4
} canonPacketOffset;

Offsets to bytes in a serial packet header.

PKT_SEQ Offset in packet to message sequence number
PKT_TYPE Offset in packet to type code
PKT_LEN_LSB Offset in packet to least-significant byte of packet length.
PKT_LEN_MSB Offset in packet to most-significant byte of packet length.
PKT_HDR_LEN Length of complete header.

MAX_PKT_PAYLOAD

#define MAX_PKT_PAYLOAD 65535

Maximum size of a packet payload; used to allocate buffers.


enum canonSerialMsgHeader

typedef enum {
	MSG_02        = 0,
	MSG_MTYPE     = 4,
	MSG_DIR       = 7,
	MSG_LEN_LSB   = 8,
	MSG_LEN_MSB   = 9,
/*	MSG_FFFB      = 12,*/
	MSG_HDR_LEN   = 16
} canonSerialMsgHeader;

MSG_02 offset to bytes "00 02" in header
MSG_MTYPE offset to message type byte in header
MSG_DIR offset to message direction byte in header: 0x11 or 0x12 is output to camera, 0x21 or 0x22 is response from camera
MSG_LEN_LSB offset to least-significant byte of 16-but message length
MSG_LEN_MSB offset to most-significant byte of 16-but message length
MSG_HDR_LEN length of entire message header

MAX_MSG_SIZE

#define MAX_MSG_SIZE    (MAX_PKT_PAYLOAD-12)

Maximum size of a message to fit within a packet.


DIR_REVERSE

#define DIR_REVERSE     0x30

Value to XOR with direction byte to reverse direction. Converts 0x21 -> 0x11, 0x11 -> 0x21.


UPLOAD_DATA_BLOCK

#define UPLOAD_DATA_BLOCK 900

Size of blocks to upload a file.


SPEED_9600

#define SPEED_9600   "\x00\x03\x02\x02\x01\x10\x00\x00\x00\x00\xc0\x39"

String to send to set camera speed to 9600 bits per second.


SPEED_19200

#define SPEED_19200  "\x00\x03\x08\x02\x01\x10\x00\x00\x00\x00\x13\x1f"

String to send to set camera speed to 19200 bits per second.


SPEED_38400

#define SPEED_38400  "\x00\x03\x20\x02\x01\x10\x00\x00\x00\x00\x5f\x84"

String to send to set camera speed to 38400 bits per second.


SPEED_57600

#define SPEED_57600  "\x00\x03\x40\x02\x01\x10\x00\x00\x00\x00\x5e\x57"

String to send to set camera speed to 57600 bits per second.


SPEED_115200

#define SPEED_115200 "\x00\x03\x80\x02\x01\x10\x00\x00\x00\x00\x4d\xf9"

String to send to set camera speed to 115200 bits per second.