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

📄 at91.c

📁 uCOS-II for AT91M55800A完整实例
💻 C
字号:

/*
 * $Revision: 1.7 $
 */

#include "config.h"

static void(*rxrdy_function)();


//
// Clock initialization.
//

#if AT91_EB55
void AT91_EB55_PllStart()
{
#define APMC_MOSCS      1     // Main oscillator status bit 
#define APMC_PLL_LOCK   2     // PLL lock status 

  int i;
  
  // Speed up the System Frequency.

  __APMC_CGMR = 0x002F0002; // MOSCEN = 1, OSCOUNT = 47  (1.4ms/30祍)
 
  // Reading the APMC Status register to detect when the oscillator is stabilized
  while ((__APMC_SR & APMC_MOSCS) != APMC_MOSCS) ;

  // Commuting from Slow Clock to Main Oscillator (16Mhz)
  __APMC_CGMR = 0x002F4002; // MOSCEN = 1, OSCOUNT = 47  (1.4ms/30祍)

  // Setup the PLL to 32 MHz clock
  __APMC_CGMR = 0x032F4102; // MUL = 1, PLLCOUNT = 3, CSS = 1

  // Reading the APMC Status register to detect when the PLL is stabilized
  // Wait a little extra to ensure stable PLL.
  for (i = 0; i < 1000; i++)
  {
    while ((__APMC_SR & APMC_PLL_LOCK) != APMC_PLL_LOCK) ;
  }

  // Commuting from 16Mhz to PLL @ 32MHz
  __APMC_CGMR = 0x032F8102; // CSS = 2, MUL = 1
  
  // Now the Master clock is the output of PLL @ 32MHz
}
#endif

void AT91EnablePeripheralClocks()
{
#if AT91_EB55
  // Switch on clocks to all peripherals.
  __APMC_PCER = 0x0007effc;
#endif
}


//
// Interrupt handlers.
//




/* Serial port RX interrupt handler */
__irq __arm void usart0_rxrdy_interrupt(void)
{
  __AIC_IVR = 0; // Debug variant of vector read, protected mode is used.

  (*rxrdy_function)(); // Call RX callback function.
      
  __AIC_EOICR = 0; // Signal end of interrupt to AIC.
}


/* Undefined interrupt handler */
__irq __arm void undefined_irq(void)
{
  __AIC_IVR = 0; // Debug variant of vector read, protected mode is used.

  // Do nothing.

  __AIC_EOICR = 0; // Signal end of interrupt to AIC.
}


//
// Interrupt functions.
//

void AT91InitInterrupt()
{
#if !ANGEL
  int      irq_id ;
#endif // ANGEL

 // timer_function = timer_func;
 /// rxrdy_function = rxrdy_func;
 // can_function = can_func;
  
#if !ANGEL
  // Disable all interrupts.
  __AIC_IDCR = 0xFFFFFFFF;
  // Clear all interrupts.
  __AIC_ICCR = 0xFFFFFFFF;

  // For each priority level.
  for (irq_id = 0; irq_id < 8; irq_id++)
  {
    // Unstack a level by writting in AIC_EOICR.
    // Value written has no effect.
    __AIC_EOICR = 0;
  }

  {
    // For each interrupt source.
    __REG32 volatile* aic_smr_base = &__AIC_SMR0;
    __REG32 volatile* aic_svr_base = &__AIC_SVR0;
    for (irq_id = 0; irq_id < 32; irq_id++)
    {
      // Priority is lowest.
      aic_smr_base[irq_id] = 0 ;
      // Interrupt routine is undefined.
      aic_svr_base[irq_id] = (unsigned long)&undefined_irq;
    }
  }
  
  __AIC_SPU = (unsigned long)&undefined_irq; // Spurious interrupt vector.
  __SF_PMR = 0x27a80020; // Run AIC in protected mode.
  // Initialize ARM IRQ vector to map to interrupt controller.
  //*(unsigned long *)0x04 = 0xe1b0f00e; // ldr pc,[pc,#-0xf20]
  *(unsigned long *)0x0C = 0xe25ef004; // ldr pc,[pc,#-0xf20]
  *(unsigned long *)0x10 = 0xe25ef008; // ldr pc,[pc,#-0xf20]
  *(unsigned long *)0x18 = 0xe51fff20; // ldr pc,[pc,#-0xf20]
  *(unsigned long *)0x1C = 0xe51fff20; // ldr pc,[pc,#-0xf20]
#endif // ANGEL

#if ANGEL
  // The Angel ROM monitor code is written to allow AIC
  // protected mode. That means that from tis point it is
  // safe to look at the AIC registers from the memory and
  // register windows. Take care not to start up C-SPY with
  // AIC display active since the ROM monitor itself does not
  // Enable protected mode.
  __SF_PMR = 0x27a80020; // Run AIC in protected mode.
#endif // ANGEL
}
//---------------------------------------------------------------

