📄 main.c
字号:
//*----------------------------------------------------------------------------
//* AT91SAM7S example application "gamma" (SWI, stdio, remapping...)
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//*
//* by Martin Thomas, Kaiserslautern, Germany
//* http://www.siwawi.arubi.uni-kl.de/avr_projects
//*
//* partly based on free code from Atmel Rousset, Keil/ARM and others
//*
//*----------------------------------------------------------------------------
/*
20060902 : PIT ISR-Handler in RAM (__ramfunc)
20070517 : modifications to avoid warnings with WinARM 5/07-testing
*/
#include <stdint.h>
#include <stdio.h>
#include "Board.h"
#include "dbgu.h"
#include "swi.h"
#define RTTC_INTERRUPT_LEVEL 0
#define PIV_200_MS 600000 //* 200 ms for 48 MHz
#define SWDEBOUNCE 2
volatile int sw1cnt, sw2cnt;
static const char demotext[] = "Hello\r\n";
//*----------------------------------------------------------------------------
//* Function Name : Periodic_Interval_Timer_handler
//* Object : C handler interrupt function called by the interrupts
//* assembling routine
//*----------------------------------------------------------------------------
__ramfunc void Periodic_Interval_Timer_handler(void)
{
volatile uint32_t status;
// Interrupt Acknowledge
status = AT91C_BASE_PITC->PITC_PIVR;
// status = status;
// toogle LED1
if ((AT91F_PIO_GetInput(AT91C_BASE_PIOA) & LED1 ) == LED1 ) {
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED1 );
}
else {
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED1 );
}
// detect switch-states
if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & SW1_MASK ) != SW1_MASK ) {
sw1cnt++;
}
else {
sw1cnt=0;
}
if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & SW2_MASK ) != SW2_MASK ) {
sw2cnt++;
}
else {
sw2cnt=0;
}
}
static void device_init(void)
{
// Enable User Reset and set its minimal assertion to 960 us
AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTEN | (0x4<<8) | (unsigned int)(0xA5<<24);
// Set-up the PIO
// First, enable the clock of the PIO and set the LEDs in output
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;
// then, we configure the PIO Lines corresponding to LED1 to LED4
// to be outputs. No need to set these pins to be driven by the PIO because it is GPIO pins only.
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK ) ;
// Clear the LED's. On the SAM7S-EK we must apply a "1" to turn off LEDs
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED_MASK ) ;
// define switch SW1 and SW2 at PIO input
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, SW1_MASK|SW2_MASK);
// Set-up PIT interrupt
// AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_SYS, RTTC_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, Periodic_Interval_Timer_handler);
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_SYS, RTTC_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, (void*)Periodic_Interval_Timer_handler);
AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN | AT91C_PITC_PITIEN | PIV_200_MS; // IRQ enable CPC
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SYS);
// Set-up DBGU Usart ("UART2")
AT91F_DBGU_Init();
}
static void dump_mem(unsigned long startaddress, int n)
{
unsigned long *p;
unsigned long val;
p = (unsigned long*)startaddress;
int i;
for (i=0; i<n; i++) {
val = *p;
iprintf("Addr:0x%08lx = 0x%08lx (0x%04x:0x%04x)\n",
(unsigned long)p, val,
(unsigned short)val>>16,
(unsigned short)val&0xffff);
p++;
}
}
static void dump_interrupt_state(void)
{
unsigned long cpsr;
const unsigned long I_Bit = 0x80;
const unsigned long F_Bit = 0x40;
cpsr = IntGetCPSR();
iprintf("State : stat-reg 0x%08lx -> ", cpsr);
if ( cpsr & I_Bit ) {
iprintf("IRQ disabled, ");
}
else {
iprintf("IRQ enabled, ");
}
if ( cpsr & F_Bit ) {
iprintf("FIQ disabled\n");
}
else {
iprintf("FIQ enabled\n");
}
}
static void showsp(void)
{
unsigned long mysp;
asm volatile ("mov %0, r13" : "=r" (mysp) );
iprintf("SP = 0x%08lx\n", mysp);
}
int main(void)
{
const int MAXMSG = 80;
char message[MAXMSG];
int drawmenu;
unsigned long stored_int;
unsigned long val;
unsigned int choice;
device_init(); // init interrupts and peripherals
// example "puts" with dbgu.c-function
AT91F_DBGU_Printk("\r\n\r\nAT91SAM7-Demo for the GNU-Toolchain\r\n");
// example "puts" with siprintf formated string, the integer versions
// of the newlib's printf need less memory but do not offer floating-
// point support
siprintf(message,"MCK clock frequency: %d Hz \r\n",MCK );
AT91F_DBGU_Printk(message);
AT91F_DBGU_Printk(demotext);
stored_int = IntGetCPSR(); // save initial-state
IntEnable(); // enable INT thru sWI call (not enabled in Cstartup.S)
// example printf with "newlib" - the write-routine is
// bound to the dbug-interface (see syscalls.c) so
// (i)printf output goes to DBGU (uart2)
iprintf("Demo created by Martin Thomas, Kaiserslautern, Germany\n\n");
drawmenu = 1;
// main-loop
while (1) {
if ( drawmenu ) {
iprintf("** Test Menu **\n");
iprintf("(1) INT/FIQ Status\n");
iprintf("(2) INT Enable\n");
iprintf("(3) INT Disable\n");
iprintf("(4) Push INT/FIQ state\n");
iprintf("(5) Pop INT/FIQ state\n");
iprintf("(6) FIQ Enable\n");
iprintf("(7) FIQ Disable\n");
iprintf("(8) Call Application's SWI 0x10 (toggle LED2)\n");
#ifdef LED3
iprintf("(9) Call Application's SWI 0x11 (toogle LED3)\n");
#else
// only 2 LEDs on OX-Board
iprintf("(9) Call Application's SWI 0x11\n");
#endif
iprintf("(10) Call Application's SWI 0x12 (0x55+1)\n");
iprintf("(11) Show fist values from Mem/Flash/RAM\n");
#ifdef DO_SWI_AVAIL
iprintf("(12) do_SWI(0x12, 0x55) -> 0x55+1\n");
#else
iprintf("(12) do_SWI disabled - see swi.h\n");
#endif
iprintf("(13) show SP\n");
iprintf("Select > ");
drawmenu = 0;
}
else {
iprintf("Select (0 shows menu) > ");
}
fflush(stdout);
AT91F_DBGU_scanf("%i", &choice);
iprintf("Selected %i\n", choice);
switch (choice) {
case 0 :
drawmenu = 1;
break;
case 1 :
dump_interrupt_state();
break;
case 2 :
IntEnable();
break;
case 3 :
IntDisable();
break;
case 4 :
dump_interrupt_state();
stored_int = IntGetCPSR();
iprintf("This state has been stored\n");
break;
case 5 :
iprintf("Restoreing saved state\n");
IntRestore(stored_int);
FiqRestore(stored_int);
dump_interrupt_state();
break;
case 6 :
FiqEnable();
break;
case 7 :
FiqDisable();
break;
case 8 :
asm volatile ("swi 0x10");
break;
case 9 :
SWI_CALL(0x11);
break;
case 10 :
MY_SWI_CALL_PARAM(0x12, 0x55, val); /* swi-num, in, out */
iprintf("Result from SWI-call: 0x%lx\n", val);
break;
case 11 :
// Remapping info:
iprintf("Mapped:\n");
dump_mem(INT_SRAM_REMAP, 16); // dump_mem(0x00000000, 16);
iprintf("Flash:\n");
dump_mem(INT_FLASH_REMAP, 16); // dump_mem(0x00100000, 16);
iprintf("RAM:\n");
dump_mem(INT_SRAM, 16); // dump_mem(0x00200000, 16);
break;
case 12 :
#ifdef DO_SWI_AVAIL
val = do_SWI(0x12, 0x55, 0, 0, 0);
iprintf("Result from do_SWI()-call: 0x%x\n", val);
#else
iprintf("do_SWI not available\n");
#endif
break;
case 13 :
showsp();
break;
default:
iprintf("Invalid Choice\n");
break;
}
if ( sw1cnt > SWDEBOUNCE ) {
iprintf("SW1 pressed\n");
}
if ( sw2cnt > SWDEBOUNCE ) {
iprintf("SW2 pressed\n");
}
}
return 0; /* never reached */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -