网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> DSP >> 代码示例 >> ADI DSP代码示例 >> Blackfin >> 文章正文
  UART RS-232 HyperTerminal (ASM)         ★★★ 【字体:
UART RS-232 HyperTerminal (ASM)
作者:61IC    文章来源:本站原创    点击数:    更新时间:2007-1-22    

/*****************************************************************************
**                   **
**  Name:  UART  Software Interface          ** 
**                   **
******************************************************************************

(C) Copyright 2006 - Analog Devices, Inc.  All rights reserved.

File Name:  uartlib.asm

Date Modified: 04/03/03  Rev 1.0

Software:       VisualDSP++ 4.5

Purpose:  This file contains some library functions
                commonly used on UART processing.    

******************************************************************************/


#include <defBF533.h>

.section L1_code;

///////// uart_autobaud //////////////////////////////////////////////////////

/*****************************************************************************
 *
 *  Assuming 8 data bits, this functions expects a '@' (ASCII 0x40) character
 *  on the UART RX pin.
 *  Timer 2 performs the autobaud detection. Also special support for
 *  half-duplex systems is provided.
 *
 *  Input parameters: none
 *  Return values: r0 holds timer period value (equals 8 bits)
 *  Assumptions: p0 contains UART_GCTL register address
 *
 ****************************************************************************/

.global uart_autobaud;
uart_autobaud:

 [--sp] = r2;
 [--sp] = p1;

/*****************************************************************************
 *
 *  First of all, enable UART clock. It is required for autobaud detection on
 *  silicon revision 0.0.
 *
 ****************************************************************************/
  
 r0 = UCEN (z);
 w[p0+UART_GCTL-UART_GCTL] = r0;
 

/*****************************************************************************
 *
 *  Activate Loopback mode in order the receive channel is disconnected
 *  from RX pin during autobaud detection.
 *
 ****************************************************************************/

  r0 = LOOP_ENA (z);
 w[p0+UART_MCR-UART_GCTL] = r0; 
  
   
/*****************************************************************************
 *
 *  Setup Timer 2 Controller to do the autobaud detection. Timer captures
 *  duration between two falling edges. It expects a '@' (ASCII 0x40)
 *  character. 8-bit, no parity assumed.
 *
 ****************************************************************************/

 p1.h = hi(TIMER_STATUS);
 p1.l = lo(TIMER_STATUS);

  
/*****************************************************************************
 *
 *  Disable Timer 2 first, in case there was an unexpected history. 
 *
 ****************************************************************************/

 r0 = TIMDIS2 (z);
 w[p1 + TIMER_DISABLE - TIMER_STATUS] = r0;
 
 r0 = TRUN2 | TOVL_ERR2 | TIMIL2 (z);
 w[p1 + TIMER_STATUS - TIMER_STATUS] = r0;

 
/*****************************************************************************
 *
 *  Capture from UART RxD pin. Select period capture from falling edge to
 *  falling edge. Enable IRQ_ENA, but don't enable the interrupt at system
 *  level (SIC).
 *
 ****************************************************************************/
   
  r0 = TIN_SEL | IRQ_ENA | PERIOD_CNT | WDTH_CAP (z);    
 w[p1 + TIMER2_CONFIG - TIMER_STATUS] = r0; 

 
/*****************************************************************************
 *
 *  Start the timer and wait until the according interrupt latch bit TIMIL2
 *  in the TIMER_STATUS register is set. Then, two falling edges on the RxD
 *  pin have been detected.
 *
 ****************************************************************************/
 
 r0 =  TIMEN2 (z);
 w[p1 + TIMER_ENABLE - TIMER_STATUS] = r0; 
 
wait_autobaud:
 r0 = w[p1 + TIMER_STATUS - TIMER_STATUS] (z);
 CC = bittst (r0, bitpos (TIMIL2) );
 if !CC jump wait_autobaud;
 

/*****************************************************************************
 *
 *  Disable Timer 2 again 
 *
 ****************************************************************************/

  r0 = TIMDIS2 (z);
 w[p1 + TIMER_DISABLE - TIMER_STATUS] = r0;

 r0 = TRUN2 | TOVL_ERR2 | TIMIL2 (z);
 w[p1 + TIMER_STATUS - TIMER_STATUS] = r0;
 
     
/*****************************************************************************
 *
 *  Save period value to R2
 *
 ****************************************************************************/

  r2 = [p1 + TIMER2_PERIOD - TIMER_STATUS];
 
   
/*****************************************************************************
 *
 *  In order to support also half-duplex connections, we need to delay any
 *  transmission, in order the sent character does not overlap the autobaud
 *  pattern.
 *
 *  Use Timer 2 to perform this delay. Note that the Period Register still
 *  contains the proper value and the Width Register is not used.
 *
 ****************************************************************************/ 
 
  r0 = OUT_DIS | IRQ_ENA | PERIOD_CNT | PWM_OUT (z);    
 w[p1 + TIMER2_CONFIG - TIMER_STATUS] = r0; 
 
 r0 =  TIMEN2 (z);
 w[p1 + TIMER_ENABLE - TIMER_STATUS] = r0; 
 
wait_delay:
 r0 = w[p1 + TIMER_STATUS - TIMER_STATUS] (z);
 CC = bittst (r0, bitpos (TIMIL2) );
 if !CC jump wait_delay;

/*****************************************************************************
 *
 *  Disable Timer 2 again 
 *
 ****************************************************************************/

  r0 = TIMDIS2 (z);
 w[p1 + TIMER_DISABLE - TIMER_STATUS] = r0;

 r0 = TRUN2 | TOVL_ERR2 | TIMIL2 (z);
 w[p1 + TIMER_STATUS - TIMER_STATUS] = r0; 
  
 
/*****************************************************************************
 *
 *  Deactive Loopback mode again
 *
 ****************************************************************************/  
  
 r0 = 0 (z);
 w[p0+UART_MCR-UART_GCTL] = r0; 

 
/*****************************************************************************
 *
 *  done !
 *
 ****************************************************************************/  
  
  r0 = r2;
  
 p1 = [sp++];
 r2 = [sp++];  
 
 rts;

uart_autobaud.end:


///////// uart_init //////////////////////////////////////////////////////////

/*****************************************************************************
 *
 *  Configures UART in 8 data bits, no parity, 1 stop bit mode.
 *
 *  Input parameters: r0 holds divisor latch value to be written into
 *                    DLH:DLL registers.
 *  Return values:    none
 *  Assumptions:      p0 contains UART_GCTL register address
 *
 ****************************************************************************/

.global uart_init;
uart_init:

 [--sp] = r1;

/*****************************************************************************
 *
 *  First of all, enable UART clock.
 *
 ****************************************************************************/
  
 r1 = UCEN (z);
 w[p0+UART_GCTL-UART_GCTL] = r1;

 
/*****************************************************************************
 *
 *  Read period value and apply formula:  DL = PERIOD / 16 / 8
 *  Write result to the two 8-bit DL registers (DLH:DLL).
 *
 ****************************************************************************/

  r1 = DLAB (z);
 w[p0+UART_LCR-UART_GCTL] = r1;
  
 w[p0+UART_DLL-UART_GCTL] = r0;
 
 r1 = r0 >> 8;
 w[p0+UART_DLH-UART_GCTL] = r1;
 

/*****************************************************************************
 *
 *  Clear DLAB again and set UART frame to 8 bits, no parity, 1 stop bit.
 *  This may differ in other scenarious.
 *
 ****************************************************************************/
 
 r1 = WLS(8) (z);
 w[p0+UART_LCR-UART_GCTL] = r1; 

 r1 = [sp++];
 
 rts;

uart_init.end:

 

 

 

///////// uart_wait4temt /////////////////////////////////////////////////////

/*****************************************************************************
 *
 * This function polls the TEMT bit in the LSR register and waits until
 *  all data has been shifted out.
 *
 *  Input parameters: none
 *  Return values: none
 *  Assumptions: p0 contains UART_GCTL register address
 *
 ****************************************************************************/

.global uart_wait4temt;
uart_wait4temt:
 [--sp] = r1;
 
