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

 
 
> Nios чтение байта из двухпортовой RAM
Acvarif
сообщение Jul 4 2016, 07:36
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Имеется модуль с Avalon Slave присоединенный в систему с Nios
Код
    Port
    (
        -- Avalon Slave
        clk                  : in  std_logic                     := '0';             -- clock.clk
        reset_n              : in  std_logic                     := '0';             --      .reset_n
        avs_s0_address       : in  std_logic_vector(7 downto 0)  := (others => '0'); --    s0.address
        avs_s0_read_n        : in  std_logic                     := '0';             --      .read_n
        avs_s0_write_n       : in  std_logic                     := '0';             --      .write_n
        avs_s0_writedata     : in  std_logic_vector(7 downto 0) := (others => '0'); --      .writedata
        avs_s0_byteenable    : in  std_logic_vector(0 downto 0)     := (others => '0');
        avs_s0_readdata      : out std_logic_vector(7 downto 0);                    --      .readdata
        ins_irq0_irq         : out std_logic;

В модуле имеется двухпортовая RAM (16 байт) которую необходимо читать по прерыванию ins_irq0_irq
В программе обработчика первым делом сбрасываю импульс прерывания чтением по крайнему адресу
Код
....
void Irq0Isr(void* context, alt_u32 id)
{
    // сброс сигнала прерывания
    IORD_8DIRECT(AMULET_0_BASE, 255);
    Isr0Occur = 1;
    AllIrq0Count++;
}
....

В майн читаю память. Данные в памяти заранее известны. 0x55, 0xaa, ...
Код
...
            if (AllIrq0Count)
            {
                RamData = IORD_8DIRECT(AMULET_0_BASE, 0);
                printf("Прерывание Irq0: N %d \n", AllIrq0Count);
                printf("Данные: %x \n", RamData[0]);
                AllIrq0Count = 0;
            }
....
Все работает нормально пока (AMULET_0_BASE, 0)
Вопрос как считать данные по следующему адресу RAM? Какое должно быть смещение. Поскольку Nios оперирует байтами, а Avalon имеет ширину 32 бита, то смещение для чтения следующего байта из двухпортовой RAM должно быть 4. Прочитанный байт должет быть 0хaa. На практике читается все то же 0х55. Подскажите пожалуйста в чем загвоздка?

Сообщение отредактировал Acvarif - Jul 4 2016, 07:37
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
vadimuzzz
сообщение Jul 5 2016, 00:29
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988



Так а зачем - делаете сколько надо флагов в статусном регистре с соответствующими interrupt_enable в контрольном, а сигнал прерывания будет просто логическим ИЛИ от этих флагов. Обработчик прерывания уже сам разберется в причине, заглянув в статусный регистр перед снятием прерывания.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 5 2016, 06:24
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(vadimuzzz @ Jul 5 2016, 03:29) *
Так а зачем - делаете сколько надо флагов в статусном регистре с соответствующими interrupt_enable в контрольном, а сигнал прерывания будет просто логическим ИЛИ от этих флагов. Обработчик прерывания уже сам разберется в причине, заглянув в статусный регистр перед снятием прерывания.

Спасибо. Смысл понятен. Не соображу как эти регистры создать. По типу .h фала?
Код
#ifndef __ALTERA_AVALON_AMULET_REGS_H__
#define __ALTERA_AVALON_AMULET_REGS_H__

#include <io.h>

#define ALTERA_AVALON_AMULET_STATUS_REG                 2
#define IOADDR_ALTERA_AVALON_AMULET_STATUS(base)        \
        __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_AMULET_STATUS_REG)
#define IORD_ALTERA_AVALON_AMULET_STATUS(base)          \
        IORD(base, ALTERA_AVALON_AMULET_STATUS_REG)
#define IOWR_ALTERA_AVALON_AMULET_STATUS(base, data)    \
        IOWR(base, ALTERA_AVALON_AMULET_STATUS_REG, data)

#define ALTERA_AVALON_AMULET_STATUS_IRQ0_MSK              (0x1)
#define ALTERA_AVALON_AMULET_STATUS_IRQ0_OFST             (0)
#define ALTERA_AVALON_AMULET_STATUS_IRQ1_MSK              (0x2)
#define ALTERA_AVALON_AMULET_STATUS_IRQ1_OFST             (1)

#define ALTERA_AVALON_AMULET_CONTROL_REG                3
#define IOADDR_ALTERA_AVALON_AMULET_CONTROL(base)       \
        __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_AMULET_CONTROL_REG)
#define IORD_ALTERA_AVALON_AMULET_CONTROL(base)         \
        IORD(base, ALTERA_AVALON_AMULET_CONTROL_REG)
#define IOWR_ALTERA_AVALON_AMULET_CONTROL(base, data)   \
        IOWR(base, ALTERA_AVALON_AMULET_CONTROL_REG, data)

#define ALTERA_AVALON_AMULET_CONTROL_IRQ0_MSK             (0x1)
#define ALTERA_AVALON_AMULET_CONTROL_IRQ0_OFST            (0)
#define ALTERA_AVALON_AMULET_CONTROL_IRQ1_MSK             (0x2)
#define ALTERA_AVALON_AMULET_CONTROL_IRQ1_OFST            (1)

#endif /* __ALTERA_AVALON_AMULET_REGS_H__ */

Не врубаюсь как в регистрах будут устанавливаться и сбрасываться биты. Очевидно эти регистры (ALTERA_AVALON_AMULET_CONTROL_REG, ALTERA_AVALON_AMULET_STATUS_REG) нужно создать и в самом модуле Amulet? Или нет.. Если не сложно, поясните пожалуйста коротко механизм.
Go to the top of the page
 
+Quote Post
vadimuzzz
сообщение Jul 5 2016, 14:03
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988



Цитата(Acvarif @ Jul 5 2016, 12:24) *
Очевидно эти регистры (ALTERA_AVALON_AMULET_CONTROL_REG, ALTERA_AVALON_AMULET_STATUS_REG) нужно создать и в самом модуле Amulet? Или нет.. Если не сложно, поясните пожалуйста коротко механизм.

Да, пример выше привели. Эти регистры привязать к MM-слейву, чтобы проц туда доступ имел. Вот еще пример: http://paste.org.ru/?18jxcc
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 13 2016, 06:37
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(vadimuzzz @ Jul 5 2016, 17:03) *
Да, пример выше привели. Эти регистры привязать к MM-слейву, чтобы проц туда доступ имел. Вот еще пример: http://paste.org.ru/?18jxcc

Спасибо. Понятно.
В тему появилась еще непонятка. При чтении по прерывании (из Nios) данных которые заранее записаны в двухпортовую RAM первое прерывание читает все 0 и только по второму прерыванию читаются верные данные. Ниже обработчик.
Код
void Irq0Isr(void* context, alt_u32 id)
{
    alt_u8 i;

    // сброс сигнала прерывания
    IORD_8DIRECT(AMULET_0_BASE, 255);

    // чтение двухпортовой RAM
    for (i = 0; i < 16; i++)
    {
        RamData[i] = IORD_8DIRECT(AMULET_0_BASE, i);
    }
    // флаг прерывания
    FlIrq0 = 1;
    // счетчик прерываний
    AllIrq0Count++;

    // синхро поймано
    if (RamData[0] == 0x55 && RamData[1] == 0xaa && !BeginTrns)
    {
        // начало передачи протокола
        BeginTrns = 1;
        // общее количество байт информации о метках
        AllNbData = (RamData[6] << 8) | RamData[7];
        // переключатель банков памяти протокола
        if(NbTx) NbTx = 0; else NbTx = 1;
        // флаг для светодиода
        BeginPr = 1;
        // фиксация номера прерывания
        printf("Номер прерывания синхросимволов Irq0: N %d \n", AllIrq0Count);
    }

}
Дело в том, что синхросимволы уже имеются в памяти и должны появиться в RamData по первому прерыванию, тоесть когда AllIrq0Count = 1. Но printf принтует в окне терминала N 2. На самом деле так оно и есть. Почему по первому прерыванию из двухпортовой RAM читаются нули, а не реальные данные ?
Go to the top of the page
 
+Quote Post



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

 


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


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