www.pudn.com > Adsp21262forUart.rar > UART_Driver.asm
/* UART_Driver.asm */ #include#include #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; 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 (la); dm(UART_i3_store) = i3; i3 = UART_Transmit_Buffer; m4 = dm(UART_Transmit_Buffer_Write_Ptr); dm(m4,i3) = r1; i3 = dm(UART_i3_store); // 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; UART_Transmit_Loop: // 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 UART_TX_Full: r0 = TX_BUFFER_OVERFLOW; dm(_UART_Error) = r0; bit set imask SFT3I; // raise software interrupt 3 when UART error detected. bit clr IRPTL SP1I; bit set IMASK SP1I; #ifdef ASM rts; #else leaf_exit; #endif _UartTx_Buffer.end: .global _UartTx_Buffer; .type _UartTx_Buffer,STT_FUNC; /*************************************************************************************** Uart_Rx Description: Once a SPORT3 receive interrupt occurs, this function should be called (from C) to retrieve the and interpret the value. This routine captures the input from RX3A, a derives the 8-bit value. int UartRx();This is internal call by receive interrupt subroutine. ****************************************************************************************/ .section /pm seg_pmco; _UartRx: // receive in a 30 bit transmission, generate rx interrupt // start bit triggers frame sync (rfs and dr tied together r0 = dm(RXSP3B); r4 = fext r0 by 25:1; // bit 0 r1 = fext r0 by 22:1; // bit 1 r4 = r4 or fdep r1 by 1:1; r1 = fext r0 by 19:1; // bit 2 r4 = r4 or fdep r1 by 2:1; r1 = fext r0 by 16:1; // bit 3 r4 = r4 or fdep r1 by 3:1; r1 = fext r0 by 13:1; // bit 4 r4 = r4 or fdep r1 by 4:1; r1 = fext r0 by 10:1; // bit 5 r4 = r4 or fdep r1 by 5:1; r1 = fext r0 by 7:1; // bit 6 r4 = r4 or fdep r1 by 6:1; r1 = fext r0 by 4:1; // bit 7 r4 = r4 or fdep r1 by 7:1; // r4 contains received word r0 = r4; #ifdef ASM rts; #else leaf_exit; #endif _UartRx.end: .global _UartRx; .type _UartRx,STT_FUNC; #ifdef ASM _UART_RX_ISR: push sts; // * BACKUP VARIABLES puts = r0; puts = r1; puts= r2; puts = r4; r4 = i4;puts = r4; r4 = m4;puts = r4; call _UartRx; call _UartTx_Word; // * RESTORE VARIABLES r4 = gets(1);m4=r4; r4 = gets(2);i4=r4; r4 = gets(3); r2 = gets(4); r1 = gets(5); r0 = gets(6); pop sts; rti; //zzx append for interrupt break return! Note:it use "rti" command to return _UART_RX_ISR.end: .global _UART_RX_ISR; #else .extern _UART_RX_ISR; #endif _IntErr: jump (pc,0); _IntErr.end: .extern _main; /***************************************************************** IRPTL 0 0x00 EMUI Emulator (read-only,non-maskable); HIGHEST PRIORITY IRPTL 1 0x04 RSTI Reset (read-only, non-maskable) IRPTL 2 0x08 IICDI Illegal Input Condition Detected IRPTL 3 0x0C SOVFI Status loop or mode stack overflow; or PC stack full IRPTL 4 0x10 TMZHI Timer = 0 (high priority option) IRPTL 5 0x14 Reserved IRPTL 6 0x18 BKPI Hardware Breakpoint Interrupt IRPTL 7 0x1C Reserved IRPTL 8 0x20 IRQ2I IRQ2I_ is asserted IRPTL 9 0x24 IRQ1I IRQ1I_ is asserted IRPTL 10 0x28 IRQ0I IRQ0I_ is asserted IRPTL 11 0x2C DAIHI DAI High Priority Interrupt IRPTL 12 0x30 SPIHI SPI Transmit or Receive (higher priority option) IRPTL 13 0x34 GPTMR0I General-purpose IOP Timer 0 Interrupt IRPTL 14 0x38 SP1I SPORT1 Interrupt IRPTL 15 0x3C SP3I SPORT3 Interrupt IRPTL 16 0x40 SP5I SPORT5 Interrupt LIRPTL 0 0x44 SP0I SPORT0 Interrupt LIRPTL 1 0x48 SP2I SPORT2 Interrupt LIRPTL 2 0x4C SP4I SPORT4 Interrupt LIRPTL 3 0x50 PPI Parallel Port Interrupt LIRPTL 4 0x54 GPTMR1I General-purpose IOP Timer 1 Interrupt LIRPTL 5 0x58 -- Reserved LIRPTL 6 0x5C DAILI DAI Low Priority Interrupt LIRPTL 7 0x60 -- Reserved IRPTL 17, 18, 19 0x64-0x6F -- Reserved LIRPTL 8 0x70 GPTMR2I General-purpose IOP Timer 2 Interrupt LIRPTL 9 0X74 SPILI SPI Transmit or Receive (lower priority option) IRPTL 20 0x78 CB7I Circular Buffer 7 Overflow IRPTL 21 0x7C CB15I Circular Buffer 15 Overflow IRPTL 22 0x80 TMZLI Timer=0(Low Priority Option) IRPTL 23 0x84 FIXI Fixed-point Overflow IRPTL 24 0x88 FLTOI Floating-point Overflow Exception IRPTL 25 0x8C FLTUI Floating-point Underflow Exception IRPTL 26 0x90 FLTII Floating-point invalid exception IRPTL 27 0x94 EMULI Emulator Low Priority Interrupt IRPTL 28 0x98 SFT0I User Software Interrupt 0 IRPTL 29 0x9C SFT1I User Software Interrupt 1 IRPTL 30 0xA0 SFT2I User Software Interrupt 2 IRPTL 31 0xA4 SFT3I User Software Interrupt 3; LOWEST PRIORITY *****************************************************************/ .extern InitSRU ; /* .section/pm seg_rth; //EMUI: nop;nop;nop;nop; //00 //RSTI: nop;jump _main;nop;nop; //04 */ #ifdef ASM #define SIZE 0xa0; .section/pm seg_rth; //EMUI: nop;nop;nop;nop; //00 //RSTI: nop;jump _main;nop;nop; //04 nop;nop;nop;nop; //08 //SOVFI: nop;nop;nop;nop; //0c //TMZHI: nop;nop;nop;nop; //10 nop;nop;nop;nop; //14 //BKPI: nop;nop;nop;nop; //18 nop;nop;nop;nop; //1c //IRQ2I: nop;nop;nop;nop; //20 //IRQ1I: nop;nop;nop;nop; //24 //IRQ0I: nop;nop;nop;jump _IntErr; //28 //DAIHI: jump _IntErr;nop;nop;nop;//2c // I have set the interrupt point to the funcion //_UartRx_ISR,The most importtant interrupt!! //SPIHI: nop;nop;nop;nop;//30 //GPTMR0I: nop;nop;nop;jump _IntErr;//34; //SP1I: jump _UartTx_Service;nop;nop;nop;//38 //SP3I: #ifdef ASM jump _UART_RX_ISR; #else nop; #endif nop;nop;nop;//3c //SP5I: nop;nop;nop;nop;//40 //SP0I: nop;nop;nop;nop;//44 //SP2I: nop;nop;nop;nop;//48 //SP4I: nop;nop;nop;nop;//4c //PPI: nop;nop;nop;nop;//50 //GPTMR1I: nop;nop;nop;nop;//54 nop;nop;nop;nop;//58 //DAILI: nop;nop;nop;nop;//5c nop;nop;nop;nop;//60 nop;nop;nop;nop;//64 nop;nop;nop;nop;//68 nop;nop;nop;nop;//6c //GPTMR2I: nop;nop;nop;nop;//70 //SPILI_SPI: nop;nop;nop;nop;//74 //CB7I: nop;nop;nop;nop;//78 //CB15I: nop;nop;nop;nop;//7c //TMZLI: nop;nop;nop;nop;//80 //FIXI: nop;nop;nop;nop;//84 //FLTOI: nop;nop;nop;nop;//88 //FLTUI: nop;nop;nop;nop;//8c //FLTII: nop;nop;nop;nop;//90 //EMULI: nop;nop;nop;nop;//94 //SFT0I: nop;nop;nop;nop;//98 //SFT1I: nop;nop;nop;nop;//9c //SFT2I: nop;nop;nop;nop;//a0 //SFT3I: nop;nop;nop;nop;//a4 nop;nop;nop;nop;//a8 nop;nop;nop;nop;//ac nop;nop;nop;nop;//b0 nop;nop;nop;nop;//b4 nop;nop;nop;nop;//b8 nop;nop;nop;nop;//bc nop;nop;nop;nop;//c0 nop;nop;nop;nop;//c0-c7 nop;nop;nop;nop; nop;nop;nop;nop;//c8-cf nop;nop;nop;nop; nop;nop;nop;nop;//d0-d7 nop;nop;nop;nop; nop;nop;nop;nop;//d8-df nop;nop;nop;nop; nop;nop;nop;nop;//e0-e7 nop;nop;nop;nop; nop;nop;nop;nop;//e8-ef nop;nop;nop;nop; nop;nop;nop;nop;//f0-f7 nop;nop;nop;nop; nop;nop;nop;jump _IntErr;//f8-ff #endif #if 0 r0=dm(TxCount); r0=r0+1; r1=200; comp(r1,r0); if GT Jump Utxcont1; 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(TxCount)=r0; r0=BHD|SPTRAN | LSBF | LAFS | LFS | IFS | FSR | ICLK | SLEN11 | SPEN_A; dm(SPCTL1) = r0; r0= BHD | LAFS | LFS | FSR | ICLK | SLEN29 | SPEN_B | CKRE; dm(SPCTL3) = r0;//ustat1; R0=0x0a28af; dm(DIV1) = R0; R0 = 0x01c0d8f; dm(DIV3) = R0; bit set mode1 IRPTEN ; r0=0; Utxcont1: dm(TxCount)=r0; #endif