📄 uart_driver.asm
字号:
/* 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 + -