📄 main.lss
字号:
{
__asm__ volatile (
180: 87 e0 ldi r24, 0x07 ; 7
182: 8a 95 dec r24
184: f1 f7 brne .-4 ; 0x182 <toggle_recv+0x1a>
186: 1f 91 pop r17
188: 08 95 ret
0000018a <toggle_send>:
delay2us();
}
void toggle_send( BOOL1 tog ) { // 主机发送同步控制:0=DATA0,1=DATA1
18a: 1f 93 push r17
18c: 18 2f mov r17, r24
xWriteCH375Cmd( CMD_SET_ENDP7 );
18e: 8d e1 ldi r24, 0x1D ; 29
190: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
xWriteCH375Data( tog ? 0xC0 : 0x80 );
194: 11 23 and r17, r17
196: 11 f0 breq .+4 ; 0x19c <toggle_send+0x12>
198: 80 ec ldi r24, 0xC0 ; 192
19a: 01 c0 rjmp .+2 ; 0x19e <toggle_send+0x14>
19c: 80 e8 ldi r24, 0x80 ; 128
19e: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
*/
void
_delay_loop_1(uint8_t __count)
{
__asm__ volatile (
1a2: 87 e0 ldi r24, 0x07 ; 7
1a4: 8a 95 dec r24
1a6: f1 f7 brne .-4 ; 0x1a4 <toggle_send+0x1a>
1a8: 1f 91 pop r17
1aa: 08 95 ret
000001ac <clr_stall>:
delay2us();
}
unsigned char clr_stall( unsigned char endp_addr ) { // USB通讯失败后,复位设备端的指定端点到DATA0
1ac: 1f 93 push r17
1ae: 18 2f mov r17, r24
xWriteCH375Cmd( CMD_CLR_STALL );
1b0: 81 e4 ldi r24, 0x41 ; 65
1b2: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
xWriteCH375Data( endp_addr );
1b6: 81 2f mov r24, r17
1b8: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
return( wait_interrupt() );
1bc: 0e 94 90 00 call 0x120 ; 0x120 <wait_interrupt>
}
1c0: 99 27 eor r25, r25
1c2: 1f 91 pop r17
1c4: 08 95 ret
000001c6 <rd_usb_data>:
// 数据读写, 单片机读写CH375芯片中的数据缓冲区
unsigned char rd_usb_data( unsigned char *buf ) { // 从CH37X读出数据块
1c6: 0f 93 push r16
1c8: 1f 93 push r17
1ca: cf 93 push r28
1cc: df 93 push r29
1ce: ec 01 movw r28, r24
unsigned char i, len;
xWriteCH375Cmd( CMD_RD_USB_DATA ); // 从CH375的端点缓冲区读取接收到的数据
1d0: 88 e2 ldi r24, 0x28 ; 40
1d2: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
len=xReadCH375Data(); // 后续数据长度
1d6: 0e 94 83 00 call 0x106 ; 0x106 <xReadCH375Data>
1da: 08 2f mov r16, r24
for ( i=0; i!=len; i++ ) *buf++=xReadCH375Data();
1dc: 88 23 and r24, r24
1de: 39 f0 breq .+14 ; 0x1ee <rd_usb_data+0x28>
1e0: 10 e0 ldi r17, 0x00 ; 0
1e2: 0e 94 83 00 call 0x106 ; 0x106 <xReadCH375Data>
1e6: 89 93 st Y+, r24
1e8: 1f 5f subi r17, 0xFF ; 255
1ea: 01 17 cp r16, r17
1ec: d1 f7 brne .-12 ; 0x1e2 <rd_usb_data+0x1c>
return( len );
}
1ee: 80 2f mov r24, r16
1f0: 99 27 eor r25, r25
1f2: df 91 pop r29
1f4: cf 91 pop r28
1f6: 1f 91 pop r17
1f8: 0f 91 pop r16
1fa: 08 95 ret
000001fc <wr_usb_data>:
void wr_usb_data( unsigned char len, unsigned char *buf ) { // 向CH37X写入数据块
1fc: 1f 93 push r17
1fe: cf 93 push r28
200: df 93 push r29
202: 18 2f mov r17, r24
204: eb 01 movw r28, r22
xWriteCH375Cmd( CMD_WR_USB_DATA7 ); // 向CH375的端点缓冲区写入准备发送的数据
206: 8b e2 ldi r24, 0x2B ; 43
208: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
xWriteCH375Data( len ); // 后续数据长度, len不能大于64
20c: 81 2f mov r24, r17
20e: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
while( len-- ) xWriteCH375Data( *buf++ );
212: 11 50 subi r17, 0x01 ; 1
214: 1f 3f cpi r17, 0xFF ; 255
216: 29 f0 breq .+10 ; 0x222 <wr_usb_data+0x26>
218: 89 91 ld r24, Y+
21a: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
21e: 11 50 subi r17, 0x01 ; 1
220: d8 f7 brcc .-10 ; 0x218 <wr_usb_data+0x1c>
222: df 91 pop r29
224: cf 91 pop r28
226: 1f 91 pop r17
228: 08 95 ret
0000022a <issue_token>:
}
// 主机操作
unsigned char endp_out_addr; // 打印机数据接收端点的端点地址
unsigned char endp_out_size; // 打印机数据接收端点的端点尺寸
BOOL1 tog_send; // 打印机数据接收端点的同步标志
unsigned char endp_in_addr; // 双向打印机发送端点的端点地址,一般不用
BOOL1 tog_recv; // 双向打印机发送端点的同步标志,一般不用
unsigned char issue_token( unsigned char endp_and_pid ) { // 执行USB事务
22a: 1f 93 push r17
22c: 18 2f mov r17, r24
// 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功
xWriteCH375Cmd( CMD_ISSUE_TOKEN );
22e: 8f e4 ldi r24, 0x4F ; 79
230: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
xWriteCH375Data( endp_and_pid ); // 高4位目的端点号, 低4位令牌PID
234: 81 2f mov r24, r17
236: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
return( wait_interrupt() ); // 等待CH375操作完成
23a: 0e 94 90 00 call 0x120 ; 0x120 <wait_interrupt>
}
23e: 99 27 eor r25, r25
240: 1f 91 pop r17
242: 08 95 ret
00000244 <issue_token_X>:
unsigned char issue_token_X( unsigned char endp_and_pid, unsigned char tog ) { // 执行USB事务,适用于CH375A
244: 0f 93 push r16
246: 1f 93 push r17
248: 08 2f mov r16, r24
24a: 16 2f mov r17, r22
// 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功
xWriteCH375Cmd( CMD_ISSUE_TKN_X );
24c: 8e e4 ldi r24, 0x4E ; 78
24e: 0e 94 65 00 call 0xca ; 0xca <xWriteCH375Cmd>
xWriteCH375Data( tog ); // 同步标志的位7为主机端点IN的同步触发位, 位6为主机端点OUT的同步触发位, 位5~位0必须为0
252: 81 2f mov r24, r17
254: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
xWriteCH375Data( endp_and_pid ); // 高4位目的端点号, 低4位令牌PID
258: 80 2f mov r24, r16
25a: 0e 94 74 00 call 0xe8 ; 0xe8 <xWriteCH375Data>
return( wait_interrupt() ); // 等待CH375操作完成
25e: 0e 94 90 00 call 0x120 ; 0x120 <wait_interrupt>
}
262: 99 27 eor r25, r25
264: 1f 91 pop r17
266: 0f 91 pop r16
268: 08 95 ret
0000026a <soft_reset_print>:
void soft_reset_print( void ) { // 控制传输:软复位打印机
26a: 10 92 76 01 sts 0x0176, r1
26e: 10 92 b9 01 sts 0x01B9, r1
tog_send=tog_recv=0; // 复位USB数据同步标志
toggle_send( 0 ); // SETUP阶段为DATA0
272: 80 e0 ldi r24, 0x00 ; 0
274: 0e 94 c5 00 call 0x18a ; 0x18a <toggle_send>
buffer[0]=0x21; buffer[1]=2; buffer[2]=buffer[3]=buffer[4]=buffer[5]=buffer[6]=buffer[7]=0; // SETUP数据,SOFT_RESET
278: 81 e2 ldi r24, 0x21 ; 33
27a: 80 93 78 01 sts 0x0178, r24
27e: 82 e0 ldi r24, 0x02 ; 2
280: 80 93 79 01 sts 0x0179, r24
284: 10 92 7f 01 sts 0x017F, r1
288: 10 92 7e 01 sts 0x017E, r1
28c: 10 92 7d 01 sts 0x017D, r1
290: 10 92 7c 01 sts 0x017C, r1
294: 10 92 7b 01 sts 0x017B, r1
298: 10 92 7a 01 sts 0x017A, r1
wr_usb_data( 8, buffer ); // SETUP数据总是8字节
29c: 68 e7 ldi r22, 0x78 ; 120
29e: 71 e0 ldi r23, 0x01 ; 1
2a0: 88 e0 ldi r24, 0x08 ; 8
2a2: 0e 94 fe 00 call 0x1fc ; 0x1fc <wr_usb_data>
if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_SETUP )==USB_INT_SUCCESS ) { // SETUP阶段操作成功
2a6: 8d e0 ldi r24, 0x0D ; 13
2a8: 0e 94 15 01 call 0x22a ; 0x22a <issue_token>
2ac: 84 31 cpi r24, 0x14 ; 20
2ae: 09 f0 breq .+2 ; 0x2b2 <soft_reset_print+0x48>
2b0: 08 95 ret
toggle_recv( 1 ); // STATUS阶段,准备接收DATA1
2b2: 81 e0 ldi r24, 0x01 ; 1
2b4: 0e 94 b4 00 call 0x168 ; 0x168 <toggle_recv>
if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_IN )==USB_INT_SUCCESS ) return; // STATUS阶段操作成功,操作成功返回
2b8: 89 e0 ldi r24, 0x09 ; 9
2ba: 0e 94 15 01 call 0x22a ; 0x22a <issue_token>
2be: 08 95 ret
000002c0 <send_data>:
}
}
#define USB_INT_RET_NAK 0x2A // 00101010B,返回NAK
void send_data( unsigned short len, unsigned char *buf ) { // 主机发送数据块,一次最多64KB
2c0: ff 92 push r15
2c2: 0f 93 push r16
2c4: 1f 93 push r17
2c6: cf 93 push r28
2c8: df 93 push r29
2ca: ec 01 movw r28, r24
2cc: 8b 01 movw r16, r22
unsigned char l, s;
while( len ) { // 连续输出数据块给USB打印机
2ce: 89 2b or r24, r25
2d0: 59 f4 brne .+22 ; 0x2e8 <send_data+0x28>
2d2: 2f c0 rjmp .+94 ; 0x332 <send_data+0x72>
toggle_send( tog_send ); // 数据同步
l = len>endp_out_size?endp_out_size:len; // 单次发送不能超过端点尺寸
wr_usb_data( l, buf ); // 将数据先复制到CH375芯片中
s = issue_token( ( endp_out_addr << 4 ) | DEF_USB_PID_OUT ); // 请求CH375输出数据
if ( s==USB_INT_SUCCESS ) { // CH375成功发出数据
tog_send = ~ tog_send; // 切换DATA0和DATA1进行数据同步
len-=l; // 计数
buf+=l; // 操作成功
}
else if ( s==USB_INT_RET_NAK ) { // USB打印机正忙,如果未执行SET_RETRY命令则CH375自动重试,所以不会返回USB_INT_RET_NAK状态
2d4: 8a 32 cpi r24, 0x2A ; 42
2d6: 31 f0 breq .+12 ; 0x2e4 <send_data+0x24>
// USB打印机正忙,正常情况下应该稍后重试
// s=get_port_status( ); 如果有必要,可以检查是什么原因导致打印机忙
}
else { // 操作失败,正常情况下不会失败
clr_stall( endp_out_addr ); // 清除打印机的数据接收端点,或者 soft_reset_print()
2d8: 80 91 77 01 lds r24, 0x0177
2dc: 0e 94 d6 00 call 0x1ac ; 0x1ac <clr_stall>
// soft_reset_print(); 打印机出现意外错误,软复位
tog_send = 0; // 操作失败
2e0: 10 92 b9 01 sts 0x01B9, r1
2e4: 20 97 sbiw r28, 0x00 ; 0
2e6: 29 f1 breq .+74 ; 0x332 <send_data+0x72>
2e8: 80 91 b9 01 lds r24, 0x01B9
2ec: 0e 94 c5 00 call 0x18a ; 0x18a <toggle_send>
2f0: 80 91 ba 01 lds r24, 0x01BA
2f4: 99 27 eor r25, r25
2f6: c8 17 cp r28, r24
2f8: d9 07 cpc r29, r25
2fa: 08 f4 brcc .+2 ; 0x2fe <send_data+0x3e>
2fc: ce 01 movw r24, r28
2fe: f8 2e mov r15, r24
300: b8 01 movw r22, r16
302: 0e 94 fe 00 call 0x1fc ; 0x1fc <wr_usb_data>
306: 80 91 77 01 lds r24, 0x0177
30a: 82 95 swap r24
30c: 80 7f andi r24, 0xF0 ; 240
30e: 81 60 ori r24, 0x01 ; 1
310: 0e 94 15 01 call 0x22a ; 0x22a <issue_token>
314: 84 31 cpi r24, 0x14 ; 20
316: f1 f6 brne .-68 ; 0x2d4 <send_data+0x14>
318: 80 91 b9 01 lds r24, 0x01B9
31c: 80 95 com r24
31e: 80 93 b9 01 sts 0x01B9, r24
322: 8f 2d mov r24, r15
324: 99 27 eor r25, r25
326: c8 1b sub r28, r24
328: d9 0b sbc r29, r25
32a: 08 0f add r16, r24
32c: 19 1f adc r17, r25
32e: 20 97 sbiw r28, 0x00 ; 0
330: d9 f6 brne .-74 ; 0x2e8 <send_data+0x28>
332: df 91 pop r29
334: cf 91 pop r28
336: 1f 91 pop r17
338: 0f 91 pop r16
33a: ff 90 pop r15
33c: 08 95 ret
0000033e <get_port_status>:
}
// 如果数据量较大,可以定期调用get_port_status()检查打印机状态
}
}
unsigned char get_port_status( void ) { // 查询打印机端口状态,返回状态码,如果为0FFH则说明操作失败
33e: 80 e0 ldi r24, 0x00 ; 0
340: 0e 94 c5 00 call 0x18a ; 0x18a <toggle_send>
// 返回状态码中: 位5(Paper Empty)为1说明无纸, 位4(Select)为1说明打印机联机, 位3(Not Error)为0说明打印机出错
toggle_send( 0 ); // 下面通过控制传输获取打印机的状态, SETUP阶段为DATA0
buffer[0]=0xA1; buffer[1]=1; buffer[2]=buffer[3]=buffer[4]=buffer[5]=0; buffer[6]=1; buffer[7]=0; // SETUP数据,GET_PORT_STATUS
344: 81 ea ldi r24, 0xA1 ; 161
346: 80 93 78 01 sts 0x0178, r24
34a: 81 e0 ldi r24, 0x01 ; 1
34c: 80 93 79 01 sts 0x0179, r24
350: 10 92 7d 01 sts 0x017D, r1
354: 10 92 7c 01 sts 0x017C, r1
358: 10 92 7b 01 sts 0x017B, r1
35c: 10 92 7a 01 sts 0x017A, r1
360: 80 93 7e 01 sts 0x017E, r24
364: 10 92 7f 01 sts 0x017F, r1
wr_usb_data( 8, buffer ); // SETUP数据总是8字节
368: 68 e7 ldi r22, 0x78 ; 120
36a: 71 e0 ldi r23, 0x01 ; 1
36c: 88 e0 ldi r24, 0x08 ; 8
36e: 0e 94 fe 00 call 0x1fc ; 0x1fc <wr_usb_data>
if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_SETUP )==USB_INT_SUCCESS ) { // SETUP阶段操作成功
372: 8d e0 ldi r24, 0x0D ; 13
374: 0e 94 15 01 call 0x22a ; 0x22a <issue_token>
378: 84 31 cpi r24, 0x14 ; 20
37a: c9 f4 brne .+50 ; 0x3ae <get_port_status+0x70>
toggle_recv( 1 ); // DATA阶段,准备接收DATA1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -