Смекни!
smekni.com

Проектирование устройства передачи данных по радиоканалу (стр. 12 из 12)

/*-------------------------------------------------------------*/

/* 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(";@&bsol;r&bsol;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(";@&bsol;r&bsol;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;