📄 main.lss
字号:
37c: 81 e0 ldi r24, 0x01 ; 1
37e: 0e 94 b4 00 call 0x168 ; 0x168 <toggle_recv>
if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_IN )==USB_INT_SUCCESS ) { // DATA阶段操作成功
382: 89 e0 ldi r24, 0x09 ; 9
384: 0e 94 15 01 call 0x22a ; 0x22a <issue_token>
388: 84 31 cpi r24, 0x14 ; 20
38a: 89 f4 brne .+34 ; 0x3ae <get_port_status+0x70>
rd_usb_data( buffer ); // 读出接收到的数据,通常只有1个字节
38c: 88 e7 ldi r24, 0x78 ; 120
38e: 91 e0 ldi r25, 0x01 ; 1
390: 0e 94 e3 00 call 0x1c6 ; 0x1c6 <rd_usb_data>
toggle_send( 1 ); // STATUS阶段为DATA1
394: 81 e0 ldi r24, 0x01 ; 1
396: 0e 94 c5 00 call 0x18a ; 0x18a <toggle_send>
wr_usb_data( 0, buffer ); // 发送0长度的数据说明控制传输成功
39a: 68 e7 ldi r22, 0x78 ; 120
39c: 71 e0 ldi r23, 0x01 ; 1
39e: 80 e0 ldi r24, 0x00 ; 0
3a0: 0e 94 fe 00 call 0x1fc ; 0x1fc <wr_usb_data>
if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_OUT )==USB_INT_SUCCESS ) return( buffer[0] ); // 返回状态码
3a4: 81 e0 ldi r24, 0x01 ; 1
3a6: 0e 94 15 01 call 0x22a ; 0x22a <issue_token>
3aa: 84 31 cpi r24, 0x14 ; 20
3ac: 19 f0 breq .+6 ; 0x3b4 <get_port_status+0x76>
3ae: 8f ef ldi r24, 0xFF ; 255
3b0: 90 e0 ldi r25, 0x00 ; 0
}
}
return( 0xFF ); // 返回操作失败
}
3b2: 08 95 ret
3b4: 80 91 78 01 lds r24, 0x0178
3b8: 99 27 eor r25, r25
3ba: 08 95 ret
000003bc <get_port_status_X>:
unsigned char get_port_status_X( void ) { // 查询打印机端口状态,返回状态码,如果为0FFH则说明操作失败,适用于CH375A
3bc: 81 ea ldi r24, 0xA1 ; 161
3be: 80 93 78 01 sts 0x0178, r24
3c2: 81 e0 ldi r24, 0x01 ; 1
3c4: 80 93 79 01 sts 0x0179, r24
3c8: 10 92 7d 01 sts 0x017D, r1
3cc: 10 92 7c 01 sts 0x017C, r1
3d0: 10 92 7b 01 sts 0x017B, r1
3d4: 10 92 7a 01 sts 0x017A, r1
3d8: 80 93 7e 01 sts 0x017E, r24
3dc: 10 92 7f 01 sts 0x017F, r1
// 返回状态码中: 位5(Paper Empty)为1说明无纸, 位4(Select)为1说明打印机联机, 位3(Not Error)为0说明打印机出错
buffer[0]=0xA1; buffer[1]=1; buffer[2]=buffer[3]=buffer[4]=buffer[5]=0; buffer[6]=1; buffer[7]=0; // 控制传输获取打印机状态,SETUP数据
wr_usb_data( 8, buffer ); // SETUP数据总是8字节
3e0: 68 e7 ldi r22, 0x78 ; 120
3e2: 71 e0 ldi r23, 0x01 ; 1
3e4: 88 e0 ldi r24, 0x08 ; 8
3e6: 0e 94 fe 00 call 0x1fc ; 0x1fc <wr_usb_data>
if ( issue_token_X( ( 0 << 4 ) | DEF_USB_PID_SETUP, 0x00 )==USB_INT_SUCCESS ) { // SETUP阶段DATA0操作成功
3ea: 60 e0 ldi r22, 0x00 ; 0
3ec: 8d e0 ldi r24, 0x0D ; 13
3ee: 0e 94 22 01 call 0x244 ; 0x244 <issue_token_X>
3f2: 84 31 cpi r24, 0x14 ; 20
3f4: a9 f4 brne .+42 ; 0x420 <get_port_status_X+0x64>
if ( issue_token_X( ( 0 << 4 ) | DEF_USB_PID_IN, 0x80 )==USB_INT_SUCCESS ) { // DATA阶段DATA1接收操作成功
3f6: 60 e8 ldi r22, 0x80 ; 128
3f8: 89 e0 ldi r24, 0x09 ; 9
3fa: 0e 94 22 01 call 0x244 ; 0x244 <issue_token_X>
3fe: 84 31 cpi r24, 0x14 ; 20
400: 79 f4 brne .+30 ; 0x420 <get_port_status_X+0x64>
rd_usb_data( buffer ); // 读出接收到的数据,通常只有1个字节
402: 88 e7 ldi r24, 0x78 ; 120
404: 91 e0 ldi r25, 0x01 ; 1
406: 0e 94 e3 00 call 0x1c6 ; 0x1c6 <rd_usb_data>
wr_usb_data( 0, buffer ); // 发送0长度的数据DATA1说明控制传输成功
40a: 68 e7 ldi r22, 0x78 ; 120
40c: 71 e0 ldi r23, 0x01 ; 1
40e: 80 e0 ldi r24, 0x00 ; 0
410: 0e 94 fe 00 call 0x1fc ; 0x1fc <wr_usb_data>
if ( issue_token_X( ( 0 << 4 ) | DEF_USB_PID_OUT, 0x40 )==USB_INT_SUCCESS ) return( buffer[0] ); // STATUS阶段操作成功,返回状态码
414: 60 e4 ldi r22, 0x40 ; 64
416: 81 e0 ldi r24, 0x01 ; 1
418: 0e 94 22 01 call 0x244 ; 0x244 <issue_token_X>
41c: 84 31 cpi r24, 0x14 ; 20
41e: 19 f0 breq .+6 ; 0x426 <get_port_status_X+0x6a>
420: 8f ef ldi r24, 0xFF ; 255
422: 90 e0 ldi r25, 0x00 ; 0
}
}
return( 0xFF ); // 返回操作失败
}
424: 08 95 ret
426: 80 91 78 01 lds r24, 0x0178
42a: 99 27 eor r25, r25
42c: 08 95 ret
0000042e <get_descr>:
unsigned char get_descr( unsigned char type ) { // 从设备端获取描述符
42e: 1f 93 push r17
430: 18 2f mov r17, r24
xWriteCH375Cmd( CMD_GET_DESCR );
432: 86 e4 ldi r24, 0x46 ; 70
434: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
xWriteCH375Data( type ); // 描述符类型, 只支持1(设备)或者2(配置)
438: 81 2f mov r24, r17
43a: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
return( wait_interrupt() ); // 等待CH375操作完成
43e: 0e 94 90 00 call 0x120 ; 0x120 <wait_interrupt>
}
442: 99 27 eor r25, r25
444: 1f 91 pop r17
446: 08 95 ret
00000448 <set_addr>:
unsigned char set_addr( unsigned char addr ) { // 设置设备端的USB地址
448: 0f 93 push r16
44a: 1f 93 push r17
44c: 08 2f mov r16, r24
unsigned char status;
xWriteCH375Cmd( CMD_SET_ADDRESS ); // 设置USB设备端的USB地址
44e: 85 e4 ldi r24, 0x45 ; 69
450: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
xWriteCH375Data( addr ); // 地址, 从1到127之间的任意值, 常用2到20
454: 80 2f mov r24, r16
456: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
status=wait_interrupt(); // 等待CH375操作完成
45a: 0e 94 90 00 call 0x120 ; 0x120 <wait_interrupt>
45e: 18 2f mov r17, r24
if ( status==USB_INT_SUCCESS ) { // 操作成功
460: 84 31 cpi r24, 0x14 ; 20
462: 31 f4 brne .+12 ; 0x470 <set_addr+0x28>
xWriteCH375Cmd( CMD_SET_USB_ADDR ); // 设置USB主机端的USB地址
464: 83 e1 ldi r24, 0x13 ; 19
466: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
xWriteCH375Data( addr ); // 当目标USB设备的地址成功修改后,应该同步修改主机端的USB地址
46a: 80 2f mov r24, r16
46c: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
*/
void
_delay_loop_2(uint16_t __count)
{
__asm__ volatile (
470: 80 e0 ldi r24, 0x00 ; 0
472: 96 e3 ldi r25, 0x36 ; 54
474: 01 97 sbiw r24, 0x01 ; 1
476: f1 f7 brne .-4 ; 0x474 <set_addr+0x2c>
}
mDelaymS( 5 );
return( status );
}
478: 81 2f mov r24, r17
47a: 99 27 eor r25, r25
47c: 1f 91 pop r17
47e: 0f 91 pop r16
480: 08 95 ret
00000482 <set_config>:
unsigned char set_config( unsigned char cfg ) { // 设置设备端的USB配置
482: 1f 93 push r17
484: 18 2f mov r17, r24
tog_send=tog_recv=0; // 复位USB数据同步标志
486: 10 92 76 01 sts 0x0176, r1
48a: 10 92 b9 01 sts 0x01B9, r1
xWriteCH375Cmd( CMD_SET_CONFIG ); // 设置USB设备端的配置值
48e: 89 e4 ldi r24, 0x49 ; 73
490: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
xWriteCH375Data( cfg ); // 此值取自USB设备的配置描述符中
494: 81 2f mov r24, r17
496: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
return( wait_interrupt() ); // 等待CH375操作完成
49a: 0e 94 90 00 call 0x120 ; 0x120 <wait_interrupt>
}
49e: 99 27 eor r25, r25
4a0: 1f 91 pop r17
4a2: 08 95 ret
000004a4 <init_print>:
#define UNKNOWN_USB_DEVICE 0xF1
#define UNKNOWN_USB_PRINT 0xF2
unsigned char init_print( void ) { // 初始化USB打印机,完成打印机枚举
4a4: 81 e0 ldi r24, 0x01 ; 1
4a6: 0e 94 17 02 call 0x42e ; 0x42e <get_descr>
#define p_dev_descr ((PUSB_DEV_DESCR)buffer)
#define p_cfg_descr ((PUSB_CFG_DESCR_LONG)buffer)
unsigned char status, len, c;
status=get_descr(1); // 获取设备描述符
if ( status==USB_INT_SUCCESS ) {
4aa: 84 31 cpi r24, 0x14 ; 20
4ac: b1 f4 brne .+44 ; 0x4da <init_print+0x36>
len=rd_usb_data( buffer ); // 将获取的描述符数据从CH375中读出到单片机的RAM缓冲区中,返回描述符长度
4ae: 88 e7 ldi r24, 0x78 ; 120
4b0: 91 e0 ldi r25, 0x01 ; 1
4b2: 0e 94 e3 00 call 0x1c6 ; 0x1c6 <rd_usb_data>
if ( len<18 || p_dev_descr->bDescriptorType!=1 ) return( UNKNOWN_USB_DEVICE ); // 意外错误:描述符长度错误或者类型错误
4b6: 82 31 cpi r24, 0x12 ; 18
4b8: 40 f0 brcs .+16 ; 0x4ca <init_print+0x26>
4ba: 80 91 79 01 lds r24, 0x0179
4be: 81 30 cpi r24, 0x01 ; 1
4c0: 21 f4 brne .+8 ; 0x4ca <init_print+0x26>
if ( p_dev_descr->bDeviceClass!=0 ) return( UNKNOWN_USB_DEVICE ); // 连接的USB设备不是USB打印机,或者不符合USB规范
4c2: 80 91 7c 01 lds r24, 0x017C
4c6: 88 23 and r24, r24
4c8: 19 f0 breq .+6 ; 0x4d0 <init_print+0x2c>
status=set_addr(3); // 设置打印机的USB地址
if ( status==USB_INT_SUCCESS ) {
status=get_descr(2); // 获取配置描述符
if ( status==USB_INT_SUCCESS ) { // 操作成功则读出描述符并分析
len=rd_usb_data( buffer ); // 将获取的描述符数据从CH375中读出到单片机的RAM缓冲区中,返回描述符长度
if ( p_cfg_descr->itf_descr.bInterfaceClass!=7 || p_cfg_descr->itf_descr.bInterfaceSubClass!=1 ) return( UNKNOWN_USB_PRINT ); // 不是USB打印机或者不符合USB规范
endp_out_addr=endp_in_addr=0;
c=p_cfg_descr->endp_descr[0].bEndpointAddress; // 第一个端点的地址
if ( c&0x80 ) endp_in_addr=c&0x0f; // IN端点的地址
else { // OUT端点
endp_out_addr=c&0x0f;
endp_out_size=p_cfg_descr->endp_descr[0].wMaxPacketSize; // 数据接收端点的最大包长度
}
if ( p_cfg_descr->itf_descr.bNumEndpoints>=2 ) { // 接口有两个以上的端点
if ( p_cfg_descr->endp_descr[1].bDescriptorType==5 ) { // 端点描述符
c=p_cfg_descr->endp_descr[1].bEndpointAddress; // 第二个端点的地址
if ( c&0x80 ) endp_in_addr=c&0x0f; // IN端点
else { // OUT端点
endp_out_addr=c&0x0f;
endp_out_size=p_cfg_descr->endp_descr[1].wMaxPacketSize;
}
}
}
if ( p_cfg_descr->itf_descr.bInterfaceProtocol<=1 ) endp_in_addr=0; // 单向接口不需要IN端点
if ( endp_out_addr==0 ) return( UNKNOWN_USB_PRINT ); // 不是USB打印机或者不符合USB规范
status=set_config( p_cfg_descr->cfg_descr.bConfigurationValue ); // 加载USB配置值
if ( status==USB_INT_SUCCESS ) {
xWriteCH375Cmd( CMD_SET_RETRY ); // 设置USB事务操作的重试次数
xWriteCH375Data( 0x25 );
xWriteCH375Data( 0x89 ); // 位7为1则收到NAK时无限重试, 位3~位0为超时后的重试次数
4ca: 81 ef ldi r24, 0xF1 ; 241
4cc: 90 e0 ldi r25, 0x00 ; 0
4ce: 08 95 ret
4d0: 83 e0 ldi r24, 0x03 ; 3
4d2: 0e 94 24 02 call 0x448 ; 0x448 <set_addr>
4d6: 84 31 cpi r24, 0x14 ; 20
4d8: 11 f0 breq .+4 ; 0x4de <init_print+0x3a>
4da: 99 27 eor r25, r25
4dc: 08 95 ret
4de: 82 e0 ldi r24, 0x02 ; 2
4e0: 0e 94 17 02 call 0x42e ; 0x42e <get_descr>
4e4: 84 31 cpi r24, 0x14 ; 20
4e6: c9 f7 brne .-14 ; 0x4da <init_print+0x36>
4e8: 88 e7 ldi r24, 0x78 ; 120
4ea: 91 e0 ldi r25, 0x01 ; 1
4ec: 0e 94 e3 00 call 0x1c6 ; 0x1c6 <rd_usb_data>
4f0: 80 91 86 01 lds r24, 0x0186
4f4: 87 30 cpi r24, 0x07 ; 7
4f6: 19 f5 brne .+70 ; 0x53e <init_print+0x9a>
4f8: 80 91 87 01 lds r24, 0x0187
4fc: 81 30 cpi r24, 0x01 ; 1
4fe: f9 f4 brne .+62 ; 0x53e <init_print+0x9a>
500: 10 92 b8 01 sts 0x01B8, r1
504: 10 92 77 01 sts 0x0177, r1
508: 80 91 8c 01 lds r24, 0x018C
50c: 87 fd sbrc r24, 7
50e: 3b c0 rjmp .+118 ; 0x586 <init_print+0xe2>
510: 8f 70 andi r24, 0x0F ; 15
512: 80 93 77 01 sts 0x0177, r24
516: 80 91 8e 01 lds r24, 0x018E
51a: 80 93 ba 01 sts 0x01BA, r24
51e: 80 91 85 01 lds r24, 0x0185
522: 82 30 cpi r24, 0x02 ; 2
524: 20 f0 brcs .+8 ; 0x52e <init_print+0x8a>
526: 80 91 92 01 lds r24, 0x0192
52a: 85 30 cpi r24, 0x05 ; 5
52c: e9 f0 breq .+58 ; 0x568 <init_print+0xc4>
52e: 80 91 88 01 lds r24, 0x0188
532: 82 30 cpi r24, 0x02 ; 2
534: 28 f1 brcs .+74 ; 0x580 <init_print+0xdc>
536: 80 91 77 01 lds r24, 0x0177
53a: 88 23 and r24, r24
53c: 19 f4 brne .+6 ; 0x544 <init_print+0xa0>
53e: 82 ef ldi r24, 0xF2 ; 242
540: 90 e0 ldi r25, 0x00 ; 0
// 如果单片机在打印机忙时并无事可做,建议设置位7为1,使CH375在收到NAK时自动重试直到操作成功或者失败
// 如果希望单片机在打印机忙时能够做其它事,那么应该设置位7为0,使CH375在收到NAK时不重试,
// 所以在下面的USB通讯过程中,如果USB打印机正忙,issue_token等子程序将得到状态码USB_INT_RET_NAK
}
}
}
}
return(status);
}
542: 08 95 ret
544: 80 91 7d 01 lds r24, 0x017D
548: 0e 94 41 02 call 0x482 ; 0x482 <set_config>
54c: 84 31 cpi r24, 0x14 ; 20
54e: 29 f6 brne .-118 ; 0x4da <init_print+0x36>
550: 8b e0 ldi r24, 0x0B ; 11
552: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
556: 85 e2 ldi r24, 0x25 ; 37
558: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
55c: 89 e8 ldi r24, 0x89 ; 137
55e: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
562: 84 e1 ldi r24, 0x14 ; 20
564: 90 e0 ldi r25, 0x00 ; 0
566: 08 95 ret
568: 80 91 93 01 lds r24, 0x0193
56c: 87 fd sbrc r24, 7
56e: 0f c0 rjmp .+30 ; 0x58e <init_print+0xea>
570: 8f 70 andi r24, 0x0F ; 15
572: 80 93 77 01 sts 0x0177, r24
576: 80 91 95 01 lds r24, 0x0195
57a: 80 93 ba 01 sts 0x01BA, r24
57e: d7 cf rjmp .-82 ; 0x52e <init_print+0x8a>
580: 10 92 b8 01 sts 0x01B8, r1
584: d8 cf rjmp .-80 ; 0x536 <init_print+0x92>
586: 8f 70 andi r24, 0x0F ; 15
588: 80 93 b8 01 sts 0x01B8, r24
58c: c8 cf rjmp .-112 ; 0x51e <init_print+0x7a>
58e: 8f 70 andi r24, 0x0F ; 15
590: 80 93 b8 01 sts 0x01B8, r24
594: cc cf rjmp .-104 ; 0x52e <init_print+0x8a>
00000596 <uart_putchar>:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -