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

📄 main.c

📁 AT91SAM7 SWI, Remap, GPIO, PIT and stdio Example ( Gamma )
💻 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 + -