You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					157 lines
				
				3.7 KiB
			
		
		
			
		
	
	
					157 lines
				
				3.7 KiB
			| 
								 
											7 years ago
										 
									 | 
							
								;---------------------------------------------------------------------------;
							 | 
						||
| 
								 | 
							
								; Software implemented UART module                                          ;
							 | 
						||
| 
								 | 
							
								; (C)ChaN, 2005 (http://elm-chan.org/)                                      ;
							 | 
						||
| 
								 | 
							
								;---------------------------------------------------------------------------;
							 | 
						||
| 
								 | 
							
								; Bit rate settings:
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								;            1MHz  2MHz  4MHz  6MHz  8MHz  10MHz  12MHz  16MHz  20MHz
							 | 
						||
| 
								 | 
							
								;   2.4kbps   138     -     -     -     -      -      -      -      -
							 | 
						||
| 
								 | 
							
								;   4.8kbps    68   138     -     -     -      -      -      -      -
							 | 
						||
| 
								 | 
							
								;   9.6kbps    33    68   138   208     -      -      -      -      -
							 | 
						||
| 
								 | 
							
								;  19.2kbps     -    33    68   102   138    173    208      -      -
							 | 
						||
| 
								 | 
							
								;  38.4kbps     -     -    33    50    68     85    102    138    172
							 | 
						||
| 
								 | 
							
								;  57.6kbps     -     -    21    33    44     56     68     91    114
							 | 
						||
| 
								 | 
							
								; 115.2kbps     -     -     -     -    21     27     33     44     56
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.nolist
							 | 
						||
| 
								 | 
							
								#include <avr/io.h>
							 | 
						||
| 
								 | 
							
								.list
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define	BPS	44 	/* Bit delay. (see above table) */
							 | 
						||
| 
								 | 
							
								#define	BIDIR	0	/* 0:Separated Tx/Rx, 1:Shared Tx/Rx */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define	OUT_1		sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT	/* Output 1 */
							 | 
						||
| 
								 | 
							
								#define	OUT_0		cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT	/* Output 0 */
							 | 
						||
| 
								 | 
							
								#define	SKIP_IN_1	sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT	/* Skip if 1 */
							 | 
						||
| 
								 | 
							
								#define	SKIP_IN_0	sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT	/* Skip if 0 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef SPM_PAGESIZE
							 | 
						||
| 
								 | 
							
								.macro	_LPMI	reg
							 | 
						||
| 
								 | 
							
									lpm	\reg, Z+
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								.macro	_MOVW	dh,dl, sh,sl
							 | 
						||
| 
								 | 
							
									movw	\dl, \sl
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								.macro	_LPMI	reg
							 | 
						||
| 
								 | 
							
									lpm
							 | 
						||
| 
								 | 
							
									mov	\reg, r0
							 | 
						||
| 
								 | 
							
									adiw	ZL, 1
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								.macro	_MOVW	dh,dl, sh,sl
							 | 
						||
| 
								 | 
							
									mov	\dl, \sl
							 | 
						||
| 
								 | 
							
									mov	\dh, \sh
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;---------------------------------------------------------------------------;
							 | 
						||
| 
								 | 
							
								; Transmit a byte in serial format of N81
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								;Prototype: void xmit (uint8_t data);
							 | 
						||
| 
								 | 
							
								;Size: 16 words
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.global xmit
							 | 
						||
| 
								 | 
							
								.func xmit
							 | 
						||
| 
								 | 
							
								xmit:
							 | 
						||
| 
								 | 
							
								#if BIDIR
							 | 
						||
| 
								 | 
							
									ldi	r23, BPS-1	;Pre-idle time for bidirectional data line
							 | 
						||
| 
								 | 
							
								5:	dec	r23     	;
							 | 
						||
| 
								 | 
							
									brne	5b		;/
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									in	r0, _SFR_IO_ADDR(SREG)	;Save flags
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									com	r24		;C = start bit
							 | 
						||
| 
								 | 
							
									ldi	r25, 10		;Bit counter
							 | 
						||
| 
								 | 
							
									cli			;Start critical section
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1:	ldi	r23, BPS-1	;----- Bit transferring loop
							 | 
						||
| 
								 | 
							
								2:	dec	r23     	;Wait for a bit time
							 | 
						||
| 
								 | 
							
									brne	2b		;/
							 | 
						||
| 
								 | 
							
									brcs	3f		;MISO = bit to be sent
							 | 
						||
| 
								 | 
							
									OUT_1			;
							 | 
						||
| 
								 | 
							
								3:	brcc	4f		;
							 | 
						||
| 
								 | 
							
									OUT_0			;/
							 | 
						||
| 
								 | 
							
								4:	lsr	r24     	;Get next bit into C
							 | 
						||
| 
								 | 
							
									dec	r25     	;All bits sent?
							 | 
						||
| 
								 | 
							
									brne	1b	     	;  no, coutinue
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									out	_SFR_IO_ADDR(SREG), r0	;End of critical section
							 | 
						||
| 
								 | 
							
									ret
							 | 
						||
| 
								 | 
							
								.endfunc
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;---------------------------------------------------------------------------;
							 | 
						||
| 
								 | 
							
								; Receive a byte
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								;Prototype: uint8_t rcvr (void);
							 | 
						||
| 
								 | 
							
								;Size: 19 words
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.global rcvr
							 | 
						||
| 
								 | 
							
								.func rcvr
							 | 
						||
| 
								 | 
							
								rcvr:
							 | 
						||
| 
								 | 
							
									in	r0, _SFR_IO_ADDR(SREG)	;Save flags
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									ldi	r24, 0x80	;Receiving shift reg
							 | 
						||
| 
								 | 
							
									cli			;Start critical section
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1:	SKIP_IN_1		;Wait for idle
							 | 
						||
| 
								 | 
							
									rjmp	1b
							 | 
						||
| 
								 | 
							
								2:	SKIP_IN_0		;Wait for start bit
							 | 
						||
| 
								 | 
							
									rjmp	2b
							 | 
						||
| 
								 | 
							
									ldi	r25, BPS/2	;Wait for half bit time
							 | 
						||
| 
								 | 
							
								3:	dec	r25
							 | 
						||
| 
								 | 
							
									brne	3b
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								4:	ldi	r25, BPS	;----- Bit receiving loop
							 | 
						||
| 
								 | 
							
								5:	dec	r25     	;Wait for a bit time
							 | 
						||
| 
								 | 
							
									brne	5b		;/
							 | 
						||
| 
								 | 
							
									lsr	r24     	;Next bit
							 | 
						||
| 
								 | 
							
									SKIP_IN_0		;Get a data bit into r24.7
							 | 
						||
| 
								 | 
							
									ori	r24, 0x80
							 | 
						||
| 
								 | 
							
									brcc	4b	     	;All bits received?  no, continue
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									out	_SFR_IO_ADDR(SREG), r0	;End of critical section
							 | 
						||
| 
								 | 
							
									ret
							 | 
						||
| 
								 | 
							
								.endfunc
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								; Not wait for start bit. This should be called after detecting start bit.
							 | 
						||
| 
								 | 
							
								.global recv
							 | 
						||
| 
								 | 
							
								.func recv
							 | 
						||
| 
								 | 
							
								recv:
							 | 
						||
| 
								 | 
							
									in	r0, _SFR_IO_ADDR(SREG)	;Save flags
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									ldi	r24, 0x80	;Receiving shift reg
							 | 
						||
| 
								 | 
							
									cli			;Start critical section
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								;1:	SKIP_IN_1		;Wait for idle
							 | 
						||
| 
								 | 
							
								;	rjmp	1b
							 | 
						||
| 
								 | 
							
								;2:	SKIP_IN_0		;Wait for start bit
							 | 
						||
| 
								 | 
							
								;	rjmp	2b
							 | 
						||
| 
								 | 
							
									ldi	r25, BPS/2	;Wait for half bit time
							 | 
						||
| 
								 | 
							
								3:	dec	r25
							 | 
						||
| 
								 | 
							
									brne	3b
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								4:	ldi	r25, BPS	;----- Bit receiving loop
							 | 
						||
| 
								 | 
							
								5:	dec	r25     	;Wait for a bit time
							 | 
						||
| 
								 | 
							
									brne	5b		;/
							 | 
						||
| 
								 | 
							
									lsr	r24     	;Next bit
							 | 
						||
| 
								 | 
							
									SKIP_IN_0		;Get a data bit into r24.7
							 | 
						||
| 
								 | 
							
									ori	r24, 0x80
							 | 
						||
| 
								 | 
							
									brcc	4b	     	;All bits received?  no, continue
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									ldi	r25, BPS/2	;Wait for half bit time
							 | 
						||
| 
								 | 
							
								6:	dec	r25
							 | 
						||
| 
								 | 
							
									brne	6b
							 | 
						||
| 
								 | 
							
								7:	SKIP_IN_1		;Wait for stop bit
							 | 
						||
| 
								 | 
							
									rjmp	7b
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									out	_SFR_IO_ADDR(SREG), r0	;End of critical section
							 | 
						||
| 
								 | 
							
									ret
							 | 
						||
| 
								 | 
							
								.endfunc
							 |