|
|
  |
NIOS для начинающих |
|
|
|
Jan 20 2014, 05:17
|
Местный
  
Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451

|
Всем категорически здрасте! Нужно сделать следующую штуковину - принимать с ПК данные по COM порту с одной скоростью, и передавать их на внешнее с другой скоростью. Решл сделать это на ниосе, что б не особо замарачиваться и встрял... А именно, написл вот такой вот проект: Код #include <stdio.h> #include "system.h" #include "io.h" #include "alt_types.h" #include "sys/alt_irq.h" #include "altera_avalon_uart_regs.h"
void* context;
alt_8 a = 255; void uart_test(); // прототип ф-ци выполняемой в прерывании
int main() { IOWR(LED_BASE, 0, a); IOWR(UART_BASE, 3, 128); // маска преерывания alt_irq_register (UART_IRQ, context, (void*)uart_test); // здесь говорим компилятору неоходимое о прерывании IOWR(UART_BASE, 4, 5208); // скорость передачи задана в SOPCBUILDER'е, но ещё раз напомним while(1) { IOWR(LED_BASE, 0, a); } }
void uart_test() // прерывание { a = IORD(UART_BASE, 0) & 255; читаем принятый байт IOWR(UART_BASE, 4, 2000); // изменяем скорость передачи IOWR(UART_BASE, 1, a); // предаём принятый байт на внешн. устр. с другой скоростью IOWR(UART_BASE, 4, 5208); // возвращаем предыдущую скорость (9600 бод/сек) return; } Так вот, происходит следующее: проц уходит прерывание, считывает байт (пока всё норм) и передаёт его, но вот осциллограф показывает следующее: Длительность стартового ипульса соответствует необходимой скорости, авот длительности остальных импульсов соответствуют скорости 9600. Такое чувство, что процессор не успев выполнить предыдущую команду, бросается за выполнение следующей. Модифицыровал код подпрогр. прерывания след. образом: Код void uart_test() { a = IORD(UART_BASE, 0) & 255; IOWR(UART_BASE, 4, 2000); IOWR(UART_BASE, 1, a); alt_32 i = 0; for(i = 0; i < 10000; i++) {} IOWR(UART_BASE, 4, 5208); return; } и всё стало нормалёк... передача идёт с заданной скоростью... Может кто поделиться соображениями?
|
|
|
|
|
Jan 30 2014, 09:37
|
Местный
  
Группа: Свой
Сообщений: 236
Регистрация: 28-06-13
Из: Минск, Беларусь
Пользователь №: 77 312

|
Цитата(vadimuzzz @ Jan 30 2014, 07:29)  это адреса портов i/o компонента (можно посмотреть в билдере или в system.h), они фиксированы. порядок данных при чтении будет тот же, что и при записи Понемногу разобираюсь с документацией. Читаю регистр статуса. Возник вопрос: каким образом записать данные? Использую функцию altera_avalon_write_fifo(alt_u32 write_address, alt_u32 ctrl_address, alt_u32 data). Если правильно понял ctrl_address это адрес control slave reg, не понятно с write_address адресом base FIFO write slave. Может ли быть это любой адрес в FIFO memory, отсчитываемый от base FIFO control slave (с учетом адресного пространства зарезервированного под регистр статуса)? Проект в SOPC
код Eclipse Код #include "altera_avalon_fifo_regs.h" #include "altera_avalon_fifo_util.h" #include "system.h" #include "sys/alt_irq.h" #include <stdio.h> #include <stdlib.h> #include "altera_avalon_pio_regs.h" #include "system.h" #include <stdio.h>
int main() { alt_u32 tmp; tmp = 100; // чтение регистра статуса printf("LEVEL = %u\n", altera_avalon_fifo_read_level(FIFO_IN_CSR_BASE) ); printf("STATUS = %u\n", altera_avalon_fifo_read_status(FIFO_IN_CSR_BASE, ALTERA_AVALON_FIFO_STATUS_ALL) ); printf("EVENT = %u\n", altera_avalon_fifo_read_event(FIFO_IN_CSR_BASE, ALTERA_AVALON_FIFO_EVENT_ALL) ); //altera_avalon_fifo_write_ienable(FIFO_IN_CSR_BASE, 3); printf("IENABLE = %u\n", altera_avalon_fifo_read_ienable(FIFO_IN_CSR_BASE, ALTERA_AVALON_FIFO_IENABLE_ALL) ); printf("ALMOSTEMPTY = %u\n", altera_avalon_fifo_read_almostempty(FIFO_IN_CSR_BASE) ); printf("ALMOSTFULL = %u\n\n", altera_avalon_fifo_read_almostfull(FIFO_IN_CSR_BASE));
// запись в FIFO altera_avalon_write_fifo( 10 , FIFO_IN_CSR_BASE, tmp);
return 0; } при этом возникает ошибка undefined reference to `altera_avalon_write_fifo' непонятно почему неправильно вызываю функцию `altera_avalon_write_fifo'... Цитата(farbius @ Jan 30 2014, 11:49)  при этом возникает ошибка undefined reference to `altera_avalon_write_fifo' непонятно почему неправильно вызываю функцию `altera_avalon_write_fifo'... Ошибку нашел: в мануале функция неправильно названа (altera_avalon_write_fifo, а необходимо altera_avalon_fifo_write_fifo) записываю и читаю переменную следующим образом Код alt_u32 tmp, tmp_read; tmp = 0xff;
// запись в FIFO altera_avalon_fifo_write_fifo( FIFO_IN_BASE, FIFO_IN_CSR_BASE, tmp);
// чтение из FIFO
tmp_read = altera_avalon_fifo_read_fifo(FIFO_OUT_BASE, FIFO_IN_CSR_BASE);
printf("read = %02x\n", tmp_read); Однако вместо 0xff получаю значение read = 92980. Пока не ясно в чем проблема.
|
|
|
|
|
Jan 30 2014, 13:32
|
Местный
  
Группа: Свой
Сообщений: 236
Регистрация: 28-06-13
Из: Минск, Беларусь
Пользователь №: 77 312

|
Цитата(vadimuzzz @ Jan 30 2014, 14:48)  нет, не может. пишите все в base FIFO write slave Благодарю за ответ. Не ясно где прописан base FIFO write slave для записи или base FIFO read slave для чтения данных. system.h для FIFO Код /* * fifo_in configuration * */
#define ALT_MODULE_CLASS_fifo_in altera_avalon_fifo #define FIFO_IN_AVALONMM_AVALONMM_DATA_WIDTH 32 #define FIFO_IN_AVALONMM_AVALONST_DATA_WIDTH 32 #define FIFO_IN_BASE 0x1108c #define FIFO_IN_BITS_PER_SYMBOL 16 #define FIFO_IN_CHANNEL_WIDTH 8 #define FIFO_IN_ERROR_WIDTH 8 #define FIFO_IN_FIFO_DEPTH 16 #define FIFO_IN_IRQ -1 #define FIFO_IN_IRQ_INTERRUPT_CONTROLLER_ID -1 #define FIFO_IN_NAME "/dev/fifo_in" #define FIFO_IN_SINGLE_CLOCK_MODE 1 #define FIFO_IN_SPAN 4 #define FIFO_IN_SYMBOLS_PER_BEAT 2 #define FIFO_IN_TYPE "altera_avalon_fifo" #define FIFO_IN_USE_AVALONMM_READ_SLAVE 1 #define FIFO_IN_USE_AVALONMM_WRITE_SLAVE 1 #define FIFO_IN_USE_AVALONST_SINK 0 #define FIFO_IN_USE_AVALONST_SOURCE 0 #define FIFO_IN_USE_BACKPRESSURE 1 #define FIFO_IN_USE_IRQ 1 #define FIFO_IN_USE_PACKET 1 #define FIFO_IN_USE_READ_CONTROL 0 #define FIFO_IN_USE_REGISTER 0 #define FIFO_IN_USE_WRITE_CONTROL 1
/* * fifo_in_csr configuration * */
#define ALT_MODULE_CLASS_fifo_in_csr altera_avalon_fifo #define FIFO_IN_CSR_AVALONMM_AVALONMM_DATA_WIDTH 32 #define FIFO_IN_CSR_AVALONMM_AVALONST_DATA_WIDTH 32 #define FIFO_IN_CSR_BASE 0x11040 #define FIFO_IN_CSR_BITS_PER_SYMBOL 16 #define FIFO_IN_CSR_CHANNEL_WIDTH 8 #define FIFO_IN_CSR_ERROR_WIDTH 8 #define FIFO_IN_CSR_FIFO_DEPTH 16 #define FIFO_IN_CSR_IRQ 10 #define FIFO_IN_CSR_IRQ_INTERRUPT_CONTROLLER_ID 0 #define FIFO_IN_CSR_NAME "/dev/fifo_in_csr" #define FIFO_IN_CSR_SINGLE_CLOCK_MODE 1 #define FIFO_IN_CSR_SPAN 32 #define FIFO_IN_CSR_SYMBOLS_PER_BEAT 2 #define FIFO_IN_CSR_TYPE "altera_avalon_fifo" #define FIFO_IN_CSR_USE_AVALONMM_READ_SLAVE 1 #define FIFO_IN_CSR_USE_AVALONMM_WRITE_SLAVE 1 #define FIFO_IN_CSR_USE_AVALONST_SINK 0 #define FIFO_IN_CSR_USE_AVALONST_SOURCE 0 #define FIFO_IN_CSR_USE_BACKPRESSURE 1 #define FIFO_IN_CSR_USE_IRQ 1 #define FIFO_IN_CSR_USE_PACKET 1 #define FIFO_IN_CSR_USE_READ_CONTROL 0 #define FIFO_IN_CSR_USE_REGISTER 0 #define FIFO_IN_CSR_USE_WRITE_CONTROL 1
/* * fifo_out configuration * */
#define ALT_MODULE_CLASS_fifo_out altera_avalon_fifo #define FIFO_OUT_AVALONMM_AVALONMM_DATA_WIDTH 32 #define FIFO_OUT_AVALONMM_AVALONST_DATA_WIDTH 32 #define FIFO_OUT_BASE 0x11088 #define FIFO_OUT_BITS_PER_SYMBOL 16 #define FIFO_OUT_CHANNEL_WIDTH 8 #define FIFO_OUT_ERROR_WIDTH 8 #define FIFO_OUT_FIFO_DEPTH 16 #define FIFO_OUT_IRQ -1 #define FIFO_OUT_IRQ_INTERRUPT_CONTROLLER_ID -1 #define FIFO_OUT_NAME "/dev/fifo_out" #define FIFO_OUT_SINGLE_CLOCK_MODE 1 #define FIFO_OUT_SPAN 4 #define FIFO_OUT_SYMBOLS_PER_BEAT 2 #define FIFO_OUT_TYPE "altera_avalon_fifo" #define FIFO_OUT_USE_AVALONMM_READ_SLAVE 1 #define FIFO_OUT_USE_AVALONMM_WRITE_SLAVE 1 #define FIFO_OUT_USE_AVALONST_SINK 0 #define FIFO_OUT_USE_AVALONST_SOURCE 0 #define FIFO_OUT_USE_BACKPRESSURE 1 #define FIFO_OUT_USE_IRQ 1 #define FIFO_OUT_USE_PACKET 1 #define FIFO_OUT_USE_READ_CONTROL 0 #define FIFO_OUT_USE_REGISTER 0 #define FIFO_OUT_USE_WRITE_CONTROL 1 в этом файле в соответствии с документацией на On chip FIFO memory FIFO_IN_CSR_BASE -- это the base address of the FIFO control slave как быть с the base address of the FIFO write slave и the base address of the FIFO read slave? Изначально была мысль о FIFO_IN_BASE и FIFO_OUT_BASE соответственно. Цитата(farbius @ Jan 30 2014, 16:22)  как быть с the base address of the FIFO write slave и the base address of the FIFO read slave? Изначально была мысль о FIFO_IN_BASE и FIFO_OUT_BASE соответственно. например в такой конфигурации происходит запись/чтение без проблем для одной переменной Код alt_u32 tmp, tmp_read; tmp = 0xff;
// запись altera_avalon_fifo_write_fifo( FIFO_IN_USE_AVALONMM_WRITE_SLAVE, FIFO_IN_CSR_BASE, tmp); // чтение tmp_read = altera_avalon_fifo_read_fifo(FIFO_IN_USE_AVALONMM_READ_SLAVE , FIFO_IN_CSR_BASE); printf("read = %02x\n", tmp_read); Каким образом можно проверить что записан весь буфер? Можно, например, сформировать массив, записать используя altera_avalon_fifo_write_fifo, и как потом считать?
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|