Программа 29.2. Пример программы на языке Си

/* CIRCBUF.C */
/* Это программа генерации эха, написанная на Си для ADSP-21061 EZ-KIT Lite */
/* Эта программа использует базовую программу прямой передачи входных данных */
/* (talkthrough) на выход и дополнительно использует схему циклической буферизации */
/* Циклический буфер инициализируется функциями CIRCULAR_BUFFER, BASE и LENGTH */
/* Эхо формируется добавлением к текущему входному отсчёту самого старого */
/* записанного в циклический буфер входного отсчёта */
/* Задержка эха может регулироваться значением параметра BUFF_LENGTH */
/*                                                                                 */
#include <21020.h>   /* для команды idle() */
#include <signal.h>  /* для команды  interrupt */
#include <macros.h>  /* для функций CIRCULAR_BUFFER() и segment() */

#define BUFF_LENGTH 4000

CIRCULAR_BUFFER (float,1,echo) /* инициализирует переменную echo,
                               /* как указатель на */
/* циклический буфер в памяти данных. Значение указателя хранится в регистре i1 */
/* генератора адреса данных DAG1 */

volatile float in_port segment (hip_reg0);  /* объекты hip_reg0 и hip-reg2 */
volatile float out_port segment (hip_reg2); /* используются в файле архитектуры */

void process_input (int);
void main (void)

{/* Длину циклического буфера можно менять. Если остановить выполнение программы в */
/* теле функции main и в окне отображения памяти dm изменить параметр _BUFF_LENGTH */
/* то задержка эха изменится. Но не делайте BUFF_LENGTH больше, чем размер стека!  */

float data_buff [BUFF_LENGTH];
interrupt (SIG_IRQ3, process_input);
BASE (echo) = data_buff;     /* Загружает в b1 и i1 начальный адрес буфера */
LENGTH (echo) = BUFF_LENGTH; /* Загружает в L1 длину буфера */
/* когда циклический буфер полностью заполнен, n-й его элемент содержит самый */
/* новый отсчёт, а (n + 1)-й элемент содержит самый старый отсчёт */

while (1)
{
float oldest, newest;  /* Добавление эха означает суммирование самого нового */
idle();                              /* и самого старого отсчётов */

/* После обработки прерывания переменная echo указывает на n-й элемент        */
/* циклического буфера. Новый отсчёт записывается в переменную 'newest'.       */
/* Затем указатель увеличивается на единицу и переходит к элементу n + 1         */

CIRC_READ (echo, 1, newest, dm);

/* Теперь переменная echo указывает на (n + 1)-й элемент. Происходит чтение */
/* переменной 'oldest'. Указатель не изменяется, так как теперь он указывает */
/* на элемент, в который после следующего прерывания будет записан новый отсчёт */

CIR_READ (echo, 0, oldest, dm);

/* Суммируем самый старый и самый новый отсчёты и результат отправляем на выход */
out_port=oldest+newest;
}
}
void process_input (int int_number)
{
/* Новый входной отсчёт записывается в циклический буфер на место самого старого */
/* отсчёта в n-й элемент.
Указатель не изменяется */

CIRC_WRITE (echo, 0, in_port, dm);
}