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

 
 
> AT91SAM7S64, FIQ от Timer
_4afc_
сообщение Aug 22 2006, 09:20
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 262
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565



Я уже поднимал эту тему, но она кудато делась.

Возможно ли на AT91SAM7S64 сделать так, чтоб на нём периодически (MCK/192) вызывались прерывания FIQ?

Если смотреть на рисунки в даташитах, то вроде AIC позволяет завернуть pit_irq или tcx_irq на FIQ. Но если рассматривать регистры, то я не представляю как это сделать.

Задача - периодически выполнять небольшой код на асм, причём с миниммальной нагрузкой на процессор - посему не хотелосьбы использовать обычный IRQ и сохранять регистры.

Неужели для этого надо вывести сигнал от таймера на ногу FIQ снаружи микросхемы?

Если кто-то считает что задача имеет решение, то прошу ответить более развёрнуто.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SpiritDance
сообщение Aug 22 2006, 10:43
Сообщение #2


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

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



Не понял.Как вы на регистры смотрели? Я не делал такого но сразу нашел регистры
AIC_FFER
AIC_FFDR
AIC_FFSR
В которые надо прописать ID соотсветсвующей периферии для редиректа, ну и сответсвенно добавить вектор обработчика
в AIC_SVR0 Есть также абзац Fast Forcing
Возможно я ошибаюсь но как-то так. Может у Вас даташит старый?

Сообщение отредактировал SpiritDance - Aug 22 2006, 11:06


--------------------
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
_4afc_
сообщение Aug 22 2006, 14:29
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 262
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565



Цитата(SpiritDance @ Aug 22 2006, 14:43) *
Не понял.Как вы на регистры смотрели? Я не делал такого но сразу нашел регистры
AIC_FFER
AIC_FFDR
AIC_FFSR
В которые надо прописать ID соотсветсвующей периферии для редиректа,


AIC_FFER я тоже нашел легко, когда понял, что это называется Fast Forcing smile.gif

Цитата(SpiritDance @ Aug 22 2006, 14:43) *
ну и сответсвенно добавить вектор обработчика
в AIC_SVR0 Есть также абзац Fast Forcing
Возможно я ошибаюсь но как-то так. Может у Вас даташит старый?


Мне удалось добиться примером приведённым ниже.

Если закомментировать Fast Forcing мигает LED1, иначе LED2.

Cstartup.S:
Код
...
    .equ AIC_IVR,         (256)
    .equ AIC_FVR,         (260)
    .equ AIC_EOICR,       (0x130)
    .equ AIC_ICCR,        (0x128)
    .equ AT91C_BASE_AIC,  (0xFFFFF000)
    .equ AT91C_BASE_PIOA, (0xFFFFF400)
    .equ PIO_PDSR,          (0x3C)
    .equ PIO_SODR,          (0x30)
    .equ PIO_CODR,          (0x34)
    .equ TC0_SR,          (0xFFFA0020)
...
fiqvec:                                           /* 0x1c FIQ    */
//================================================================================
=============
                ldr        r8,    =TC0_SR
                ldr     r9, [r8, #0]
                  ldr        r8, =AT91C_BASE_PIOA
                ldr        r9, [r8, #PIO_PDSR]
                ands    r9, #0x80000
                mov        r9, #0x80000 //LED2        
                streq    r9, [r8, #PIO_SODR]
                strne    r9, [r8, #PIO_CODR]

                //if not do this - many interrupts
                ldr        r8, =AT91C_BASE_AIC
                mov        r9, #0x1000     //AT91C_ID_TC0
                str        r9, [r8, #AIC_ICCR]

FIQ_Exit:        //Not Need here
//                ldr        r8, =AT91C_BASE_AIC
//                mov        r9, #0
//                str        r9,[r8, #AIC_EOICR]
                
                subs    pc, lr, #4


main.c:
Код
#include "Board.h"

#define TIMER0_INTERRUPT_LEVEL        1

/*-----------------*/
/* Clock Selection */
/*-----------------*/
#define TC_CLKS                  0x7
#define TC_CLKS_MCK2             0x0
#define TC_CLKS_MCK8             0x1
#define TC_CLKS_MCK32            0x2
#define TC_CLKS_MCK128           0x3
#define TC_CLKS_MCK1024          0x4

//*----------------------------------------------------------------------------
//* Function Name       : AT91F_TC_Open
//* Object              : Initialize Timer Counter Channel and enable is clock
//* Input Parameters    : <tc_pt> = TC Channel Descriptor Pointer
//*                       <mode> = Timer Counter Mode
//*                     : <TimerId> = Timer peripheral ID definitions
//* Output Parameters   : None
//*----------------------------------------------------------------------------
void AT91F_TC_Open ( AT91PS_TC TC_pt, unsigned int Mode, unsigned int TimerId)
//* Begin
{
    unsigned int dummy;

    //* First, enable the clock of the TIMER
        AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<< TimerId );

    //* Disable the clock and the interrupts
    TC_pt->TC_CCR = AT91C_TC_CLKDIS;
    TC_pt->TC_IDR = 0xFFFFFFFF;

    //* Clear status bit
        dummy = TC_pt->TC_SR;
    //* Suppress warning variable "dummy" was set but never used
        dummy = dummy;
    //* Set the Mode of the Timer Counter
    TC_pt->TC_CMR = Mode;

    //* Enable the clock
    TC_pt->TC_CCR = AT91C_TC_CLKEN;
//* End
}


__inline void AT91F_AIC_ForceIt (
    AT91PS_AIC pAic,      // \arg pointer to the AIC registers
    unsigned int irq_id ) // \arg interrupt number to initialize
{
    //* Force the interrupt to the FIQ
    pAic->AIC_FFER = 0x1 << irq_id;
}


//*----------------------------------------------------------------------------
//* Function Name       : timer0_c_irq_handler
//* Object              : C handler interrupt function called by the interrupts
//*                       assembling routine
//* Output Parameters   : increment count_timer0_interrupt
//*----------------------------------------------------------------------------
__ramfunc void timer0_c_irq_handler(void)
{
    AT91PS_TC TC_pt = AT91C_BASE_TC0;
    unsigned int dummy;
    //* Acknowledge interrupt status
    dummy = TC_pt->TC_SR;
    //* Suppress warning variable "dummy" was set but never used
    dummy = dummy;
    //* Read the output state
    if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & LED1 ) == LED1 )
    {
        AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED1 );
    }
    else
    {
        AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED1 );
    }
}

void timer_init ( void )
//* Begin
{
//* Open timer0
AT91F_TC_Open(AT91C_BASE_TC0,TC_CLKS_MCK1024,AT91C_ID_TC0);

//* Open Timer 0 interrupt
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_TC0, TIMER0_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED, timer0_c_irq_handler);
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;  //  IRQ enable CPC

// Led2 via FIQ -----------------------------------------
        AT91F_AIC_ForceIt (AT91C_BASE_AIC, AT91C_ID_TC0);
//-------------------------------------------------------

AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC0);
//* Start timer0
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
}


//*--------------------------------------------------------------------------------------
//* Function Name       : Main
//* Object              : Software entry point
//* Input Parameters    : none.
//* Output Parameters   : none.
//*--------------------------------------------------------------------------------------
int main(void)
{
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, (1 << AT91C_ID_PIOA) );
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED1|LED2);
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED1|LED2);
AT91F_PIO_CfgPullup( AT91C_BASE_PIOA,~(LED1|LED2));

timer_init();
for (;;);
}
Go to the top of the page
 
+Quote Post



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

 


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


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