Перейти к содержанию
    

Работа с прерываниями UART Nios II.

Всем привет!

Нужна ваша помощь. В QSys добавил uart, завел IRQ на процессор. При при этом прерываний нет, функция alt_ic_isr_register возвращает 0. Читал, что нужно использовать векторизированные прерывания (VIC). Может кто подскажет, что нужно сделать? Обязательно ли VIC подключать?

 

Вот мой пример кода:

 

static void UARTInterruptHandler(void* isr_context)
{
   alt_u32 status = IORD_ALTERA_AVALON_UART_STATUS(UART_BASE);

   IOWR_ALTERA_AVALON_UART_STATUS(UART_BASE, 0);

   if (status & ALTERA_AVALON_UART_STATUS_RRDY_MSK | )
   {
       if ( status & ( ALTERA_AVALON_UART_STATUS_PE_MSK) )
       {
           asm("break");
           return;
       }
       char ch = (char)IORD_ALTERA_AVALON_UART_RXDATA( UART_BASE );
   }
}

static void uartInit()
{
   alt_u32 control;
   int divisor;

   control = (ALTERA_AVALON_UART_CONTROL_TRDY_MSK | ALTERA_AVALON_UART_CONTROL_RRDY_MSK | ALTERA_AVALON_UART_CONTROL_E_MSK);
   IOWR_ALTERA_AVALON_UART_CONTROL(UART_BASE, control);

   divisor = (int) (50000000 / 9600 + 0.5);
   IOWR_ALTERA_AVALON_UART_DIVISOR(UART_BASE, divisor);

   alt_ic_isr_register(UART_IRQ_INTERRUPT_CONTROLLER_ID, UART_IRQ, UARTInterruptHandler, NULL, 0))
}

int main(void)
{
   uartInit();
   for (;;)
   {
   }
}

 

Еще заметил, что в сгенерированном "system.h" у всех уартов IRQ_INTERRUPT_CONTROLLER_ID равен нулю.

Изменено пользователем arpa-net

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у меня вот так работает

alt_ic_isr_register(DEV_CONTROLLER_ID, DEV_IRQ_ID, (void*) ISR_UART, 0, 0);
alt_ic_irq_enable(DEV_CONTROLLER_ID, DEV_IRQ_ID);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может кто подскажет, что нужно сделать? Обязательно ли VIC подключать?

Использовать VIC не обязательно.

Делать можно, например, вот так:

 

#include <stdio.h>
#include <string.h>
#include "sys/alt_flash.h"

#include "sys/alt_irq.h"
#include "system.h"

#include "altera_avalon_pio_regs.h"
#include "altera_avalon_timer_regs.h"
//#include "altera_avalon_timer.h"

#include "pwm_avalon_interface_regs.h"
#include "pwm_avalon_interface.h"
#include "pwm_avalon_interface.c"

//********************** Global Variables ***********************************************
volatile unsigned short int led_dir;
volatile int return_code;
volatile unsigned char i = 0;
volatile unsigned int duty_cycle[8] = {499999, 150000, 60000, 10000, 5000, 2500, 800, 1};

//********************** ISR functions **************************************************
static void timer_isr (void * context)
{ volatile unsigned char* led_ptr;
  volatile unsigned char* dir_ptr;

  IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0);

  dir_ptr = (volatile unsigned char*)context;
  led_ptr = dir_ptr + 1;

  return_code = altera_avalon_pwm_change_duty_cycle(LED_PWM_BASE, duty_cycle[i]);
  IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, *led_ptr);

  if(*dir_ptr)
    { *led_ptr >>= 1;
      i--;
    }
  else
    { *led_ptr <<= 1;
      i++;
    }
  if(*led_ptr & 0x81)
    *dir_ptr ^= 0x1;

}

//********************** Auxiliary functions ********************************************
void check_return_code(unsigned int address, int return_code)
{ if(return_code != ALTERA_AVALON_PWM_OK)
;
//          print_error(address, return_code);
}

//********************* Main function ***************************************************
int main (void)
{ void* led_dir_ptr = (void*)&led_dir;

  led_dir = 0x0100;

  //Timer Initialization
  IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE, 0x0003);
  IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0);

  IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_BASE, 0x9f00);
  IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_BASE, 0x0024);

  //Register ISR for timer event
  alt_ic_isr_register(TIMER_IRQ_INTERRUPT_CONTROLLER_ID, TIMER_IRQ, timer_isr, led_dir_ptr, 0);

  //Initialize PWM and Check Return Code
  return_code = altera_avalon_pwm_init(LED_PWM_BASE, 500000, 1);
  check_return_code(LED_PWM_BASE, return_code);

  //Enable PWM and Check Return Code
  return_code = altera_avalon_pwm_enable(LED_PWM_BASE);
  check_return_code(LED_PWM_BASE, return_code);

  //Start timer and begin the work
  IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE, 0x0007);

//  IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led);

  while (1)
   check_return_code(LED_PWM_BASE, return_code);

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем спасибо за ответы. Проблема была в том, что альтеровский HAL-драйвер перехватывал мой IRQ

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...