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

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> прерывания от таймеров в SAM, опять затупил :(
SpiritDance
сообщение Jun 26 2006, 09:41
Сообщение #1


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Что-то с самом у меня не клеится. Не пионимаю как организовать прерывание по переполнению таймера.
вобщем что понятно. нужно проинициализировать aic и поставить таймер в режим сравнения. в регистр сравнения rc таймера записать максимальное значение 0xFFFF
Код
void set_timer_channel1_to_timer_mode(void)
{
    /* */
    //AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC1] = PRIORITY_TIMER1 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE;
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC1] = PRIORITY_TIMER1 | AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED;

    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC1] = (unsigned int)ih_timer1_overload;
    /* ðàçðåøàåì ïðåðûâàíèå îò êàíàëà 1 òàéìåðà-ñ÷åò÷èêà */
    AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC1);

    /* ïîäêëþ÷àåì ê êàíàëó ñèñòåìíóþ ÷àñòîòó è âêëþ÷àåì âûâîä */
    AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_TC1);

    /*  */
    AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK
                             |
                             AT91C_TC_WAVE
                             |
                             AT91C_TC_WAVESEL_UP_AUTO;


    AT91C_BASE_TC1->TC_RC = 0xFFFF;
    AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS;

    /* çàïóñêàåì òàéìåð */
    AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
}


далее пишется простенький обработчик
Код
void ih_timer1_overload(void) __irq
{
//    Time = AT91C_BASE_AIC->AIC_IVR;                 //automatic clear current interrupt
    AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC1);  //clear current interrupt
  
    //if(AT91C_BASE_TC1->TC_SR & AT91C_TC_CPCS)
    {
        Time   = 0xFFFF;
        ReloadCountTime++;
        ReloadCountPulses = 0;
    }
}


Что не понятно.
1. Надо ли очищать какой-то флаг источника прерываний в САМе? То есть правильно ли я делаю что пишу первую(закоментированную) или вторую строчки обработчика?

2. Каким образом таймер генерит прерывания и выбирается их конкретный источник (сравнение по ra rb rc, захват и пр.) в даташите по этому поводу очень грамотно написано
Цитата
Interrupt
The TC has an interrupt line connected to the Advanced Interrupt Controller (AIC). Handling the
TC interrupt requires programming the AIC before configuring the TC.

Круто ничего не скажешь... дальше то что?angry.gif
по поводу определения истьочника подозреваю надо читать статус. Но генерятся то прерывания когда?

3 Прерывание вызывается но только один раз. Подозреваю это из-за того что я что-то упустил с источниками прерываний. Или вообще что-то упустил. При этом я вижу в эмуляторе что флаг cpcs в регистре статуса не изменяется. При каких условиях сбрасывается CPCS?

Памажите а?


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Jun 26 2006, 09:57
Сообщение #2


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Кстати при выборе TC_IER = AT91C_TC_COVFS прерывание тоже 1 раз вызывается. и флаг преполнения после первого вызова торчит постоянно. В чем проблема?


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 26 2006, 10:36
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(SpiritDance @ Jun 26 2006, 13:41) *
1. Надо ли очищать какой-то флаг источника прерываний в САМе? То есть правильно ли я делаю что пишу первую(закоментированную) или вторую строчки обработчика?

2. Каким образом таймер генерит прерывания и выбирается их конкретный источник (сравнение по ra rb rc, захват и пр.) в даташите по этому поводу очень грамотно написано

3 Прерывание вызывается но только один раз. Подозреваю это из-за того что я что-то упустил с источниками прерываний. Или вообще что-то упустил. При этом я вижу в эмуляторе что флаг cpcs в регистре статуса не изменяется. При каких условиях сбрасывается CPCS?


1. Нужно читать TC_SR. Раскомментируйте вторую строку и добавьте в конце AT91C_BASE_AIC->AIC_EOICR = 0x00;
2. Если активен один или несколько источников в таймере, то будет вызвано прерывание.
3. см. п.1

Документация у атмела совершенно нормальная, тщательнее надо smile.gif

Сообщение отредактировал aaarrr - Jun 26 2006, 10:39
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Jun 26 2006, 11:26
Сообщение #4


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



БЛИИИИН я пропустил этот ;*№* EOICR. А уж было думал пойти повесится. Спасибо.

Цитата(aaarrr @ Jun 26 2006, 14:36) *
Документация у атмела совершенно нормальная, тщательнее надо smile.gif

Ничего не говорю против, документация - лучшая из того что наблюдается в АРМах. Только вот... некоторые моменты расписаны очень подробно а некоторые как-то не очень.


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
AVR
сообщение Jul 26 2006, 22:04
Сообщение #5


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Спасите, я тоже уже готов повеситься. Не могу понять как заставить срабатывать прерывание по RTT. Таймер запускается и считает ~1 раз в секунду, но самого прерывание не происходит... Возможно чего-нибудь очень важное забыл настроить... help.gif
ЗЫ Отлаживаю на реальном sam7s64 через Wiggler в CW 1.6
Код
int y = 0;
void IntHandler()
{
    y++;
}

int main(void)
{
    struct x a;
  int i;
    AIC_SVR12 = (int)IntHandler;
    AIC_SMR12 |= 1;
    RTT_VR = 0;
    RTT_MR = 0x00008000 | RTT_MR_RTTINCIEN | RTT_MR_RTTRST;
    AIC_IECR |= 1<<12;
    PMC_PCER = (1<<2);
    int w = 0;
    debug_printf("Initialized!\n");
    while(1)
    {
        if(w != RTT_VR)
        {
            debug_printf("New value of RTT_VR = %4i; y = %4i\n", RTT_VR, y);
            w = RTT_VR;
        }
    }
  return 0;
}

Лог:
Код
Initialized!
New value of RTT_VR =    1; y =    0
New value of RTT_VR =    2; y =    0
New value of RTT_VR =    3; y =    0


Сообщение отредактировал AVR - Jul 26 2006, 22:06


--------------------
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Jul 27 2006, 06:57
Сообщение #6


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Какой-то не такой у вас файл описаний smile.gif , возьмите лучше это.
На вскидку помарки в коде

В прерывании не читается SR

PIO включать не обязательно
PMC_PCER = (1<<2);

Регистр VR - read-only.

на всякий случай
volatile int y

12 соответсвует AT91C_ID_TC0, а RTT я что то вообще не нашел.
Прикрепленные файлы
Прикрепленный файл  AT91SAM7S64.rar ( 62.9 килобайт ) Кол-во скачиваний: 97
 


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
AVR
сообщение Jul 27 2006, 20:46
Сообщение #7


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



SpiritDance, ничего не помогло... sad.gif
PeripheralID для RTT тоже не нашел... wacko.gif
Приведите, пожалуйста, пример наипростейшей инициализации прерывания от таймера.
ЗЫ
К IAR конечно есть примеры, в которых это всё расписано, но в них я не вижу ничего принципиально отличного от того что у меня... =(
ЗЫЗЫ
Вот в AVRке достаточно SEI и просто записать битик разрешающий то или иное прерывание... smile.gif


--------------------
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 27 2006, 21:00
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(AVR @ Jul 28 2006, 00:46) *
PeripheralID для RTT тоже не нашел... wacko.gif

Эх, господа... RTT является частью System Controller'а, соответственно его PID - AT91C_ID_SYS.
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Jul 28 2006, 06:08
Сообщение #9


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Цитата(AVR @ Jul 28 2006, 00:46) *
SpiritDance, ничего не помогло... sad.gif

И не должно было. ID то не тот. И AIC вы не на то прерывание инициализируете, и хендлер не туда записываете. Я только указал на то на что можно было еще наступить.

aaarrr
Очередное спасибо за то что несете свет в наше темное царство. smile.gif


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
AVR
сообщение Jul 29 2006, 10:29
Сообщение #10


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Не получается... sad.gif
Код
volatile int x, y;
void IntHandler()
{
    x = AIC_IVR;
    y++;
    x = RTT_SR;
    AIC_EOICR = 0x777;
}

...

    AIC_SVR2 = (int)IntHandler;
    RTT_MR = 0x00008000 | RTT_MR_RTTINCIEN | RTT_MR_RTTRST;
    AIC_IECR |= 2;
    AIC_ISCR |= 2;
    AIC_SMR1 = (1<<5) | 7;


--------------------
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 29 2006, 15:32
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(AVR @ Jul 29 2006, 14:29) *
Не получается... sad.gif


Во-первых, функция обработки прерывания должна иметь соответствующий
модификатор - __irq, __interrupt и т.п., не знаю, что должно быть в CW.
Далее, читать AIC_IVR не нужно, AIC_IECR - это write-only регистр, писать
в AIC_ISCR ничего не нужно. Кроме того, Вы пишите AIC_SMR1 вместо AIC_SMR2.

Теперь примеры кода.

Номер 1, с level sensetive прерыванием. Здесь требуется дополнительная проверка
в основном цикле, так как прерывание RTT снимается аж через 2 цикла SCLK после
чтения статуса.
Код
void rtt_init(void)
{
    *AT91C_RTTC_RTMR = 0x00008000 | AT91C_RTTC_RTTINCIEN | AT91C_RTTC_RTTRST;

    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (u_int)rtt_handler;
    AT91C_BASE_AIC->AIC_IECR = (0x01 << AT91C_ID_SYS);
}

void main(void)
{
    while(0x01)
    {
        if((*AT91C_RTTC_RTSR & AT91C_RTTC_RTTINC) == 0x00)
            *AT91C_RTTC_RTMR |= AT91C_RTTC_RTTINCIEN;

        ...
    }
}

__irq void rtt_handler(void)
{
    u_int a;

    a = *AT91C_RTTC_RTSR;
    y++;
    *AT91C_RTTC_RTMR &= ~AT91C_RTTC_RTTINCIEN;
    *AT91C_AIC_EOICR = a;
}


Номер 2, с edge sensetive прерыванием. Проще, но вылезут проблемы
при использовании других источников для SYS_IRQ.

Код
void rtt_init(void)
{
    *AT91C_RTTC_RTMR = 0x00008000 | AT91C_RTTC_RTTINCIEN | AT91C_RTTC_RTTRST;

    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (u_int)rtt_handler;
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = (0x01 << 0x05);
    AT91C_BASE_AIC->AIC_IECR = (0x01 << AT91C_ID_SYS);
}

__irq void rtt_handler(void)
{
    u_int a;

    a = *AT91C_RTTC_RTSR;
    y++;
    *AT91C_AIC_EOICR = a;
}
Go to the top of the page
 
+Quote Post
AVR
сообщение Aug 2 2006, 22:27
Сообщение #12


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Спасибо, aaarrr.
Код
#include "AT91SAM7S64.h"
#include "system.h"
typedef unsigned char byte;
byte sw = 0;

__irq void IRQ_1()
{
    unsigned int a;
    a = *AT91C_RTTC_RTSR;
    sw = !sw;
    if(sw) AT91C_BASE_PIOA->PIO_CODR = BIT30;
    else AT91C_BASE_PIOA->PIO_SODR = BIT30;
    AT91C_BASE_RTTC->RTTC_RTMR &= ~AT91C_RTTC_RTTINCIEN;
    AT91C_BASE_AIC->AIC_EOICR = a;
}

int main()
{
    AT91C_BASE_PMC->PMC_PCER = 1<<AT91C_ID_PIOA;
    AT91C_BASE_PIOA->PIO_PER |= BIT30;
    AT91C_BASE_PIOA->PIO_OER |= BIT30;
    AT91C_BASE_PIOA->PIO_CODR |= BIT30;
    AT91C_BASE_RTTC->RTTC_RTMR = 0x00008000 | AT91C_RTTC_RTTINCIEN | AT91C_RTTC_RTTRST;
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (unsigned int)IRQ_1;
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = (0x01 << 0x05);
    AT91C_BASE_AIC->AIC_IECR = (0x01 << AT91C_ID_SYS);
    while(1);
}

Всё это запустил на sam7s64 через wiggler в iar.
По-прежнему прерывание не происходит, хотя таймер тикает ~раз в секунду...
Возможно ли что всё дело в самом sam7s64? Данный код я запускаю из RAM - может ли это повлиять на работоспособность блока прерываний?


--------------------
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 2 2006, 23:21
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Ну уж одно прерывание в данном случае должно произойти.
Уберите из обработчика строку AT91C_BASE_RTTC->RTTC_RTMR &= ~AT91C_RTTC_RTTINCIEN;
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 2 2006, 23:43
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Смотрите внимательнее, оба примера рабочие.

Да, а вы уверены, что прерывание вам действительно нужно? Я бы думал, что прерывания нужнее DBGU, если он используется, конечно.

Сообщение отредактировал aaarrr - Aug 2 2006, 23:52
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Aug 3 2006, 07:01
Сообщение #15


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Почему вы так |= работаете с регистрами в АРМ.
Уних несколько хитреее чем в АВР все устроено. Для каждого набора бит, отвечающих за какие-либо периферийные функции существует три регистра, например для PIO:
1 SODR - чтобы установить высокий уровень на выводе нужно записать в соответсвующий бит еденицу.
2 CODR - чтобы сбросить вывод в низкий уровень нужно записать в соответсвующий бит ЕДЕНИЦУ
3 ODSR - чтобы узнать в каком состоянии нходится соответсвующий вывод, сконфигурированный как выход, нужно прочитать этот регистр.
Всегда читайте access type для регистров прежде чем что-либо с ними сделать. Прерывание должно работать.


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post

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

 


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


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