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

Проблема LPC2214 UART+T0 IRQ

Прерывания два УАРТ и Таймер0, Т0 запускается периодически (отсчет таймаута), пока был один Т0 все работало, с делал прерывание на прием по УАРТу - какие-то глюки

Не получается разобраться в чем проблема, вот код

Инициализания прирываний:

 

static void DefDummyInterrupt(void)

{}

 

// IRQ exception handler. Calls the interrupt handlers.

#pragma vector=0x18

__irq __ramfunc void irq_handler(void)

{

void (*interrupt_function)();

unsigned long vector;

 

vector = VICVectAddr; // Get interrupt vector.

interrupt_function = (void(*)())vector;

// __enable_interrupt(); // Enable interrupts.

(*interrupt_function)(); // Call vectored interrupt function.

 

VICVectAddr = 0; // Clear interrupt in VIC.

}

 

//************************************************************

void init_IRQ(void)

{

// Setup interrupt controller.

VICProtection = 0;

// Disable all interrupts

VICIntEnClear = 0xffffffff;

VICDefVectAddr = (unsigned long)&DefDummyInterrupt;

 

// Setup timer callback function.

VICIntSelect=0x0; // Timer0 & UART select as IRQ.

VICVectAddr0 = (unsigned long)&UART0Interrupt;

VICVectCntl0 = 0x20 | VIC_UART0; // Enable vector interrupt for UART0.

VICVectAddr1 = (unsigned long)&Timer0Interrupt;

VICVectCntl1 = 0x20 | VIC_TIMER0; // Enable vector interrupt for timer 0.

VICIntEnable = 0x50; // Enable timer 0 & UART0 interrupt.

}

 

УАРТ - слот0

Т0- слот1

Процедура обработки для Т0 и УАРТа

 

// Timer0 interrupt handler

__ramfunc void Timer0Interrupt(void)

{

T0IR = 0xff; // Clear timer 0 interrupt line.

BF=0;

}

 

//******************************************************************

// Заполняет буфер приема

__ramfunc void UART0Interrupt()

{

while (U0LSR&0x1)

{

rx_buff[rx_end]=U0RBR;

rx_end=(rx_end+1)%RX_BUFF_LEN;

rx_len++;

}

}

 

 

Под житагом запускаю программу, передаю пакет данных. На него должен быть ответ, ответа нет. Останавливаю программу, пакет в буфер принимается верно, лишнего нет почему-то постоянно вылетает на DummyInterrupt, пока не тормознешь отладчиком ответа нет, после остановки отладчиком и снова запуска ответ передается.

Если точка останова на irq_handler то постоянно вылезают DummyInterrupt.

Вообщем чушь какая-то, отладить не получается стоит тормознуть отладчиком идут ответы на пакет.

 

Может есть пример рабочего кода для обработки приема по УАРТ?

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


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

Немного переделал - выкинул Т0, оставил только прием по прерыванию. Передача в цикле по опросу заполнения буфера.

Такое впечатление что при возникновении прерывания в нем все и зацикливается.

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


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

Немного переделал - выкинул Т0, оставил только прием по прерыванию. Передача в цикле по опросу заполнения буфера.

Такое впечатление что при возникновении прерывания в нем все и зацикливается.

 

А почемуб по честному не читать IRR и в соответствии с причиной прерывания действовать, дабы это прерывание сбрасывалось.

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


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

Использую оба указанных прерывания. Никаких проблем.

Вот пример обработчика:

void uart0_interrupt(void)
{
    unsigned int iir;
    unsigned int data;
    
    if (on_uart0_int != NULL)
        on_uart0_int();
    else
    {
        iir = UART[0]->IIR;
        switch ((iir >> 1) & 0x07) {
            /* Receive line status interrupt */
            case 3:
                data = UART[0]->LSR;
                break;
                /* Receive data available interrupt */
            case 2:
                /* Character timeout indicator interrupt */
            case 6:
                data = UART[0]->RBR;
                break;
                /* Transmit holding register empty interrupt */
            case 1:
                break;
        }
    }
}

Вставте в case нужный код.

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


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

А почемуб по честному не читать IRR и в соответствии с причиной прерывания действовать, дабы это прерывание сбрасывалось.

