⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart_driver.asm

📁 一段ADSP21262用DAI口实现UART通讯的汇编源代码。
💻 ASM
📖 第 1 页 / 共 2 页
字号:
/* UART_Driver.asm */
#include <def21262.h>
#include <asm_sprt.h>
#include "UART_Driver.h"
#define TX_BUFFER_EMPTY	0
#define TX_BUFFER_NOT_EMPTY 1
#define TX_BUFFER_OVERFLOW 0xff
#define ASM
	.section /dm seg_dmda;
	.var UART_i3_store;
	.var UART_Transmit_Buffer_Read_Ptr=0;
	.var UART_Transmit_Buffer_Write_Ptr=0;
	.var UART_Transmit_Buffer[UART_TX_BUFFER_LEN];
	.var _UART_Error = 0;
	.var _UART_TX_EMPTY;
#ifdef ASM
	.var _RX_Buffer[256];/*
						=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
						 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;
						  */
	.global _RX_Buffer;
	.var _Rx_Indx;
#endif
	.global _UART_Error;
	//.global UART_Transmit_Buffer;
	//.global UART_Transmit_Buffer_Read_Ptr;
	//.global UART_Transmit_Buffer_Write_Ptr;
/***************************************************************************************
Setup_UART
	Input:
	r4 = DSP operating frequency
	r8 = desired BAUD rate
	Output:
	f0 = divisor error. this is the fractional portion resulting from the truncation
	to fixed point of the sport clock divisor
	C Prototype:
	int Setup_UART( int DSP_Frequency, int BAUD );
****************************************************************************************/
	.section /pm seg_pmco;
_Setup_UART:
	.global _Setup_UART;
#ifndef ASM
 //   modify(i7,-2);
#endif
	r0=0x00000000; // initially clear SPORT control register
	dm(SPCTL1)=r0; // tx on sport 1
	dm(SPCTL3)=r0; // rx on sport 3
	dm(SPMCTL01)=r0;//zzx append for Multichannel Mode
	dm(SPMCTL23)=r0;//zzx
	dm(UART_Transmit_Buffer_Write_Ptr)=r0;
	dm(UART_Transmit_Buffer_Read_Ptr)=r0;
	dm(_UART_TX_EMPTY)=r0;
	dm(SPMCTL23) = r0;
	
	
	// Setup SPORT1 - Transmit
	/* r0=  SPTRAN   //发送       bit25
		  | BHD    //禁止系统挂起 bit23
	      | LAFS	//迟到的同步祯bit17  Late (vs early) frame sync FSx
	      | LFS     //同步祯信号低bit16
	      | IFS     //内部产生同步bit14
	      | FSR     //同步信号有效bit13
	      | ICLK    //内部时钟    bit10
	      | SLEN11  //11比特长度  bit4-8
	      | LSBF   //低字节在先   bit03
	      | SPEN_A;//使用数据信道Abit00                       */
	r0=SPTRAN | LAFS | LFS | IFS | FSR | ICLK | SLEN11 | LSBF | SPEN_A;   
	dm(SPCTL1) = r0;
	
	
	
	
	// Setup SPORT3 - Receive
	/*
	r0=		  BHD   //禁止系统挂起 bit23
			| SPEN_B//使用数据信道Bbit20  
			| LAFS  //迟到的同步祯bit17
			| LFS   //同步祯信号低有效bit16
			| FSR   //同步信号有效bit13
			| ICLK  //内部时钟    bit10
			| SLEN29//29比特长度  bit4-8
			| CKRE; //同步信号上升沿有效 bit12
	 */
	r0= BHD | LAFS | LFS | FSR | ICLK | SLEN29 | SPEN_B | CKRE;
	
	dm(SPCTL3) = r0;//ustat1;
	// Calculate divisors based on DSP clock frequency and BAUD rate

/*  I guess maybe I was work in 200M
	Baut Rate =115200
	SysClock =400M (fcclk)
	TransBitLen =11
	Frame Rate = 115200(fsclk)
	
	CLKDEV1=200000000/(115200*2)-1=0x363
	FEDEV1=0xa
	Div1=0x0a0363;
	CHKDEV3=200000000/(115200*3*2)-1=0x120
	DEDEV3=0x1d
	Div3=0x01d0120
	
	
	
	Baut Rate 9600
	CLKDEV1=200000000/(9600*2)-1=28af
	dev1=0x0a28af
	CLKDEV2=200000000/(9600*3*2)-1=d8f
	dev2=0x01d0d8f;
 */
	R2=0x0a0363;

	dm(DIV1) = R2;
	// Setup Receive
	// To enable MIDI RX with UART transmit, hardwire RX clock to 115200*3

	R4 = 0x01c0120;

	dm(DIV3) = R4;
	
#ifndef ASM
	// UART Transmit
	r0 = _UartTx_Service;
	r1 = lshift r0 by 16;
	px1 = r1;
	r1 = b#000001100011111;
	r0 = lshift r0 by -16;
	r1 = lshift r1 by 17;
	r1 = r1 OR r0;
	px2 = r1;
	pm(0x80038) = px;
	px2 = 0x0b3e0000;
	px1 = 0;
	pm(0x80039) = px;
	pm(0x8003a) = px;
	// UART Receiver
	r0 = _UART_RX_ISR;
	r1 = lshift r0 by 16;
	px1 = r1;
	r1 = b#000001100011111;
	r0 = lshift r0 by -16;
	r1 = lshift r1 by 17;
	r1 = r1 OR r0;
	px2 = r1;
	pm(0x8003d) = px;
#endif	
	
	
	
	
	// setup SPORT1 and SPORT3 ISRs
	// UART Transmit at SP1A
	// Receiver at SP3B
	bit set imask SP1I | SP3I;
	bit set mode1 IRPTEN ;
    r0 = 0;
#ifdef ASM
	rts;
#else
	leaf_exit;
#endif
_Setup_UART.end:


//*********************************************************************
/***************************************************************************************
UartTX_Service
Description:
This function handles the TX interrupt and moving data from the UART_Transmit_Buffer
out to the serial port. This function should be placed in the SPORT 1 ISR.
****************************************************************************************/


	.section /pm seg_pmco;
_UartTx_Service:
	.global _UartTx_Service;
	
	push sts;
	// * BACKUP VARIABLES
	puts = r0;
	puts = r1;

	// * END BACKUP VARIABLES
	r0 = dm(UART_Transmit_Buffer_Read_Ptr);
	r1 = dm(UART_Transmit_Buffer_Write_Ptr);
	comp(r0,r1);
	if eq jump UART_Nothing_To_Transmit;
	// BACKUP MORE VARIABLES
	r1 = i4; puts = r1;
	r1 = m4; puts = r1;
	puts = r4;
	i4 = UART_Transmit_Buffer;
	m4 = dm(UART_Transmit_Buffer_Read_Ptr);
	r4 = dm(m4,i4);
	// increment pointer
	r0 = m4; r0 = r0 + 1;
	// See if pointer has wrapped
	r1 = UART_TX_BUFFER_LEN;
	
	comp(r1,r0);
	if EQ r0 =r0 - r1;
	dm(UART_Transmit_Buffer_Read_Ptr) = r0;
	dm(TXSP1A) = r4;
	// * RESTORE VARIABLES
	r4 = gets(1);
	r1 = gets(2); m4 = r1;
	r1 = gets(3); i4 = r1;
	r1 = gets(4);
	r0 = gets(5);
#ifndef ASM
	alter(5);
#endif
	pop sts;
	rti;
// * END RESTORE VARIABLES
// If there is nothing more to transmit, disable the transmit interrupt
UART_Nothing_To_Transmit:
	r0=0;
	dm(UART_Transmit_Buffer_Read_Ptr)=r0;
	dm(UART_Transmit_Buffer_Write_Ptr)=r0;
	r0=TX_BUFFER_OVERFLOW;
	dm(_UART_Error)=r0;
	r0=TX_BUFFER_EMPTY;
	dm(_UART_TX_EMPTY)=r0;
	bit clr IMASK SP1I;
	// * RESTORE VARIABLES
	r1 = gets(1);
	r0 = gets(2);
#ifndef ASM
	alter(2);
#endif
	pop sts;
	rti;
	// * END RESTORE VARIABLES
_UartTx_Service.end:
/***************************************************************************************
Uart_TX_Word
Description:
This function writes a value to the SPORT1 transmit register. It first takes
the 8-bit value and creates a 30-bit value for transmitting.
void TX_Word(char);
****************************************************************************************/
	.section /pm seg_pmco;
_UartTx_Word:
	r0 = r4;
	r2 = b#01111111100;
	r4 = b#10000000001;
	r1 = lshift r0 by 2;
	r1 = r1 and r2;
	r1 = r1 OR r4;
	r0 = dm(UART_Transmit_Buffer_Read_Ptr);
	r2 = dm(UART_Transmit_Buffer_Write_Ptr);
	r0 = r0 - 1;
	comp(r0,r2);
	if eq jump UART_TX_Full;	
	i4 = UART_Transmit_Buffer;
	m4 = dm(UART_Transmit_Buffer_Write_Ptr);
	dm(m4,i4) = r1;
	// increment pointer
	r0 = m4; r0 = r0 + 1;
	// See if pointer has wrapped
	r1 = UART_TX_BUFFER_LEN;

	comp(r1,r0);
	if EQ r0 = r0 - r1;
	dm(UART_Transmit_Buffer_Write_Ptr) = r0;
	// if the transmit interrupt had been disabled, re-enable it to transmit this new data
	bit clr IRPTL SP1I;
	bit set IMASK SP1I;
#ifdef ASM
	rts;
#else
	leaf_exit;
#endif
_UartTx_Word.end:
	.global _UartTx_Word;
	.type _UartTx_Word,STT_FUNC;
/***************************************************************************************
UartTx_Buffer
Description:
This function writes a buffer of data to the SPORT1 transmit register. It first takes
the 8-bit value and creates an 11-bit value for transmitting.
  void UartTx_Buffer(char *buf,int buflenth);
****************************************************************************************/

	.section /pm seg_pmco;
_UartTx_Buffer:
	.global _UartTx_Buffer;
    
	i4 = r4;
	LCNTR = r8, do (PC,UART_Transmit_Loop-1) until LCE;
	r4=dm(i4,m6);
	r0 = r4;
	r2 = b#01111111100; // binary 111 (a 'one' at 3 x baud rate)
	r4 = b#10000000001;
	r1 = lshift r0 by 2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -