⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 led_blink.c

📁 uC/OS 使用gcc进行开发的例子,可以参考一下
💻 C
📖 第 1 页 / 共 3 页
字号:
    at91_reg        AIC_IMR ;           /* Interrupt Mask Register */
    at91_reg        AIC_CISR ;          /* Core Interrupt Status Register */
    at91_reg        reserved0 ;
    at91_reg        reserved1 ;
    at91_reg        AIC_IECR ;          /* Interrupt Enable Command Register */
    at91_reg        AIC_IDCR ;          /* Interrupt Disable Command Register */
    at91_reg        AIC_ICCR ;          /* Interrupt Clear Command Register */
    at91_reg        AIC_ISCR ;          /* Interrupt Set Command Register */
    at91_reg        AIC_EOICR ;         /* End of Interrupt Command Register */
} StructAIC ;

/*---------------------------------*/
/* Interrupt Source Mode Registers */
/*---------------------------------*/

/* Source Type Definition */
#define LevelSensitive              (0<<5)
#define EdgeTriggered               (1<<5)
#define LowLevel                    (0<<5)
#define NegativeEdge                (1<<5)
#define HighLevel                   (2<<5)
#define PositiveEdge                (3<<5)

#define SRCTYPE                     (3<<5)
#define PRIOR                       (7<<0)

/*---------------------------*/
/* Interrupt Status Register */
/*---------------------------*/
#define IRQID                       0x1F

/*--------------------------------*/
/* Interrupt Core Status Register */
/*--------------------------------*/
#define NFIQ                        (1<<0)
#define NIRQ                        (1<<1)

/*---------------------------------------*/
/* AIC Interrupt Handler type definition */
/*---------------------------------------*/

typedef void (*TypeAICHandler) (void) ;

/*--------------------------------*/
/* Device Dependancies Definition */
/*--------------------------------*/

/* Advanced Interrupt Controller is always at same address for vectoring */
#define AIC_BASE            ((StructAIC *) 0xFFFFF000 )

/* Interrupt Sources Definition */

#define FIQ             0
#define SWIRQ           1
#define US0IRQ          2
#define US1IRQ          3
#define TC0IRQ          4
#define TC1IRQ          5
#define TC2IRQ          6

#define WDIRQ           7
#define PIOIRQ          8

#define IRQ0            16
#define IRQ1            17
#define IRQ2            18

/* Really implemented in the 40400 not including the FIQ */
#define NB_INTERRUPT    18



//#include	"Include/prior_irq.h"
#define SW_IRQ_PRIORITY             4
#define USART0_IRQ_PRIORITY         4
#define USART1_IRQ_PRIORITY         4
#define TC0_IRQ_PRIORITY            3
#define TC1_IRQ_PRIORITY            3
#define TC2_IRQ_PRIORITY            3
#define PIO_IRQ_PRIORITY            5
#define WD_IRQ_PRIORITY             6
#define IRQ0_PRIORITY               3
#define IRQ1_PRIORITY               3
#define IRQ2_PRIORITY               3

/*----- Types and Constants Definition -----*/
/* None */

/*----- Imported Resources Definition -----*/

//#define _REFERENCE(x)   extern x;

//#include    "Library/lib_tc.c"
/* Reference the TC Interrupt Handlers written in assembler */
//extern void tc0_interrupt_handler ( void ) ;
//extern void tc1_interrupt_handler ( void ) ;
//extern void tc2_interrupt_handler ( void ) ;

/*---- Internal Resources Definition -----*/
typedef struct
{
    StructTCBlock   *TCBBase ;
    INT32U           PioPin ;
//    TypeAICHandler  TCHandler ;
    INT8U          ChannelId ;
    INT8U          PioCtrl ;
    INT8U          SourceId ;
    INT8U          SourcePrior ;
} StructConstTimer ;

const   StructConstTimer    ConstTimer[NB_TIMER] =
{
    /* Timer 0 */
    {
        TCB0_BASE,
        PIN_TC0,
//        tc0_interrupt_handler,
        (INT8U)0,
        (INT8U)PIO_TC0,
        (INT8U)TC0IRQ,
        (INT8U)TC0_IRQ_PRIORITY
    } ,
    /* Timer 1 */
    {
        TCB0_BASE,
        PIN_TC1,
//        tc1_interrupt_handler,
        (INT8U)1,
        (INT8U)PIO_TC1,
        (INT8U)TC1IRQ,
        (INT8U)TC1_IRQ_PRIORITY
    } ,
    /* Timer 2 */
    {
        TCB0_BASE,
        PIN_TC2,
//        tc2_interrupt_handler,
        (INT8U)2,
        (INT8U)PIO_TC2,
        (INT8U)TC2IRQ,
        (INT8U)TC2_IRQ_PRIORITY
    }
} ;


//#include    "Library/lib_pio.c"
/*---- Internal Resources Definition -----*/

