@ -53,9 +53,131 @@ struct printer_data {
int16_t paper_codes [ 256 ] ;
int16_t pgcode_offset ; /* Offset into printjob for paper type */
int16_t paper_code_offset ; /* Offset in readback for paper type */
int 16_t error_offset ;
int ( * error_detect ) ( uint8_t * rdbuf ) ;
} ;
static int es1_error_detect ( uint8_t * rdbuf )
{
if ( ! rdbuf [ 1 ] )
return 0 ;
if ( rdbuf [ 9 ] = = 0x80 )
ERROR ( " No media loaded! \n " ) ;
else if ( rdbuf [ 9 ] = = 0x00 )
ERROR ( " Cover open! \n " ) ;
else
ERROR ( " Unknown error - %02x \n " ,
rdbuf [ 9 ] ) ;
return 1 ;
}
static int es2_error_detect ( uint8_t * rdbuf )
{
if ( rdbuf [ 0 ] = = 0x16 & &
rdbuf [ 1 ] = = 0x01 ) {
ERROR ( " Cover open! \n " ) ;
return 1 ;
}
if ( rdbuf [ 0 ] = = 0x02 & &
rdbuf [ 4 ] = = 0x05 & &
rdbuf [ 5 ] = = 0x05 & &
rdbuf [ 6 ] = = 0x02 ) {
ERROR ( " No media loaded! \n " ) ;
return 1 ;
}
return 0 ;
}
static int es3_error_detect ( uint8_t * rdbuf )
{
if ( rdbuf [ 8 ] = = 0x01 ) {
if ( rdbuf [ 10 ] = = 0x0f ) {
ERROR ( " Communications Error \n " ) ;
} else if ( rdbuf [ 10 ] = = 0x01 ) {
ERROR ( " No media/ribbon loaded! \n " ) ;
} else {
ERROR ( " Unknown error - %02x + %02x \n " ,
rdbuf [ 8 ] , rdbuf [ 10 ] ) ;
}
return 1 ;
} else if ( rdbuf [ 8 ] = = 0x03 & &
rdbuf [ 10 ] = = 0x02 ) {
ERROR ( " No media! \n " ) ;
return 1 ;
} else if ( rdbuf [ 8 ] = = 0x08 & &
rdbuf [ 10 ] = = 0x04 ) {
ERROR ( " Cover open! \n " ) ;
return 1 ;
}
if ( rdbuf [ 8 ] | | rdbuf [ 10 ] ) {
ERROR ( " Unknown error - %02x + %02x \n " ,
rdbuf [ 8 ] , rdbuf [ 10 ] ) ;
}
return 0 ;
}
static int es40_error_detect ( uint8_t * rdbuf )
{
if ( ! rdbuf [ 4 ] & & ! rdbuf [ 5 ] ) {
/* ES40 */
if ( ! rdbuf [ 3 ] )
return 0 ;
if ( rdbuf [ 3 ] = = 0x01 )
ERROR ( " Generic communication error \n " ) ;
else if ( rdbuf [ 3 ] = = 0x32 )
ERROR ( " Cover open or media empty! \n " ) ;
else
ERROR ( " Unknown error - %02x \n " , rdbuf [ 3 ] ) ;
return 1 ;
}
/* CP790 */
if ( rdbuf [ 4 ] = = 0x10 & & rdbuf [ 5 ] = = 0xff ) {
ERROR ( " No ribbon! \n " ) ;
return 1 ;
} else if ( rdbuf [ 4 ] = = 0xff & & rdbuf [ 5 ] = = 0x01 ) {
ERROR ( " No media loaded! \n " ) ;
return 1 ;
}
return 0 ;
}
static int cp10_error_detect ( uint8_t * rdbuf )
{
if ( ! rdbuf [ 2 ] )
return 0 ;
if ( rdbuf [ 2 ] = = 0x80 )
ERROR ( " No ribbon \n " ) ;
else if ( rdbuf [ 2 ] = = 0x01 )
ERROR ( " No media! \n " ) ;
else
ERROR ( " Unknown error - %02x \n " , rdbuf [ 2 ] ) ;
return 1 ;
}
static int cpxxx_error_detect ( uint8_t * rdbuf )
{
if ( ! rdbuf [ 2 ] )
return 0 ;
if ( rdbuf [ 2 ] = = 0x01 )
ERROR ( " Out of paper! \n " ) ;
else if ( rdbuf [ 2 ] = = 0x04 )
ERROR ( " Ribbon problem! \n " ) ;
else if ( rdbuf [ 2 ] = = 0x08 )
ERROR ( " Ribbon depleted! \n " ) ;
else
ERROR ( " Unknown error - %02x \n " , rdbuf [ 2 ] ) ;
return 1 ;
}
static struct printer_data selphy_printers [ ] = {
{ . type = P_ES1 ,
. model = " SELPHY ES1 " ,
@ -70,7 +192,7 @@ static struct printer_data selphy_printers[] = {
// .paper_codes
. pgcode_offset = 3 ,
. paper_code_offset = 6 ,
. error_ offset = 1 ,
. error_ detect = es1_error_detect ,
} ,
{ . type = P_ES2_20 ,
. model = " SELPHY ES2/ES20 " ,
@ -85,7 +207,7 @@ static struct printer_data selphy_printers[] = {
// .paper_codes
. pgcode_offset = 2 ,
. paper_code_offset = 4 ,
. error_ offset = 1 , // XXX insufficient
. error_ detect = es2_error_detect ,
} ,
{ . type = P_ES3_30 ,
. model = " SELPHY ES3/ES30 " ,
@ -100,7 +222,7 @@ static struct printer_data selphy_printers[] = {
// .paper_codes
. pgcode_offset = 2 ,
. paper_code_offset = - 1 ,
. error_ offset = 8 , // or 10
. error_ detect = es3_error_detect ,
} ,
{ . type = P_ES40_CP790 ,
. model = " SELPHY ES40/CP790 " ,
@ -115,7 +237,7 @@ static struct printer_data selphy_printers[] = {
// .paper_codes
. pgcode_offset = 2 ,
. paper_code_offset = 11 ,
. error_ offset = 3 ,
. error_ detect = es40_error_detect ,
} ,
{ . type = P_CP_XXX ,
. model = " SELPHY CP Series (!CP-10/CP790) " ,
@ -130,7 +252,7 @@ static struct printer_data selphy_printers[] = {
// .paper_codes
. pgcode_offset = 3 ,
. paper_code_offset = 6 ,
. error_ offset = 2 ,
. error_ detect = cpxxx_error_detect ,
} ,
{ . type = P_CP10 ,
. model = " SELPHY CP-10 " ,
@ -145,7 +267,7 @@ static struct printer_data selphy_printers[] = {
// .clear_error
. pgcode_offset = - 1 ,
. paper_code_offset = - 1 ,
. error_ offset = 2 ,
. error_ detect = cp10_error_detect ,
} ,
{ . type = - 1 } ,
} ;
@ -215,17 +337,12 @@ enum {
S_FINISHED ,
} ;
static int fancy_memcmp ( const uint8_t * buf_a , const int16_t * buf_b , uint len , int16_t papercode_offset , int16_t papercode_val )
static int fancy_memcmp ( const uint8_t * buf_a , const int16_t * buf_b , uint len )
{
uint i ;
for ( i = 0 ; i < len ; i + + ) {
if ( papercode_offset ! = - 1 & & i = = ( uint ) papercode_offset ) {
if ( papercode_val = = - 1 )
continue ;
else if ( ( buf_a [ i ] & 0xf ) ! = ( papercode_val & 0xf ) )
return INCORRECT_PAPER ;
} else if ( buf_b [ i ] = = - 1 )
if ( buf_b [ i ] = = - 1 )
continue ;
else if ( buf_a [ i ] > buf_b [ i ] )
return 1 ;
@ -530,18 +647,25 @@ top:
fflush ( stderr ) ;
/* Error detection */
if ( ctx - > printer - > error_offset ! = - 1 & &
rdbuf [ ctx - > printer - > error_offset ] ) {
ERROR ( " Printer reported error condition %02x; aborting. (Out of ribbon/paper?) \n " , rdbuf [ ctx - > printer - > error_offset ] ) ;
if ( ctx - > printer - > error_detect ( rdbuf ) )
return 4 ;
}
switch ( state ) {
case S_IDLE :
INFO ( " Waiting for printer idle \n " ) ;
if ( ! fancy_memcmp ( rdbuf , ctx - > printer - > init_readback , READBACK_LEN , ctx - > printer - > paper_code_offset , ctx - > paper_code ) ) {
state = S_PRINTER_READY ;
if ( fancy_memcmp ( rdbuf , ctx - > printer - > init_readback , READBACK_LEN ) )
break ;
/* Make sure paper is correct */
if ( ctx - > printer - > paper_code_offset ! = - 1 ) {
if ( ( rdbuf [ ctx - > printer - > paper_code_offset ] & 0x0f ) ! =
( ctx - > paper_code & 0x0f ) ) {
ERROR ( " Incorrect paper loaded, aborting job! \n " ) ;
return 3 ; /* Hold this job, don't stop queue */
}
}
state = S_PRINTER_READY ;
break ;
case S_PRINTER_READY :
INFO ( " Printing started; Sending init sequence \n " ) ;
@ -552,7 +676,7 @@ top:
state = S_PRINTER_INIT_SENT ;
break ;
case S_PRINTER_INIT_SENT :
if ( ! fancy_memcmp ( rdbuf , ctx - > printer - > ready_y_readback , READBACK_LEN , ctx - > printer - > paper_code_offset , ctx - > paper_code )) {
if ( ! fancy_memcmp ( rdbuf , ctx - > printer - > ready_y_readback , READBACK_LEN )) {
state = S_PRINTER_READY_Y ;
}
break ;
@ -568,7 +692,7 @@ top:
state = S_PRINTER_Y_SENT ;
break ;
case S_PRINTER_Y_SENT :
if ( ! fancy_memcmp ( rdbuf , ctx - > printer - > ready_m_readback , READBACK_LEN , ctx - > printer - > paper_code_offset , ctx - > paper_code )) {
if ( ! fancy_memcmp ( rdbuf , ctx - > printer - > ready_m_readback , READBACK_LEN )) {
if ( ctx - > bw_mode )
state = S_PRINTER_DONE ;
else
@ -584,7 +708,7 @@ top:
state = S_PRINTER_M_SENT ;
break ;
case S_PRINTER_M_SENT :
if ( ! fancy_memcmp ( rdbuf , ctx - > printer - > ready_c_readback , READBACK_LEN , ctx - > printer - > paper_code_offset , ctx - > paper_code )) {
if ( ! fancy_memcmp ( rdbuf , ctx - > printer - > ready_c_readback , READBACK_LEN )) {
state = S_PRINTER_READY_C ;
}
break ;
@ -597,7 +721,7 @@ top:
state = S_PRINTER_C_SENT ;
break ;
case S_PRINTER_C_SENT :
if ( ! fancy_memcmp ( rdbuf , ctx - > printer - > done_c_readback , READBACK_LEN , ctx - > printer - > paper_code_offset , ctx - > paper_code )) {
if ( ! fancy_memcmp ( rdbuf , ctx - > printer - > done_c_readback , READBACK_LEN )) {
state = S_PRINTER_DONE ;
}
break ;
@ -666,7 +790,7 @@ top:
struct dyesub_backend canonselphy_backend = {
. name = " Canon SELPHY CP/ES " ,
. version = " 0.6 8 " ,
. version = " 0.6 9 " ,
. multipage_capable = 1 ,
. uri_prefix = " canonselphy " ,
. init = canonselphy_init ,
@ -834,7 +958,6 @@ struct dyesub_backend canonselphy_backend = {
00 ff 10 00 ff ff ff ff 00 00 00 00 [ ready for footer ]
01 ff 10 00 ff ff ff ff 01 00 0f 00 [ communication error ]
00 ff 00 00 ff ff ff ff 00 00 00 00 [ cover open , no media ]
00 ff 01 00 ff ff ff ff 01 00 01 00 [ error , no media / ink ]
00 ff 01 00 ff ff ff ff 03 00 02 00 [ attempt to print with no media ]
00 ff 01 00 ff ff ff ff 08 00 04 00 [ attempt to print with cover open ]