Вот мой код:
Использую Keil Vision 3V3.20a
#include <AT91SAM7X256.H> /* AT91SAMT7X256 definitions */
#include <lib_AT91SAM7X256.h>
#include "Board.h"
#define WAIT_TIME AT91B_MCK
#define PIO_INTERRUPT_LEVEL 6
void pio_c_irq_handler (void) __irq
{
int dummy;
//* Read the output state
if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOB) & AT91B_LED2 ) == AT91B_LED2 )
{
AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, AT91B_LED2);
}
else
{
AT91F_PIO_SetOutput( AT91C_BASE_PIOB, AT91B_LED2);
}
//* enable the next PIO IRQ
dummy =AT91C_BASE_PIOA->PIO_ISR;
//* suppress the compilation warning
dummy =dummy;
AT91C_BASE_AIC->AIC_EOICR=0x00;
//* while SW3 is push wait
// while ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & AT91B_SW5 ) != AT91B_SW5 );
}
void delay ( void )
{
volatile unsigned int i ;
for ( i = 0 ;(i < WAIT_TIME/100 );i++ ) ;
}
//*----------------------------------------------------------------------------
//* Function Name : main
//* Object : Main interrupt function
//* Input Parameters : none
//* Output Parameters : TRUE
//*----------------------------------------------------------------------------
int main( void )
//* Begin
{
// unsigned int loop_count ;
AT91PS_AIC pAic;
//* Load System pAic Base address
pAic = AT91C_BASE_AIC;
//* Init
// loop_count = 0 ;
// First, enable the clock of the PIOB
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOB ) ;
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;
AT91F_PIO_CfgOutput( AT91C_BASE_PIOB, AT91B_LED_MASK ) ;
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, AT91B_SW5 | AT91B_SW4);
AT91F_AIC_ConfigureIt ( pAic, AT91C_ID_PIOA, PIO_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, pio_c_irq_handler);
AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA,AT91B_SW4);
AT91F_AIC_EnableIt (pAic, AT91C_ID_PIOA);
AT91F_PIO_SetOutput( AT91C_BASE_PIOB, AT91B_LED_MASK ) ;
for (;;)
{
AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, AT91B_LED1 );
delay () ;
AT91F_PIO_SetOutput( AT91C_BASE_PIOB, AT91B_LED1 );
delay () ;
}
//* End
}
Вот мой Startup:
// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
I_Bit EQU 0x80 /* when I bit is set, IRQ is disabled */
F_Bit EQU 0x40 /* when F bit is set, FIQ is disabled */
// Internal Memory Base Addresses
FLASH_BASE EQU 0x00100000
RAM_BASE EQU 0x00200000
/*
// <h> Stack Configuration (Stack Sizes in Bytes)
// <o0> Undefined Mode <0x0-0xFFFFFFFF:4>
// <o1> Supervisor Mode <0x0-0xFFFFFFFF:4>
// <o2> Abort Mode <0x0-0xFFFFFFFF:4>
// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:4>
// <o4> Interrupt Mode <0x0-0xFFFFFFFF:4>
// <o5> User/System Mode <0x0-0xFFFFFFFF:4>
// </h>
*/
UND_Stack_Size EQU 0x00000004
SVC_Stack_Size EQU 0x00000004
ABT_Stack_Size EQU 0x00000004
FIQ_Stack_Size EQU 0x00000004
IRQ_Stack_Size EQU 0x00000080
USR_Stack_Size EQU 0x00000400
AREA STACK, DATA, READWRITE, ALIGN=2
DS (USR_Stack_Size+3)&~3 ; Stack for User/System Mode
DS (SVC_Stack_Size+3)&~3 ; Stack for Supervisor Mode
DS (IRQ_Stack_Size+3)&~3 ; Stack for Interrupt Mode
DS (FIQ_Stack_Size+3)&~3 ; Stack for Fast Interrupt Mode
DS (ABT_Stack_Size+3)&~3 ; Stack for Abort Mode
DS (UND_Stack_Size+3)&~3 ; Stack for Undefined Mode
Top_Stack:
// Embedded Flash Controller (EFC) definitions
EFC_BASE EQU 0xFFFFFF00 /* EFC Base Address */
EFC_FMR EQU 0x60 /* EFC_FMR Offset */
/*
// <e> Embedded Flash Controller (EFC)
// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
// <i> Number of Master Clock Cycles in 1us
// <o1.8..9> FWS: Flash Wait State
// <0=> Read: 1 cycle / Write: 2 cycles
// <1=> Read: 2 cycle / Write: 3 cycles
// <2=> Read: 3 cycle / Write: 4 cycles
// <3=> Read: 4 cycle / Write: 4 cycles
// </e>
*/
EFC_SETUP EQU 1
EFC_FMR_Val EQU 0x00320100
// Watchdog Timer (WDT) definitions
WDT_BASE EQU 0xFFFFFD40 /* WDT Base Address */
WDT_MR EQU 0x04 /* WDT_MR Offset */
/*
// <e> Watchdog Timer (WDT)
// <o1.0..11> WDV: Watchdog Counter Value <0-4095>
// <o1.16..27> WDD: Watchdog Delta Value <0-4095>
// <o1.12> WDFIEN: Watchdog Fault Interrupt Enable
// <o1.13> WDRSTEN: Watchdog Reset Enable
// <o1.14> WDRPROC: Watchdog Reset Processor
// <o1.28> WDDBGHLT: Watchdog Debug Halt
// <o1.29> WDIDLEHLT: Watchdog Idle Halt
// <o1.15> WDDIS: Watchdog Disable
// </e>
*/
WDT_SETUP EQU 1
WDT_MR_Val EQU 0x00008000
// Power Mangement Controller (PMC) definitions
PMC_BASE EQU 0xFFFFFC00 /* PMC Base Address */
PMC_MOR EQU 0x20 /* PMC_MOR Offset */
PMC_MCFR EQU 0x24 /* PMC_MCFR Offset */
PMC_PLLR EQU 0x2C /* PMC_PLLR Offset */
PMC_MCKR EQU 0x30 /* PMC_MCKR Offset */
PMC_SR EQU 0x68 /* PMC_SR Offset */
PMC_MOSCEN EQU (1<<0) /* Main Oscillator Enable */
PMC_OSCBYPASS EQU (1<<1) /* Main Oscillator Bypass */
PMC_OSCOUNT EQU (0xFF<<8) /* Main OScillator Start-up Time */
PMC_DIV EQU (0xFF<<0) /* PLL Divider */
PMC_PLLCOUNT EQU (0x3F<<8) /* PLL Lock Counter */
PMC_OUT EQU (0x03<<14) /* PLL Clock Frequency Range */
PMC_MUL EQU (0x7FF<<16) /* PLL Multiplier */
PMC_USBDIV EQU (0x03<<28) /* USB Clock Divider */
PMC_CSS EQU (3<<0) /* Clock Source Selection */
PMC_PRES EQU (7<<2) /* Prescaler Selection */
PMC_MOSCS EQU (1<<0) /* Main Oscillator Stable */
PMC_LOCK EQU (1<<2) /* PLL Lock Status */
/*
// <e> Power Mangement Controller (PMC)
// <h> Main Oscillator
// <o1.0> MOSCEN: Main Oscillator Enable
// <o1.1> OSCBYPASS: Oscillator Bypass
// <o1.8..15> OSCCOUNT: Main Oscillator Startup Time <0-255>
// </h>
// <h> Phase Locked Loop (PLL)
// <o2.0..7> DIV: PLL Divider <0-255>
// <o2.16..26> MUL: PLL Multiplier <0-2047>
// <i> PLL Output is multiplied by MUL+1
// <o2.14..15> OUT: PLL Clock Frequency Range
// <0=> 80..160MHz <1=> Reserved
// <2=> 150..220MHz <3=> Reserved
// <o2.8..13> PLLCOUNT: PLL Lock Counter <0-63>
// <o2.28..29> USBDIV: USB Clock Divider
// <0=> None <1=> 2 <2=> 4 <3=> Reserved
// </h>
// <o3.0..1> CSS: Clock Source Selection
// <0=> Slow Clock
// <1=> Main Clock
// <2=> Reserved
// <3=> PLL Clock
// <o3.2..4> PRES: Prescaler
// <0=> None
// <1=> Clock / 2 <2=> Clock / 4
// <3=> Clock / 8 <4=> Clock / 16
// <5=> Clock / 32 <6=> Clock / 64
// <7=> Reserved
// </e>
*/
PMC_SETUP EQU 1
PMC_MOR_Val EQU 0x00000601
PMC_PLLR_Val EQU 0x00191C05
PMC_MCKR_Val EQU 0x00000007
$IF (RAM_INTVEC)
// Exception Vector Area in RAM
AREA VECTORS, DATA, AT RAM_BASE
DS 64
$ENDIF
// Startup Code must be linked at address which it expects to run.
$IF (RAM_MODE)
CODE_BASE EQU RAM_BASE
$ELSE
CODE_BASE EQU FLASH_BASE
$ENDIF
AREA STARTUPCODE, CODE, AT CODE_BASE
PUBLIC __startup
EXTERN CODE32 (?C?INIT)
__startup PROC CODE32
// Pre-defined interrupt handlers that may be directly
// overwritten by C interrupt functions
EXTERN CODE32 (Undef_Handler?A)
EXTERN CODE32 (SWI_Handler?A)
EXTERN CODE32 (PAbt_Handler?A)
EXTERN CODE32 (DAbt_Handler?A)
;EXTERN CODE32 (IRQ_Handler?A)
;EXTERN CODE32 (FIQ_Handler?A)
// Exception Vectors
// Mapped to Address 0.
// Absolute addressing mode must be used.
Vectors: LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP /* Reserved Vector */
; LDR PC,IRQ_Addr
LDR PC,[PC,#-0xF20] /* Vector From AIC_IVR */
; LDR PC,FIQ_Addr
LDR PC,[PC,#-0xF20] /* Vector From AIC_FVR */
Reset_Addr: DD Reset_Handler
Undef_Addr: DD Undef_Handler?A
SWI_Addr: DD SWI_Handler?A
PAbt_Addr: DD PAbt_Handler?A
DAbt_Addr: DD DAbt_Handler?A
DD 0 /* Reserved Address */
;IRQ_Addr: DD IRQ_Handler?A
IRQ_Addr: DD 0
;FIQ_Addr: DD FIQ_Handler?A
FIQ_Addr: DD 0
// Reset Handler
Reset_Handler:
// Setup EFC
IF (EFC_SETUP != 0)
LDR R0, =EFC_BASE
LDR R1, =EFC_FMR_Val
STR R1, [R0, #EFC_FMR]
ENDIF
// Setup WDT
IF (WDT_SETUP != 0)
LDR R0, =WDT_BASE
LDR R1, =WDT_MR_Val
STR R1, [R0, #WDT_MR]
ENDIF
// Setup PMC
IF (PMC_SETUP != 0)
LDR R0, =PMC_BASE
// Setup Main Oscillator
LDR R1, =PMC_MOR_Val
STR R1, [R0, #PMC_MOR]
// Wait until Main Oscillator is stablilized
IF ((PMC_MOR_Val & PMC_MOSCEN) != 0)
MOSCS_Loop: LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MOSCS
BEQ MOSCS_Loop
ENDIF
// Setup the PLL
IF ((PMC_PLLR_Val & PMC_MUL) != 0)
LDR R1, =PMC_PLLR_Val
STR R1, [R0, #PMC_PLLR]
// Wait until PLL is stabilized
PLL_Loop: LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_LOCK
BEQ PLL_Loop
ENDIF
// Select Clock
LDR R1, =PMC_MCKR_Val
STR R1, [R0, #PMC_MCKR]
ENDIF
// Copy Exception Vectors to Internal RAM
$IF (RAM_INTVEC)
ADR R8, Vectors ; Source
LDR R9, =RAM_BASE ; Destination
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
$ENDIF
// Remap on-chip RAM to address 0
MC_BASE EQU 0xFFFFFF00 /* MC Base Address */
MC_RCR EQU 0x00 /* MC_RCR Offset */
$IF (REMAP)
LDR R0, =MC_BASE
MOV R1, #1
STR R1, [R0, #MC_RCR] ; Remap
$ENDIF
// Setup Stack for each mode
LDR R0, =Top_Stack
// Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
// Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
// Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
// Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
// Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
// Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
MOV SP, R0
// Enter the C code
LDR R0,=?C?INIT
TST R0,#1 ; Bit-0 set: main is Thumb
LDREQ LR,=exit?A ; ARM Mode
LDRNE LR,=exit?T ; Thumb Mode
BX R0
ENDP
PUBLIC exit?A
exit?A PROC CODE32
B exit?A
ENDP
PUBLIC exit?T
exit?T PROC CODE16
B exit?T
ENDP
END
Компилирую, получаю hex-файл. С помощью HEX2BIN получаю бинарник. Гружу в плату AT91SAM7256-EK c помощью самбы. Стартую с 0x100000. Запускается. Мигает диодик. При нажатии джостика программа зависает, второй диод не загорается. В симуляторе (других отладчиков нет) все прекрасно работает. Прерывание отрабатывается и происходит возвращение в основной цикл. Почему не работает в железе? Пожалуйста, подскажите если кто знает.