Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: NiosII. Как подружить UART и DMA?
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
ivanov_sg
Хочется принять пакет данных с UART и по DMA положить в память.
1. Пакет известной длины
2. Известен символ конца пакета.

Для рещения задачи 1 написал код по букварю, который в режиме отладки (debug) в железе работает, а при нормальном запуске (Run) виснет: при поступании 1 символа с UARTа цикл while (rx_done==0) {...} (см. ниже код) перестает работать и на консоль ничего не выводится...
В debug режиме происходит правильный прием 8 символов, которые выводятся в консоль. (QuartusII 7.2, WinXP, железо - альтеровский NiosII кит на кристалле Cyclone2c35, система в SOPC-билдере родная, единственное изменение - подключил DMA-контроллер к UARTу (шины read master и write master).

Делал тоже самое через регистры напрямую, результат тот-же.

//--init--
void init() {
//конфигурация UART - скорость обмена
//9600 - 8854
IOWR_ALTERA_AVALON_UART_DIVISOR(UART_BASE,8854);
}
//--------

#define buff_length 8 //столько байт хотим прочитать

static volatile int rx_done;
static void done (void* handle, void* data) {
rx_done++;
}

//--main--
int main()
{
alt_u8 ch=0, cnt=0, tt=0;
alt_16 uart_status=0, timer_status=0, i=0, j=0;
alt_32 dma_status=0, dma_length=0, dma_control=0;

init();

void* tx_data;
void* rx_data;
tx_data=(void*)alt_uncached_malloc(buff_length);
rx_data=(void*)alt_uncached_malloc(buff_length);

printf("tx_data=");
for (i=0; i<buff_length; i++) {
IOWR_8DIRECT((int)tx_data,i,(i+1));
IOWR_8DIRECT((int)rx_data,i,0);
printf("%i ",IORD_8DIRECT((int)tx_data,i));
}
printf("\n");

int rc;
alt_dma_txchan txchan;
alt_dma_rxchan rxchan;

// Create the transmit channel
if ((txchan = alt_dma_txchan_open("/dev/dma")) == NULL) {
printf ("Failed to open transmit channel\n");
exit (1);
}
// Create the receive channel
if ((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL) {
printf ("Failed to open receive channel\n");
exit (1);
}

//разрядность входных и выходных данных 8 бит
alt_dma_rxchan_ioctl(rxchan, ALT_DMA_SET_MODE_8, NULL);
alt_dma_txchan_ioctl(txchan, ALT_DMA_SET_MODE_8, NULL);

//принимаем данные из фиксированного адреса
alt_dma_rxchan_ioctl(rxchan, ALT_DMA_RX_ONLY_ON, UART_BASE);

// Post the transmit request
if ((rc = alt_dma_txchan_send (txchan, UART_BASE, buff_length, NULL, NULL)) < 0) {
printf ("Failed to post transmit request, reason = %i\n", rc);
exit (1);
}
// Post the receive request
if ((rc = alt_dma_rxchan_prepare (rxchan, rx_data, buff_length, done, NULL)) < 0) {
printf ("Failed to post read request, reason = %i\n", rc);
exit (1);
}
// wait for transfer to complete
while (rx_done==0) {
dma_length=IORD_ALTERA_AVALON_DMA_LENGTH(DMA_BASE);
dma_status=IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE);
printf("status=%i, length=%i, rx_done=%i\n",dma_status,dma_length,rx_done);
usleep(500000);
};

printf("after transfer\nrx_data=");
for (i=0; i<buff_length; i++) {
printf("%i ",IORD_8DIRECT((int)rx_data,i));
}
}
ivanov_sg
Через регистры делел так:

IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE, 0); //очистка статуса
IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE,0); //очистка регистра управления

IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE, (UART_BASE)); //адрес передатчика
IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE, rx_data); //адрес приемника

IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE, buff_length); //длина в байтах
dma_length=IORD_ALTERA_AVALON_DMA_LENGTH(DMA_BASE);

IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE,
ALTERA_AVALON_DMA_CONTROL_BYTE_MSK|
ALTERA_AVALON_DMA_CONTROL_GO_MSK|
ALTERA_AVALON_DMA_CONTROL_LEEN_MSK|
ALTERA_AVALON_DMA_CONTROL_RCON_MSK);

while ( IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE) & (
ALTERA_AVALON_DMA_STATUS_BUSY_MSK)) { // ждем пока все не передаст
}
printf("after transfer\nrx_data=");
//отображение
for (i=0; i<buff_length; i++) {
printf("%i ",IORD_8DIRECT((int)rx_data,i));
}
ivanov_sg
Это..., я в теме знак вопроса забыл поставить!!! Код НЕ РАБОТАЕТ!!! Надо найти ошибку...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.