/* PIO Controller's Constant Table Structure */
typedef struct
{
    StructPIO       *PioBase ;
//    TypeAICHandler  AsmPioHandler ;
    INT8U          PioCtrl ;
    INT8U          SourceId ;
    INT8U          SourcePrior ;
    INT8U          PioNumber ;
} StructConstPio ;

/* PIO Controller's Constant Table Structure */
const StructConstPio ConstPio[NB_PIO_CTRL] =
{
    {
        PIO_BASE,
//        pio_interrupt_handler,
        0,
        PIOIRQ,
        PIO_IRQ_PRIORITY,
        NB_PIO
    }
} ;


//#include	"Library/lib_aic.c"

//#undef _REFERENCE

/*---- Internal Resources Definition -----*/
/* None */

/*---- External Resources Definition -----*/
#define _REFERENCE(x)   x
#define CORPS
#endif

/* allocate memory for tasks' stacks */

#define	STACKSIZE	200
OS_STK	Stack1[STACKSIZE];
OS_STK	Stack2[STACKSIZE];

OS_EVENT        *Sem2;

volatile INT8U      FlagIrq , FlagSwi , FlagTask1;
volatile INT8U		need_to_swap_context;
volatile INT32U		SavedSPSR,SavedR14;

extern void IRQContextSwap(void);   /* post DispatchIRQ processing (the _real_ one) */
extern void	timer_2_isr(void);
extern void debug_led(void);

/* just 'notice' that we need to change context */

void OSIntCtxSw(void) {
    need_to_swap_context = 1;
}

/* This is what uCOS does at the start of an IRQ */
void IrqStart(void)
{
    /* increment nesting counter */
    OSIntNesting++;
}

/* This is what uCOS does at the end of an IRQ */
PrVoid IrqFinish(void)
{
    OSIntExit() ;
    return (PrVoid)NULL ;
}

void timer_irq ( StructTC *tc_pt );
void swi_irq ( void );
INT32U my_define_as_pio ( INT32U pio_ctrl_id, INT32U mask );

extern void swi_interrupt_handler(void);


/* Advanced Interrupt Controller Base Address Constant */
StructAIC   * const Pt_AICBase = AIC_BASE ;

//*P
//*-----------------------------------------------------------------------------
//* Function Name       : init_interrupt
//* Object              : Interrupt Handler Initialization
//* Input Parameters    : <irq_id>      = interrupt number to initialize
//*                     : <priority>    = priority to give to the interrupt
//*                     : <src_type>    = activation and sense of activation
//*                     : <handler_pt>  = address of the interrupt handler
//* Output Parameters   : True if <irq_id> is correct
//* Functions called    : none
//*-----------------------------------------------------------------------------
_REFERENCE (INT32U init_interrupt ( INT8U irq_id,
                                   INT8U priority,
                                   INT8U src_type,
                                   TypeAICHandler handler_pt ))
#ifdef CORPS
//* Begin
{
    INT32U       mask ;
    mask = (INT32U) 0x1 << (INT32U) irq_id ;

    //* Disable the interrupt on the interrupt controller
    Pt_AICBase->AIC_IDCR = mask ;

    //* If the interrupt number is not correct, return False
    if ( irq_id > NB_INTERRUPT ) return ( FALSE ) ;

    //* Save the interrupt handler routine pointer and the interrupt priority
    Pt_AICBase->AIC_SVR[irq_id] = (INT32U) handler_pt ;

    //* Store the Source Mode Register
    Pt_AICBase->AIC_SMR[irq_id] = (INT32U) src_type | (INT32U) priority ;

    //* Clear the interrupt on the interrupt controller
    Pt_AICBase->AIC_ICCR = mask ;

    //* Enable the interrupt on the interrupt controller
    Pt_AICBase->AIC_IECR = mask ;

    //* Return OK
    return ( TRUE ) ;
}
//* End
#endif


