реклама на сайте
подробности

 
 
> Зависает прошивка. Реализовал стек для хранения принятых по USB данных и дальнейшей передачи по SSC., at91sam7s
Bulat
сообщение Apr 29 2010, 05:47
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Принима данные из UDP, разбираю FIFO буфер UDP и заполняю собственный стек типа FIFO для SSC. SSC по прерыванию забирает из моего стека данные и отправляет их со скоростью 100 кбит\с. Дополнительный стек необходим, чтобы сильно не тормозить работу компьютера по USB, чтобы не происходила потеря данных.
CODE

unsigned int que[16]; // Стек типа FIFO для передаваемых по SSC данных
unsigned int head = 0; //начальный индекс
unsigned int tail = 0; //конечный индекс

//Обработчик прерывания SSC
__ramfunc void SscHandler()
{
AT91C_BASE_SSC->SSC_THR = que[head]; //отправляем на передачу слово из стека для SSC
head = (head+1)&0xf; //инкрементируем начальный индекс стека
//если начальный индекс обнулился, значит стек пуст и готов для повторного заполнения
if(head == 0) { AT91C_BASE_SSC->SSC_CR = AT91C_SSC_TXDIS ;
AT91C_BASE_SSC->SSC_IDR = 0xfff; jj=0;}
unsigned int dummy = AT91C_BASE_SSC->SSC_SR;
}

void main()
{
while(1)
{
//если FIFO UDP пуст
if(length == 0)
{
// проверка флага прерывания от EP2
if((AT91C_BASE_UDP->UDP_ISR) & AT91C_UDP_EPINT2)
{
if(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & pCDC.currentRcvBank)
length = regUDP->UDP_CSR[AT91C_EP_OUT]>>16;
}
}

//если в FIFO UDP присутствуют данные, то заполняем
if(length != 0)
{
if(jj==0) //если стек для SSC не заполнен, то продолжаем его заполнять
{
unsigned int byte[4];
byte[0] = regUDP->UDP_FDR[AT91C_EP_OUT];
byte[1] = regUDP->UDP_FDR[AT91C_EP_OUT];
byte[2] = regUDP->UDP_FDR[AT91C_EP_OUT];
byte[3] = regUDP->UDP_FDR[AT91C_EP_OUT];


unsigned int dat_buf = (byte[3]<<24)|(byte[2]<<16)|(byte[1]<<8)|byte[0];
//формируем 32-битное слово для передачи по SSC

que[tail] = dat_buf;
tail = (tail+1)&0xf;
//инкрементируем конечный индекс и накладываем маску (размер стека 16 слов)
if(tail == 0) jj = 1;
//если конечный индекс обнулился, значит стек полон и необходимо прекратить запись в него, пока он не освободится
else {AT91C_BASE_SSC->SSC_CR = AT91C_SSC_TXEN; AT91C_BASE_SSC->SSC_IER = AT91C_SSC_TXRDY;}
//иначе разрешаем передачу по SSC

length = length-4; //уменьшаем значение остатка в FIFO UDP

}//if(jj == 0)

if(length == 0)
{
Udp_ep_clr_flag(regUDP,AT91C_EP_OUT, pCDC.currentRcvBank);
if(pCDC.currentRcvBank == AT91C_UDP_RX_DATA_BK0)pCDC.currentRcvBank = AT91C_UDP_RX_DATA_BK1;
else pCDC.currentRcvBank = AT91C_UDP_RX_DATA_BK0;
AT91C_BASE_UDP->UDP_ICR = 0xFFFFFFFF;
}

}//if(length != 0)

}//while(1)
}//main


Таким образом, в случае заполнения стека que[], данные из FIFO UDP не считываются пока SSC не опустошит свой стек que[].
Если убрать из обработчика SSC останов передатчика (AT91C_BASE_SSC->SSC_CR = AT91C_SSC_TXDIS ; AT91C_BASE_SSC->SSC_IDR = 0xfff;) то прошивка не повисает. Но тогда данные, передаваемые по SSC будут уже не те. Не понятно где может повиснуть прошивка, так как останов и повторный запуск SSC работает, проблемы возникли, когда я ввел стек.

Сообщение отредактировал rezident - Apr 30 2010, 21:11
Причина редактирования: Редактирование оформления цитаты исходника.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 09:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.01371 секунд с 7
ELECTRONIX ©2004-2016