Jump to content
43oh

High bit rate async serial ("RS-232") software tx


Recommended Posts

Here is some code that can tx at 115.2 kbps while running at only 1 MHz clock. This can be useful for "printf debugging" with minimal impact on code speed.

 

The bit time of 115.2 kbps is aprox 8.68 us. The timing granularity at 1 MHz is only 1 us, so dithering is used to maintain correct average bit time. Most UART look at the middle of the bit, so this generally works well. The jitter is under 500 ns as shown in the following table.

 

;	 Bit	Exact	Int	  Delta	 Error
;	----------------------------------
;	Start	 0.00	 0		-	  -
;	0		 8.68	 9		9	+0.32
;	1		17.36	17		8	-0.36
;	2		26.04	26		9	-0.04
;	3		34.72	35		9	+0.28
;	4		43.40	43		8	-0.40
;	5		52.08	52		9	-0.08
;	6		60.77	61		9	+0.23
;	7		69.44	69		8	-0.44
;	Stop	78.13	78		9	-0.13

 

This is the code to send one bit...

 

bN	 rrc	  R14						    Move the next bit to send in to the carry flag, shift all others
	jc		bNh				 --+		Test the carry flag and jump if one
	bic.b   R15, &P1OUT		 |		The carry flag was zero, so put a zero on the serial output
	jmp		nxb				--|--+	Jump to the next bit
bNh	bis.b   R15, &P1OUT	  <-+  |	The carry flag was one, so put a one on the serial output
	jmp		nxb				-----+	Jump to the next bit - this jump is required to keep the
							 	       |	  code path for the bit isochronous
nxb	next bit				    <----+

 

9 cycles are required for each bit using that code, so something must be done for the 3 bits that must be sent in 8 cycles.

The last jmp can be replace with a nop to reduce the cycle count when a one is sent. To reduce the cycle count when a zero is sent, the second jump is also replaced with a nop and part of the code for the next bit is copied to directly after the nop.

 

This is the code for sending a byte...

                                       ; Data to tx is in R14
           mov     #0x02, R15          ; Setup serial output bitmask in R15
                                       ;
                                       ; Start bit
           bic.b   R15, &P1OUT         ;  0
           jmp     bit0                ;
                                       ;
bit0        rrc     R14                 ; Bit 0
           jc      bit0h               ;
           bic.b   R15, &P1OUT         ;  9
           nop                         ;
           rrc     R14                 ; Bit 1
           jc      bit1h               ;
           bic.b   R15, &P1OUT         ; 17
           jmp     bit2                ;
bit0h       bis.b   R15, &P1OUT         ;  9
           nop                         ;
                                       ;
bit1        rrc     R14                 ; Bit 1
           jc      bit1h               ;
           bic.b   R15, &P1OUT         ; 17
           jmp     bit2                ;
bit1h       bis.b   R15, &P1OUT         ; 17
           jmp     bit2                ;
                                       ;
bit2        rrc     R14                 ; Bit 2
           jc      bit2h               ;
           bic.b   R15, &P1OUT         ; 26
           jmp     bit3                ;
bit2h       bis.b   R15, &P1OUT         ; 26
           jmp     bit3                ;
                                       ;
bit3        rrc     R14                 ; Bit 3
           jc      bit3h               ;
           bic.b   R15, &P1OUT         ; 35
           nop                         ;
           rrc     R14                 ; Bit 4
           jc      bit4h               ;
           bic.b   R15, &P1OUT         ; 43    
           jmp     bit5                ;
bit3h       bis.b   R15, &P1OUT         ; 35
           nop                         ;
                                       ;
bit4        rrc     R14                 ; Bit 4
           jc      bit4h               ;
           bic.b   R15, &P1OUT         ; 43    
           jmp     bit5                ;
bit4h       bis.b   R15, &P1OUT         ; 43
           jmp     bit5                ;
                                       ;
bit5        rrc     R14                 ; Bit 5
           jc      bit5h               ;
           bic.b   R15, &P1OUT         ; 52
           jmp     bit6                ;
bit5h       bis.b   R15, &P1OUT         ; 52
           jmp     bit6                ;
                                       ;
bit6        rrc     R14                 ; Bit 6
           jc      bit6h               ;
           bic.b   R15, &P1OUT         ; 61
           nop                         ;
           rrc     R14                 ; Bit 7
           jc      bit7h               ;
           bic.b   R15, &P1OUT         ; 69
           jmp     bitstop             ;
bit6h       bis.b   R15, &P1OUT         ; 61
           nop                         ;
                                       ;
bit7        rrc     R14                 ; Bit 7
           jc      bit7h               ;
           bic.b   R15, &P1OUT         ; 69
           jmp     bitstop             ;
bit7h       bis.b   R15, &P1OUT         ; 69
           jmp     bitstop             ;
                                       ;
bitstop     nop                         ; Stop Bit
           jmp     $ + 2               ;
           bis.b   R15, &P1OUT         ; 78

Link to post
Share on other sites

Inline asm version

 