//*P
//*----------------------------------------------------------------------------
//* Function Name       : compute_register
//* Object              : Default TC Handler.
//* Input Parameters    : <mode> : Mode Register image pointer
//*                     : <ra> : RA Register image pointer
//*                     : <rb> : RB Register image pointer
//*                     : <rc> : RC Register image pointer
//* Output Parameters   : True if no error occurs
//* Functions called    : none
//*----------------------------------------------------------------------------
INT32U compute_register ( INT32U *mode, INT32U *ra, INT32U *rb, INT32U *rc )
{
//* Begin
    INT32U   rc_save ;

    //* Check a or b cycle higher than period, return False
    if (( *ra > *rc ) || ( *rb > *rc )) return ( FALSE ) ;

    //* If period(microsec) * MCK(MHz) div 2 < 2, return False
    if (( rc_save = ( *rc * MCKMHz ) >> 1 ) < 2 ) return ( FALSE ) ;

    //* If period(microsec) * MCK(MHz) div 2 < Counter max value
    if ( rc_save < ( 1<<16 ))
    {
        //* Select MCK/2
        *mode = TCMCK2 ;
        //* RA value is a level(microsed)*MCK(MHz) div 2
        *ra = (( *ra * MCKMHz ) >> 1 ) ;
        //* RB value is a level(microsed)*MCK(MHz) div 2
        *rb = (( *rb * MCKMHz ) >> 1 ) ;
    }
    //* Else
    else
    {
        //* If period(microsec) * MCK(MHz) div 8 < Counter max value
        if (( rc_save = ( *rc * MCKMHz ) >> 3 ) < ( 1 << 16 ))
        {
            //* Select MCK/8
            *mode = TCMCK8 ;
            //* RA value is a level(microsed)*MCK(MHz) div 8
            *ra = (( *ra * MCKMHz ) >> 3 ) ;
            //* RB value is a level(microsed)*MCK(MHz) div 8
            *rb = (( *rb * MCKMHz ) >> 3 ) ;
        }
        //* Else
        else
        {
            //* If period(microsec) * MCK(MHz) div 32 < Counter max value
            if (( rc_save = ( *rc * MCKMHz ) >> 5 ) < ( 1 << 16 ))
            {
                //* Select MCK/32
                *mode = TCMCK32 ;
                //* RA value is a level(microsed)*MCK(MHz) div 32
                *ra = (( *ra * MCKMHz ) >> 5 ) ;
                //* RB value is a level(microsed)*MCK(MHz) div 32
                *rb = (( *rb * MCKMHz ) >> 5 ) ;
            }
            //* Else
            else
            {
                //* If period(microsec) * MCK(MHz) div 128 < Counter max value
                if (( rc_save = ( *rc * MCKMHz ) >> 7 ) < ( 1 << 16 ))
                {
                    //* Select MCK/128
                    *mode = TCMCK128 ;
                    //* RA value is a level(microsed)*MCK(MHz) div 128
                    *ra = (( *ra * MCKMHz ) >> 7 ) ;
                    //* RB value is a level(microsed)*MCK(MHz) div 128
                    *rb = (( *rb * MCKMHz ) >> 7 ) ;
                }
                //* Else
                else
                {
                    //* If period(microsec) * MCK(MHz) div 1024 < Counter max value
                    if (( rc_save = ( *rc * MCKMHz ) >> 10 ) < ( 1 << 16 ))
                    {
                        //* Select MCK/1024
                        *mode = TCMCK1024 ;
                        //* RA value is a level(microsed)*MCK(MHz) div 1024
                        *ra = (( *ra * MCKMHz ) >> 10 ) ;
                        //* RB value is a level(microsed)*MCK(MHz) div 1024
                        *rb = (( *rb * MCKMHz ) >> 10 ) ;
                    }
                    //* Else
                    else
                    {
                        //* Return False
                        return ( FALSE ) ;
                    }
                    //* EndIf
                }
                //* EndIf
            }
            //* EndIf
        }
        //* EndIf
    }
    //* EndIf
    *rc = rc_save ;

    //* Return True
    return ( TRUE ) ;
}
//* End


//*P
//*----------------------------------------------------------------------------
//* Function Name       : delay_microsec
//* Object              : Run the specified handler after a defined delay in
//*                     : micro-seconds.
//* Input Parameters    : <timer_id> = the channel number to use
//*                     : <period> = period in micro-seconds
//*                     : <repeat> = if True, handler is run at each period
//*                     : <handler> = the handler to run after the delay
//* Output Parameters   : True if the arguments are correct, otherwise False
//* Functions called    : none
//*----------------------------------------------------------------------------
_REFERENCE (INT32U my_delay_microsec ( INT32U timer_id,
                                   INT32U period,
                                   INT32U repeat ))
//                                   TypeTCHandler handler ))
#ifdef CORPS
//* Begin
{
    StructTC    *tc_pt ;
    INT32U       ra, rb, rc ;
    INT32U       mode ;

    //* If timer index is too high, return False
    if ( timer_id >= NB_TIMER ) return ( FALSE ) ;

    //* Define the Timer Counter Channel Pointer
    tc_pt = &(ConstTimer[timer_id].TCBBase->
                    TC[ConstTimer[timer_id].ChannelId]) ;

    //* Compute registers value for maximum precision, if error return False
    //* Define RB as the period to enable stop on Load RB
    ra = 0 ;
    rb = period ;
    rc = period ;
    if ( compute_register ( &mode, &ra, &rb, &rc ) != TRUE ) return ( FALSE ) ;

    //* Define as pio the pins reserved for the Channel
    my_define_as_pio ( ConstTimer[timer_id].PioCtrl,
                        ConstTimer[timer_id].PioPin ) ;

    //* Save the handler in the table
//    TCHandlerTable[timer_id] = handler ;

    //* Initialize the mode of the timer
    tc_pt->TC_CMR = mode | WAVE | (repeat ? CPCTRG : CPCDIS) ;

    //* Initialize the RC Register value
    tc_pt->TC_RC = rc ;

    //* Enable the RC Compare interrupt
    tc_pt->TC_IER = CPCS ;

    //* Enable the clock of the timer
    tc_pt->TC_CCR = CLKEN ;

    //* Trig the timer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -