Serial Communication

Name

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.