/*-------------------------------------------------------------*/
/* Mode */
/* 0 - ARQ */
/* 1 - CFEC */
/* 2 - SFEC */
/*-------------------------------------------------------------*/
UCHAR convert(char ch) // Конвертерв NBDP
{
if(ch == ERR_SMBL) return ERR_SMBL;
{
int index = table2[(int) ch];
if(index)
{
struct CVT *cvt;
cvt = &CVT_TABLE[index-1];
switch(SHIFT)
{
case 0: return cvt->_LET;
case 1: return cvt->_FIG;
case 2: return cvt->_RUS;
}
}
}
return ERR_SMBL;
}
/*-------------------------------------------------------------*/
void NBDP_Init(void) // ИнициализацияNBDP (вызываетсяиз main.c)
{
SetID(1,"32610",SIS5,NULL,1);
SetID(2,"123456789",SIS9,SCS9,1);
strcpy(SIS9,"\x2e\x33\x65\x33\x27\x39\x2e\x71\x69");
strcpy(SCS9,"\x17\x4e\x69");
/*-------------------------------------------------------------*/
StandBy();
}
3. Программа serial.c
Содержит функции для работы с последовательным портом.
#include <stdarg.h>
#include <string.h>
#include <drivers.h>
/*-------------------------------------------------------------*/
#define MAX_CMD_LEN 127
unsigned int CMDS, /* command rx state */
CMDL; /* command rx pointer */
char CMD[MAX_CMD_LEN+1]; /* command rx buffer */
/*-------------------------------------------------------------*/
int chr;
int SerialDriver(void) // проверка работы и инициализация последоват. порта
{
/*int chr;*/
repeat:
if(get_char(&chr))
{
if(CMDS) /* command receiving */
{
if(CMDL>=MAX_CMD_LEN)
{
SendHostError(0,0);
reset_state:
CMDL=CMDS=0;
return 0;
}
if((CMD[CMDL-1] == ';') && (chr == '@')) /* EOC */
{
CMD[CMDL++] = chr;
CMD[CMDL] = 0;
HostCommandParser(&CMD[0]);
goto reset_state;
}
else
{
CMD[CMDL++] = chr;
goto repeat;
return 0;
}
}
else /* command waiting */
{
if(chr=='$')
{
CMDL=0;
CMD[CMDL++] = chr;
CMDS=1;
goto repeat;
}
}
}
return 0;
}
/*-------------------------------------------------------------*/
extern unsigned int No;
char BUFFER[MAX_CMD_LEN+1];
int SendCommandHost(char *cmd, char *fmt,...) // функциядляпередачи
// командвтерминал
{
/* Make data string to out */
/*int len;*/
va_list argptr;
/* Out the packet header: $CMD;channel_no; */
out_char('$');
out_string(cmd/*,strlen(cmd)*/);
out_char(';');
out_char(No + 0x30);
out_char(';');
/* Out the variable part */
va_start(argptr, fmt);
/*len =*/ vprinter(&BUFFER[0], fmt, argptr);
va_end(argptr);
out_string(BUFFER/*,len*/);
/* Out the end part of packet */
out_string(";@\r\n"/*,4*/);
return 0;
}
/*-------------------------------------------------------------*/
int SendCommandHostDBG(int level, char *fmt,...)
{
/* Make data string to out */
/*int len;*/
va_list argptr;
if(!(dip_sw & DIP_SW4)) return 0; /* not output debug */
if(level > DebugLevel) return 0;
/* Out the packet header: $CMD;channel_no; */
out_string("$DBG;"); out_char(No + 0x30); out_char(';');
/* Out the variable part */
va_start(argptr, fmt);
vprinter(&BUFFER[0], fmt, argptr);
va_end(argptr);
out_string(BUFFER);
/* Out the end part of packet */
out_string(";@\r\n");
return 0;
}
Критичные по быстродействию функции выполняем на языке ассемблер под ADSP 2181.
Sin.dsp
Функции разложения на синус и косинус используемые при модуляции и демодуляции для вычисления "налету".
.MODULE/RAM _SIN_COS_INTEGER_;
{---------------------------------------------------------------
Sine/Cosine approximation for 1.15 format
int Y = sin_i(int X)
int Y = cos_i(int X)
---------------------------------------------------------------
---------------------------------------------------------------
Calling parameters
AR = X in scaled 1.15 format
M1 = 1
L1 = 0
Return values
AR = X in 1.15 format
Computation time
sin : 30 + (3) cycles
cosine: 32 + (3) cycles
---------------------------------------------------------------
}
.VAR/DM sin_coeff[5];
.INIT sin_coeff : 0x3240, 0x0053, 0xAACC, 0x08B7, 0x1CCE;
.ENTRY sin_i_;
.ENTRY cos_i_;
cos_i_:
AY1 = 0x4000; { AY0 = PI/2 }
AR = AR + AY1; { AR = X+PI/2 }
sin_i_:
SI = AR; { save AR }
I1 = ^sin_coeff; {ptr to coeff buffer }
AY1=0x4000;
AF=AR AND AY1; {check 2nd or 4th quad.}
IF NE AR=-AR; {If yes negate input }
AY1=0x7FFF;
AR = AR AND AY1; {remove sign bit }
MY1=AR;
/*#ifndef GLOBAL_F*/
SR1 = MSTAT; { save MSTAT }
DIS M_MODE; { set fractional }
/*#endif*/
SR0 = MX1; {save MX1 }
MF=AR*MY1 (RND), MX1=DM(I1,M1); {MF = X^2 }
MR=MX1*MY1 (SS) , MX1=DM(I1,M1); {MR = C1*X }
CNTR=3;
DO approx UNTIL CE;
MR=MR+MX1*MF (SS);
approx: MF=AR*MF (RND), MX1=DM(I1,M1);
MR=MR+MX1*MF (SS);
MX1 = SR0; { restore MX1 }
/*#ifndef GLOBAL_F*/
MSTAT = SR1; { restore MSTAT }
/*#endif*/
SR=ASHIFT MR1 BY 3 (HI);
SR=SR OR LSHIFT MR0 BY 3 (LO); {convert to 1.15 format}
AR=PASS SR1;
IF LT AR=PASS AY1; {saturate if needed }
AY1=SI;
AF=PASS AY1;
IF LT AR=-AR;
RTS;
.ENDMOD;
Программа 2181_hdr.dsp
Содержит код инициализации ADSP 2181.
.MODULE/ABS=0 ADSP2181_Runtime_Header;
#define _MY_HANDLER 1
// объявление внешних функций Си для использования их в ассемблере
.EXTERNAL ___lib_setup_everything;
.EXTERNAL main_;
#ifndef _MY_HANDLER
.EXTERNAL ___lib_sp0r_ctrl;
#endif
.EXTERNAL stat_flag_;
.EXTERNAL next_cmd_;
.EXTERNAL process_a_bit; { uart }
.EXTERNAL IRQE_Flag_;
// Установка векторов прерываний
// По сбросу загружать функцию Си main
__Reset_vector: CALL ___lib_setup_everything;
CALL main_; RTS; NOP; {Begin C program}
__Interrupt2: rti;NOP;NOP;NOP;
__InterruptL1: rti;NOP;NOP;NOP;
__InterruptL0: rti;NOP;NOP;NOP;
__Sport0_trans: jump _sp0tx;nop;nop;nop;
#ifndef _MY_HANDLER
__Sport0_recv: JUMP ___lib_sp0r_ctrl;NOP;NOP;NOP;
#else
__Sport0_recv: JUMP _sp0rx;NOP;NOP;NOP;
#endif
__InterruptE: ena sec_reg; ar = 1; dm(IRQE_Flag_)=ar; rti;
__BDMA_interrupt: rti;NOP;NOP;NOP;
#ifndef HW_UART
__Interrupt1: pop sts; /* 20: SPORT1 tx or IRQ1 */
ena timer; rts; rti;
#else
__Interrupt1: rti; /* 20: SPORT1 tx or IRQ1 */
rti; rti; rti;
#endif
__Interrupt0: rti;NOP;NOP;NOP;
__Timer_interrupt: jump process_a_bit; /* 28: timer */
rti; rti; rti;
__Powerdown_interrupt: rti;NOP;NOP;NOP;
#ifdef _MY_HANDLER
/*-------------------------------------------------------------
1) Enble sec reg bank
2) Save all unaltered registers
3) Setup stack, Run C-handler
4) Restore unaltered registers
5) disable sec reg bank
-------------------------------------------------------------*/
.var/dm REG_SAVE_SP0RX[11];
.external modulator_;
.external demodulator_;
_sp0rx:
// сохранение регистров
dm(REG_SAVE_SP0RX + 0) = PX; /* 1 */
dm(REG_SAVE_SP0RX + 1) = L0; /* 2 */
dm(REG_SAVE_SP0RX + 2) = I1; /* 3 */
dm(REG_SAVE_SP0RX + 3) = L1; /* 4 */
dm(REG_SAVE_SP0RX + 4) = M2; /* 5 */
dm(REG_SAVE_SP0RX + 5) = M3; /* 6 */
dm(REG_SAVE_SP0RX + 6) = M5; /* 7 */
dm(REG_SAVE_SP0RX + 7) = L5; /* 8 */
dm(REG_SAVE_SP0RX + 8) = I6; /* 9 */
dm(REG_SAVE_SP0RX + 9) = M6; /* 10 */
dm(REG_SAVE_SP0RX + 10) = L6; /* 11 */
/* enable second register bank */
ena sec_reg;
/* set predefined INTR modes */
DIS BIT_REV, DIS AR_SAT, DIS AV_LATCH, ENA M_MODE;
L0=0;
L1=0;
L5=0;
L6=0;
M2=0;
M6=0;
/* restore unaltered registers */
PX = dm(REG_SAVE_SP0RX + 0)/* = PX*/; /* 1 */
L0 = dm(REG_SAVE_SP0RX + 1)/* = L0*/; /* 2 */
I1 = dm(REG_SAVE_SP0RX + 2)/* = I1*/; /* 3 */
L1 = dm(REG_SAVE_SP0RX + 3)/* = L1*/; /* 4 */
M2 = dm(REG_SAVE_SP0RX + 4)/* = M2*/; /* 5 */
M3 = dm(REG_SAVE_SP0RX + 5)/* = M3*/; /* 6 */
M5 = dm(REG_SAVE_SP0RX + 6)/* = M5*/; /* 7 */
L5 = dm(REG_SAVE_SP0RX + 7)/* = L5*/; /* 8 */
I6 = dm(REG_SAVE_SP0RX + 8)/* = I6*/; /* 9 */
M6 = dm(REG_SAVE_SP0RX + 9)/* = M6*/; /* 10 */
L6 = dm(REG_SAVE_SP0RX + 10)/* = L6*/; /* 11 */
rti;
#endif
.var/dm REG_SAVE_SP0TX[11];
_sp0tx:
/* enable second register bank */
ena sec_reg;
ar = dm(stat_flag_);
ar = pass ar;
if ne jump next_cmd_;
/* save unaltered registers */
dm(REG_SAVE_SP0TX + 0) = PX; /* 1 */
dm(REG_SAVE_SP0TX + 1) = L0; /* 2 */
dm(REG_SAVE_SP0TX + 2) = I1; /* 3 */
dm(REG_SAVE_SP0TX + 3) = L1; /* 4 */
dm(REG_SAVE_SP0TX + 4) = M2; /* 5 */
dm(REG_SAVE_SP0TX + 5) = M3; /* 6 */
dm(REG_SAVE_SP0TX + 6) = M5; /* 7 */
dm(REG_SAVE_SP0TX + 7) = L5; /* 8 */
dm(REG_SAVE_SP0TX + 8) = I6; /* 9 */
dm(REG_SAVE_SP0TX + 9) = M6; /* 10 */
dm(REG_SAVE_SP0TX + 10) = L6; /* 11 */
/* enable second register bank */
/*ena sec_reg;*/
/* set predefined INTR modes */
DIS BIT_REV, DIS AR_SAT, DIS AV_LATCH, ENA M_MODE;
L0=0;
L1=0;
L5=0;
L6=0;
M2=0;
M6=0;
call modulator_;
/* restore unaltered registers */
PX = dm(REG_SAVE_SP0TX + 0)/* = PX*/; /* 1 */
L0 = dm(REG_SAVE_SP0TX + 1)/* = L0*/; /* 2 */
I1 = dm(REG_SAVE_SP0TX + 2)/* = I1*/; /* 3 */
L1 = dm(REG_SAVE_SP0TX + 3)/* = L1*/; /* 4 */
M2 = dm(REG_SAVE_SP0TX + 4)/* = M2*/; /* 5 */
M3 = dm(REG_SAVE_SP0TX + 5)/* = M3*/; /* 6 */
M5 = dm(REG_SAVE_SP0TX + 6)/* = M5*/; /* 7 */
L5 = dm(REG_SAVE_SP0TX + 7)/* = L5*/; /* 8 */
I6 = dm(REG_SAVE_SP0TX + 8)/* = I6*/; /* 9 */
M6 = dm(REG_SAVE_SP0TX + 9)/* = M6*/; /* 10 */
L6 = dm(REG_SAVE_SP0TX + 10)/* = L6*/; /* 11 */
rti;
.ENDMOD;