Это не честнее, это просто еще более громоздко. Нормальный подход это ОДНА команда:

 

                ldr     pc,[pc,#-0xFF0]        ; 18 Jump directly to the address given by the AIC
                                               ; from [0xFFFFF020] Curent 18h +8(conveyer)=20h

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


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

Прерывания два УАРТ и Таймер0, Т0 запускается периодически (отсчет таймаута), пока был один Т0 все работало, с делал прерывание на прием по УАРТу - какие-то глюки....

Та же фигня, на LPC2129, компилил Rowley1.6b3 и Keil RVCT 3.0[b 947]

Через какое-то время перестают вызываться обработчики прерываний, хотя прерывания разрешены и в VIC и глобально. Ну не вызывается обработчик и все... (основной код крутиться).

Скорость "зависания" зависит от интенсивности обмена через UART.

Разница между этими версиями - код от Rowley "сваливается" через 5 сек, а от RVCT может несколько минут продержаться.

 

Spurious Int? Но, вроде, по инструкции делал ....

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


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

Та же фигня, на LPC2129, компилил Rowley1.6b3 и Keil RVCT 3.0[b 947]

Через какое-то время перестают вызываться обработчики прерываний, хотя прерывания разрешены и в VIC и глобально. Ну не вызывается обработчик и все... (основной код крутиться).

Скорость "зависания" зависит от интенсивности обмена через UART.

 

... Но, вроде, по инструкции делал ....

К инструкциям относится также и errat'а. Раздел Missed Interrupt Potential.

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


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

К инструкциям относится также и errat'а. Раздел Missed Interrupt Potential.

Errata дело конечно такое :-(, но валить все, что в голову пришло на чужую голову явно не стоит.

Использование таймерого (без PWM/Capture наворотов), UART(115K на полной скорости), SPI, ADC, всех 4х внешних - и никаких проблем, кроме, конечно , описанной в Erratа процедуры инициализации.

Моя статистика наблюдений за "проблемами с прерываниями" на данном форуме, показывает, что в большинстве случаев они оказываются "проблемаим со стеком".

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


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

Моя статистика наблюдений за "проблемами с прерываниями" на данном форуме, показывает, что в большинстве случаев они оказываются "проблемаим со стеком".

По-моему, описанная проблема - не вызывается обработчик прерывания - очень плохо вяжется с "проблемами со стеком".

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


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

Проблему поборол, не понятно почему вычитывание данных UART до опустошения буфера (бит DR) не эквивалентно вычитыванию UART пока не снимется IIR. Прерывания УАРТа кроме RDA все запрещены.

 

Загадкой осталось такое поведение под отладчиком через JTAG.

Причем абсолютно точно, если висит окно просмотра регистров UART то прерывание сразу сбрасывалось, если окно закрыть то нет. Видимо чтение регистров сбрасывающих прерывания через JTAG в отладчике эквивалентно их чтению в программе. Вот и получается глюкодром.

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


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

Проблему поборол, не понятно почему вычитывание данных UART до опустошения буфера (бит DR) не эквивалентно вычитыванию UART пока не снимется IIR.

Странный подход к делу - НЕ должно оно сниматся от того, что буфер опустошили а должно только после того, как Вы дали понять, что на него среагировали, а уж какяя там Ваша реакция должна быть -

читать буфер, не читать буфер, читать, но в следующий понедельник - не его дело.

 

Загадкой осталось такое поведение под отладчиком через JTAG.

Причем абсолютно точно, если висит окно просмотра регистров UART то прерывание сразу сбрасывалось, если окно закрыть то нет.

Какая "загадка" - висит отладчик и ЧИТАЕТ UART. Железу UART по барабану, кто его считал и дал знак,

что СРЕАГИРОВАЛ на прерывание.

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


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

Странный подход к делу - НЕ должно оно сниматся от того, что буфер опустошили а должно только после того, как Вы дали понять, что на него среагировали, а уж какяя там Ваша реакция должна быть -

читать буфер, не читать буфер, читать, но в следующий понедельник - не его дело.

Что же тут странного? Или есть другой способ дать понять что среагировали на прерывание по приему УАРТа и сбросить его кроме как прочитать данные из RBR?

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


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

Если точка останова на irq_handler то постоянно вылезают DummyInterrupt.

У меня такая же фигня, это наверно то что описано в SPURIOUS INTERRUPTS :blink:

Не знаю пока каг с этим быть, я сейчас просто в VicDefVectAddr ничего не записываю...

А вобще VicDefVectAddr используется для обработки невекторированных прерываний,

если у тя все прерывания векторированые то VicDefVectAddr не нужно использовать.

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


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

Или есть другой способ дать понять что среагировали на прерывание по приему УАРТа и сбросить его кроме как прочитать данные из RBR?

Уж не знаю, как и обьяснить... Вы с железом когда нибудь до этого случая дело имели?

Контроллер прерывания и контроллер UART две РАЗНЫЕ вещи. Сброс источника прерывания в UART не является сигналом для снятия прерывания КОНТРОЛЛЕРОМ и наоборот. И это правильно(см. предыщее письмо)

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


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

Уж не знаю, как и обьяснить... Вы с железом когда нибудь до этого случая дело имели?

Уважаемый, я бы попросил.....

Контроллер прерывания и контроллер UART две РАЗНЫЕ вещи. Сброс источника прерывания в UART не является сигналом для снятия прерывания КОНТРОЛЛЕРОМ и наоборот. И это правильно(см. предыщее письмо)

Если вы всетаки взгляните на код в начале ветки, то увидите что прерывание на контроллере сбрасывалось, а сброс источника прерывания на УАРТ выполнялся вычитываением буфера. Сбрасывая прерывание в VIC но не сбрасывая источник этого прерывания в контроллере УАРТа, вы его тутже получаете по новой, что я и имел удовольсвие наблюдать.

Поэтому вопрос как оказалось был в следующем (забудьте о VIC я про него и не спрашивал):

Почему сброс ИСТОЧНИКА прерывания по приему УАРТ путем чтения буфера по признаку DR и по признаку пока не снимется IIR не эквивалентны.

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


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

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

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

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

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

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

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

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

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

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