void tx(unsigned c)
{
   __asm(" mov     0(SP), R14");   // Get the char passed on the stack to R14
                                   //
   __asm(" mov     #0x02, R15");   // Setup bitmask in R15
                                   //
   __asm(" bic.b   R15, &P1OUT");  //  0 Start bit
   __asm(" jmp     $ + 2");        //
                                   //
   __asm(" rrc     R14");          // Bit 0
   __asm(" jc      $ + 18");       //
   __asm(" bic.b   R15, &P1OUT");  //  9
   __asm(" nop");                  //
   __asm(" rrc     R14");          // Bit 1
   __asm(" jc      $ + 24");       //
   __asm(" bic.b   R15, &P1OUT");  // 17
   __asm(" jmp     $ + 24");       //
   __asm(" bis.b   R15, &P1OUT");  //  9
   __asm(" nop");                  //
                                   //
   __asm(" rrc     R14");          // Bit 1
   __asm(" jc      $ + 8");        //
   __asm(" bic.b   R15, &P1OUT");  // 17
   __asm(" jmp     $ + 8");        //
   __asm(" bis.b   R15, &P1OUT");  // 17
   __asm(" jmp     $ + 2");        //
                                   //
   __asm(" rrc     R14");          // Bit 2
   __asm(" jc      $ + 8");        //
   __asm(" bic.b   R15, &P1OUT");  // 26
   __asm(" jmp     $ + 8");        //
   __asm(" bis.b   R15, &P1OUT");  // 26
   __asm(" jmp     $ + 2");        //
                                   //
   __asm(" rrc     R14");          // Bit 3
   __asm(" jc      $ + 18");       //
   __asm(" bic.b   R15, &P1OUT");  // 35
   __asm(" nop");                  //
   __asm(" rrc     R14");          // Bit 4
   __asm(" jc      $ + 24");       //
   __asm(" bic.b   R15, &P1OUT");  // 43   
   __asm(" jmp     $ + 24");       //
   __asm(" bis.b   R15, &P1OUT");  // 35
   __asm(" nop");                  //
                                   //
   __asm(" rrc     R14");          // Bit 4
   __asm(" jc      $ + 8");        //
   __asm(" bic.b   R15, &P1OUT");  // 43   
   __asm(" jmp     $ + 8");        //
   __asm(" bis.b   R15, &P1OUT");  // 43
   __asm(" jmp     $ + 2");        //
                                   //
   __asm(" rrc     R14");          // Bit 5
   __asm(" jc      $ + 8");        //
   __asm(" bic.b   R15, &P1OUT");  // 52
   __asm(" jmp     $ + 8");        //
   __asm(" bis.b   R15, &P1OUT");  // 52
   __asm(" jmp     $ + 2");        //
                                   //
   __asm(" rrc     R14");          // Bit 6
   __asm(" jc      $ + 18");       //
   __asm(" bic.b   R15, &P1OUT");  // 61
   __asm(" nop");                  //
   __asm(" rrc     R14");          // Bit 7
   __asm(" jc      $ + 24");       //
   __asm(" bic.b   R15, &P1OUT");  // 69
   __asm(" jmp     $ + 24");       //
   __asm(" bis.b   R15, &P1OUT");  // 61
   __asm(" nop");                  //
                                   //
   __asm(" rrc     R14");          // Bit 7
   __asm(" jc      $ + 8");        //
   __asm(" bic.b   R15, &P1OUT");  // 69
   __asm(" jmp     $ + 8");        //
   __asm(" bis.b   R15, &P1OUT");  // 69
   __asm(" jmp     $ + 2");        //
                                   //
   __asm(" nop");                  // Stop Bit
   __asm(" jmp     $ + 2");        //
   __asm(" bis.b   R15, &P1OUT");  // 78
}

Link to post
Share on other sites

Discussion in this thread has lead me to a smaller version of the code.

 

This is smaller, but takes a few more cycles overall.

putc        or      #0x0100, R12        ; Stop bit
           mov     #0x02, R15          ; Serial out bitmask
           jmp     bit_start           ;
                                       ;
bit0        rra     R12                 ; Bit 0/3/6
           jc      bit0h               ;
           bic.b   R15, &P1OUT         ;  9/35/61
           nop                         ;
           rra     R12                 ; Bit 1/4/7
           jc      bit1h               ;
           bic.b   R15, &P1OUT         ; 17/43/69
           jmp     bit2                ;
bit0h       bis.b   R15, &P1OUT         ;  9/35/61
           nop                         ;
                                       ;
bit1        rra     R12                 ; Bit 1/4/7
           jc      bit1h               ;
           bic.b   R15, &P1OUT         ; 17/43/69
           jmp     bit2                ;
bit1h       bis.b   R15, &P1OUT         ; 17/43/69
           jmp     bit2                ;
                                       ;
bit2        rra     R12                 ; Bit Start/2/5/Stop
           jc      bit2h               ;
bit_start   bic.b   R15, &P1OUT         ; 0/26/52
           jmp     bit0                ;
bit2h       bis.b   R15, &P1OUT         ; 26/52/78
           jne     bit0                ;
           ret

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...