temt_wait: 
 r1 = w[p0+UART_LSR-UART_GCTL] (z);
 CC = bittst(r1,bitpos(TEMT));
 if !CC jump temt_wait;   
 
 r1 = [sp++];
 
 nop;
 nop;
  
 ssync;  
 rts;

uart_wait4temt.end: 
  
 
///////// uart_disble ////////////////////////////////////////////////////////

/*****************************************************************************
 *
 * This function disables the UART clock, but polls the TEMT bit before
 *
 *  Input parameters: none
 *  Return values: none
 *  Assumptions: p0 contains UART_GCTL register address
 *
 ****************************************************************************/

.global uart_disable;
uart_disable:
 [--sp] = r0;
 [--sp] = rets;
 
 call uart_wait4temt;
  
  r0 = 0 (z);
 w[p0+UART_GCTL-UART_GCTL] = r0;

 rets = [sp++];  
 r0 = [sp++];  
 
 rts;

uart_disable.end: 

 

 

///////// uart_putc //////////////////////////////////////////////////////////

/*****************************************************************************
 *
 * This function transmits a character by polling THRE bit in the LSR
 *  register.
 *
 *  Input parameters: r0 holds the character to transmit
 *  Return values: none
 *  Assumptions: p0 contains UART_GCTL register address
 *
 ****************************************************************************/

.global uart_putc;
uart_putc:
 [--sp] = r1; 
  
putc_wait:  
 r1 = w[p0+UART_LSR-UART_GCTL] (z);
 CC = bittst(r1,bitpos(THRE));
 if !CC jump putc_wait;  
  
 w[p0+UART_THR-UART_GCTL] = r0;  
 
 r1 = [sp++];

 rts;

uart_putc.end: 


///////// uart_puts //////////////////////////////////////////////////////////

/*****************************************************************************
 *
 * This function transmits a byte string by polling THRE bit in the LSR
 *  register. The string must be NULL-terminated (C-style).
 *
 *  Input parameters: p1 holds the start address of the string to transmit
 *  Return values: none
 *  Assumptions: p0 contains UART_GCTL register address
 *
 ****************************************************************************/
  
.global uart_puts; 
uart_puts:
 [--sp] = rets;
 [--sp] = r0;
 
puts_loop:
 r0 = b[p1++] (z);
 CC = r0 == 0;
 if CC jump puts_end;  
 call uart_putc;
 jump puts_loop;    

puts_end:
 r0 = [sp++];
 rets = [sp++];  
 rts;

uart_puts.end: 
       

///////// uart_putreg ////////////////////////////////////////////////////////

/*****************************************************************************
 *
 * This function transmits the content of the r0 register in hexdecimal
 *  representation. This is based on polling operation.
 *
 *  Input parameters: r0 holds hex value
 *  Return values: none
 *  Assumptions: p0 contains UART_GCTL register address
 *
 ****************************************************************************/

.global uart_putreg;
uart_putreg:
 [--sp] = rets;
 [--sp] = (r7:1, p5:5);
 r1 = r0;

 r0 = 0x20; // ' '
 call uart_putc;
 r0 = 0x30; // '0'
 call uart_putc;
 r0 = 0x78; // 'x'
 call uart_putc;
 
 r2 = 0x0400;
 r3 = 0x0030;
 [--sp] = r3; 
 r4 = 0x0037;
 r5 = 9;
 r6 = 0x1C04;
  
 p5 = 8;  
 lsetup (putreg_lbegin, putreg_lend) lc0=p5;
 
putreg_lbegin: 
  r0 = extract(r1,r6.l)(z) || r3 = [sp]; // Read next nibble 
  CC = r0 <= r5;
  if !CC r3 = r4;  // 0..9 or A..F
  r0 = r0 + r3;   // Make ASCII
  call uart_putc;  
putreg_lend:
  r6 = r6 - r2;   // next nibble position
  
 sp+= 4;
 (r7:1, p5:5) = [sp++];
 rets = [sp++];   
 rts;
 
uart_putreg.end:

               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    本程序是BF533 DSP的串口通讯…
    开发环境为Vsual DSP++3.0的…
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号