//
// Timer functions.
//

//
// Serial communication functions.
//

void AT91UartInit()
{
// Don't use the serial port when run in Angel mode.
#if !ANGEL
#if AT91_EB55 || AT91_EB63
  __PIO_PDR = 0x00618000;// Disable PIO control of PA15/TXD0 and PA16/RXD0.
                         // Disable PIO control of PA21/TXD2 and PA12/RXD2.
#endif

  __US_MR = 0x000008c0; // Normal mode, 1 stop bit, no parity, async mode, 8 bits, MCK.
  __US_IDR = 0xffffffff; // Disable all USART interrupts.
  __US_IER = 1; // Interrupt on RXRDY.
  __US_TTGR = 5; // Transmit time guard in number of bit periods.
  __US_BRGR = AT91_MCK / BAUD_RATE / 16; // Set baud rate.

  __AIC_SVR2 = (unsigned long)&usart0_rxrdy_interrupt; // Usart 0 interrupt vector.
  __AIC_SMR2 = 0x63; // SRCTYPE=1, PRIOR=3. USART 0 interrupt positive edge-triggered at prio 3.
  __AIC_ICCR_bit.us0irq = 1; // Clears timer/counter 0 interrupt.
  __AIC_IECR_bit.us0irq = 1; // Enable timer/counter 0 interrupt.
  
  __AIC_ICCR = 1 << US0IRQ; // Clears usart 0 interrupt.
  __US_RTOR = 200;           //通信帧超时为20ms
  

  __US_CR = 0x000000a0; // Disable receiver, disable transmitter.
  __US_CR = 0x0000010c; // Reset status bits, reset rx/tx.
  __US_CR = 0x00000050; // Enable receiver, enable transmitter.
#endif // ANGEL
}


int AT91UartGetchar()
{
// Don't use the serial port when run in Angel mode.
#if ANGEL
  return '?';
#else
  return __US_RHR;
#endif // ANGEL
}


void AT91UartPutchar(int ch)
{
// Don't use the serial port when run in Angel mode.
#if !ANGEL
  unsigned char status;

  do {
    status = __US_CSR;
  } while ((status & 0x02) == 0); // Wait for TXRDY

  __US_THR = ch;
#endif // ANGEL
}

//
// Parallel I/O functions.
//

unsigned int AT91GetButtons()
{
  unsigned long pa; // Port A value.
  unsigned long pb; // Port B value.
  unsigned int sw1; // SW1 button.
  unsigned int sw2; // SW2 button.
  unsigned int sw3; // SW3 button.
  unsigned int sw4; // SW4 button.
  unsigned int mask; // Bit mask of buttons.

#if AT91_EB55
  // As seen from card edge: SW4 - PB19, SW3 - PB17, SW2 - PA9, SW1 - PB20
  pa = ~__PIO_PDSR; // Switch on PA9
  pb = ~__PIO_PDSRB; // Switch on PB17, PB19, PB20
  sw2  = !!(pa & 0x00000200); // pa9
  sw3 = !!(pb & 0x00020000); // pb17
  sw4 = !!(pb & 0x00080000); // pb19
  sw1 = !!(pb & 0x00100000); // pb20
#endif

  mask = (sw1 << 3) | (sw2 << 2) | (sw3 << 1) | sw4;

  return mask;
}


void AT91InitPIO()
{
#if ANGEL
// In Angel mode the serial port is already initialized and
// used by the Angel monitor.

  // Initialize port B.
  
  __PIO_PERB = 0xff00; // enable register
  __PIO_OERB = 0xff00; // output enable
  __PIO_SODRB = 0xff00; // LED's off

#else // ANGEL

  // Initialize port A.

#if AT91_EB55 || AT91_EB63
  __PIO_PER = 0x8000; // enable register (uart TX bit)
  __PIO_OER = 0x8000; // output enable (uart TX bit)
  __PIO_SODR = 0x8000; // inactive TX line
#endif

  // Initialize port B.

  __PIO_PERB = 0xff00; // enable register
  __PIO_OERB = 0xff00; // output enable
  __PIO_SODRB = 0xff00; // LED's off

#endif // ANGEL
}

//
// LED output drivers.
//

static void led_on(unsigned int mask)
{

  __PIO_CODRB = mask << 8;

}

static void led_off(unsigned int mask)
{

  __PIO_SODRB = mask << 8;

}

void AT91LedSet(unsigned int mask)
{
  led_off(0xff); // Switch off all LED's.
  led_on(mask);  // Switch on selected LED's.
}

⌨️ 快捷键说明

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