M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions
@@ -0,0 +1,15 @@
Platform support for the ATMEL AT91SAM7[XS] ARM7 microcontrollers.
This is a base platform -- it needs to be specialized for a particular
board (see sam7ex256 as an example of this) to be useful. In particular
it does not provide the platform/board.h (which must include the
correct at91sam7*h file and mux config).
TODO:
- support clock rates other than (and above) 18MHz
- compute uart divisor, PIT interval, etc from MCK
- timer hook should honor the requested interval
- current_time() should return a meaningful value
- actually pass argument to interrupt handlers?
@@ -0,0 +1,32 @@
PA0 PWM0 TIOA0
PA1 PWM1 TIOB0
PA2 PWM2 SCK0
PA3 TWD NPCS3
PA4 TWCK TCLK0
PA5 RXD0 NPCS3
PA6 TXD0 PCK0
PA7 RTS0 PWM3
PA8 CTS0 ADTRG
PA9 DRXD NPCS1
PA10 DTXD NPCS2
PA11 NPCS0 PWM0
PA12 MISO PWM1
PA13 MOSI PWM2
PA14 SPCK PWM3
PA15 TF TIOA1
PA16 TK TIOB1
PA17 TD PCK1
PA18 RD PCK2
PA19 RK FIQ
PA20 RF IRQ0
PA21 RXD1 PCK1
PA22 TXD1 NPCS3
PA23 SCK1 PWM0
PA24 RTS1 PWM1
PA25 CTS1 PWM2
PA26 DCD1 TIOA2
PA27 DTR1 TIOB2
PA28 DSR1 TCLK1
PA29 RI1 TCLK2
PA30 IRQ1 NPCS2
PA31 NPCS1 PCK2
@@ -0,0 +1,31 @@
PA0 RXD0 NC
PA1 TXD0 NC
PA2 SCK0 SPI1_NPCS1
PA3 RTS0 SPI1_NPCS2
PA4 CTS0 SPI1_NPCS3
PA5 RXD1 NC
PA6 TXD1 NC
PA7 SCK1 SPI0_NPCS1
PA8 RTS1 SPI0_NPCS2
PA9 CTS1 SPI0_NPCS3
PA10 TWD NC
PA11 TWCK NC
PA12 SPI0_NPCS0 NC
PA13 SPI0_NPCS1 PCK1
PA14 SPI0_NPCS2 IRQ1
PA15 SPI0_NPCS3 TCLK2
PA16 SPI0_MISO NC
PA17 SPI0_MOSI NC
PA18 SPI0_SPCK NC
PA19 CANRX NC
PA20 CANTX NC
PA21 TF SPI1_NPCS0
PA22 TK SPI1_SPCK
PA23 TD SPI1_MOSI
PA24 RD SPI1_MISO
PA25 RK SPI1_NPCS1
PA26 RF SPI1_NPCS2
PA27 DRXD PCK3
PA28 DTXD NC
PA29 FIQ SPI1_NPCS3
PA30 IRQ0 PCK2
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <debug.h>
#include <printf.h>
#include <platform/at91sam7.h>
#include <kernel/thread.h>
#include <stdarg.h>
void ser_init(void)
{
AT91DBGU *dbgu = AT91DBGU_ADDR;
// AT91PIO *pio = AT91PIO_ADDR;
// pio->select_a = PIN_DRXD | PIN_DTXD;
// pio->pio_disable = PIN_DRXD | PIN_DTXD;
dbgu->MR = DBGU_PAR_NONE | DBGU_MODE_NORMAL;
// dbgu->BRGR = 10; //MCK_IN_MHZ / 115200 / 16;
dbgu->BRGR = AT91_MCK_MHZ / 115200 / 16;
dbgu->CR = DBGU_RXEN | DBGU_TXEN;
}
void ser_putc(unsigned c)
{
AT91DBGU *dbgu = AT91DBGU_ADDR;
if(c == 10) {
while(!(dbgu->SR & DBGU_TXRDY));
dbgu->THR = 13;
}
while(!(dbgu->SR & DBGU_TXRDY));
dbgu->THR = c;
}
void ser_puts(const char *s)
{
AT91DBGU *dbgu = AT91DBGU_ADDR;
while(*s) {
if(*s == 10) {
while(!(dbgu->SR & DBGU_TXRDY));
dbgu->THR = 13;
}
while(!(dbgu->SR & DBGU_TXRDY));
dbgu->THR = *s++;
}
}
int dgetc(char *c, bool wait)
{
return -1;
}
void _dputc(char c)
{
ser_putc(c);
}
void platform_halt()
{
arch_disable_ints();
for(;;);
}
@@ -0,0 +1,250 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <debug.h>
#include <kernel/thread.h>
#include <kernel/mutex.h>
#include <platform/at91sam7.h>
#include <platform/debug.h>
#include <dev/ethernet.h>
#include <malloc.h>
#include <string.h>
#include <hw/mii.h>
void emac_init_send(void);
#define PHYA 31
static unsigned mi_rd(AT91EMAC *emac, unsigned addr)
{
addr &= 0x1f;
thread_sleep(20);
emac->MAN =
(1 << 30) | /* sof: 01 */
(2 << 28) | /* rw: 10 = read */
(PHYA << 23) | /* phya: PHYA */
(addr << 18) | /* rega: addr */
(2 << 16); /* code: 10 */
while(!(emac->NSR & NSR_IDLE)) ;
thread_sleep(20);
return emac->MAN & 0xffff;
}
static void mi_wr(AT91EMAC *emac, unsigned addr, unsigned val)
{
addr &= 0x1f;
val &= 0xffff;
emac->MAN =
(1 << 30) | /* sof: 01 */
(1 << 28) | /* rw: 01 = read */
(PHYA << 23) | /* phya: PHYA */
(addr << 18) | /* rega: addr */
(2 << 16) | /* code: 10 */
val; /* data: val */
while(!(emac->NSR & NSR_IDLE)) ;
}
#define PIN_EMAC_ALL 0x3ffff
#define PIN_PHY_PD (1 << 18)
#define PIN_PHY_IRQ (1 << 26)
#define PIN_PHYAD0 (1 << 26)
#define PIN_PHYAD1 (1 << 14)
#define PIN_PHYAD2 (1 << 13)
#define PIN_PHYAD3 (1 << 6)
#define PIN_PHYAD4 (1 << 5)
#define PIN_LPBK (1 << 15)
#define PIN_ISOLATE (1 << 7)
#define PIN_RMII_MODE (1 << 16)
#define PIN_RMII_BTB (1 << 4)
/* select RMII w/ BTB, 100mbps duplex autonegotiate
** disable ISOLATE and LPBK
** phya=00001b
*/
#define PIN_RESET_LOW (PIN_LPBK)
int emac_init(void)
{
AT91EMAC *emac = AT91EMAC_ADDR;
AT91PIO *piob = AT91PIOB_ADDR;
AT91PMC *pmc = AT91PMC_ADDR;
AT91RSTC *rstc = AT91RSTC_ADDR;
dprintf(INFO, "emac_init()\n");
/* enable clock to EMAC */
pmc->PCER = (1 << PID_EMAC);
thread_sleep(10);
/* for reset, all lines are gpio inputs and pullups are
enabled or disabled per strapping mode defined above */
piob->pio_enable = PIN_EMAC_ALL | PIN_PHY_PD | PIN_PHY_IRQ;
piob->select_a = PIN_EMAC_ALL;
piob->pullup_enable = PIN_EMAC_ALL | PIN_PHY_IRQ;
piob->pullup_disable = PIN_LPBK | PIN_ISOLATE | PIN_RMII_MODE;
piob->output_disable = PIN_EMAC_ALL;
/* PHY PD becomes output and high (no powerdown mode */
piob->data_set = PIN_PHY_PD;
piob->output_enable = PIN_PHY_PD;
thread_sleep(30);
dprintf(INFO, "emac_init() - reset phy\n");
/* assert the RST line and wait until the it deasserts */
rstc->CR = RSTC_KEY | RSTC_EXTRST;
while(rstc->SR & RSTC_NRSTL) ;
thread_sleep(30);
/* after reset all the gpios are assigned to the EMAC,
except for PHY_PD (which remains output and high) */
piob->pio_disable = PIN_EMAC_ALL;
emac->USRIO = USRIO_CLKEN;
thread_sleep(1000);
dprintf(INFO, "emac_init() - read state\n");
emac->NCR = NCR_MPE;
emac->NCFG = NCFG_CLK_d64;
dprintf(INFO, "bcr = %x\n", mi_rd(emac, MII_REG_BCR));
dprintf(INFO, "id1 = %x\n", mi_rd(emac, MII_REG_PHY_ID1));
dprintf(INFO, "id2 = %x\n", mi_rd(emac, MII_REG_PHY_ID2));
#if 0
unsigned state, last;
last = 0xff;
for(;;) {
state = mi_rd(emac, MII_REG_100TX_PHY) & MII_100TX_MODE_MASK;
if(last != state) {
last = state;
char *name;
switch(state) {
case MII_100TX_MODE_AUTO:
name = "auto negotiate";
break;
case MII_100TX_MODE_10T_H:
name = "10-T half duplex";
break;
case MII_100TX_MODE_10T_F:
name = "10-T full duplex";
break;
case MII_100TX_MODE_100TX_H:
name = "100-TX half duplex";
break;
case MII_100TX_MODE_100TX_F:
name = "100-TX full duplex";
break;
case MII_100TX_MODE_ISOLATE:
name = "isolate";
break;
default:
name = "unknown";
}
dprintf(INFO, "link state: %s\n", name);
}
thread_sleep(100);
}
#endif
emac_init_send();
return 0;
}
#define XMIT_ENTRY_COUNT 32
static emac_xmit_entry xmit_list[XMIT_ENTRY_COUNT];
static unsigned xmit_next = 0;
static mutex_t xmit_lock;
void emac_init_send(void)
{
AT91EMAC *emac = AT91EMAC_ADDR;
int i;
for(i = 0; i < XMIT_ENTRY_COUNT; i++) {
xmit_list[i].info = XMIT_USED;
xmit_list[i].addr = 0;
}
xmit_list[i-1].info |= XMIT_LAST;
emac->NCFG = NCFG_CLK_d64 | NCFG_SPD | NCFG_FD;
emac->NCR = NCR_TE | NCR_MPE;
emac->TBQP = (unsigned) xmit_list;
mutex_init(&xmit_lock);
}
int ethernet_send(void *data, unsigned len)
{
AT91EMAC *emac = AT91EMAC_ADDR;
emac_xmit_entry *xe;
int waited = 0;
mutex_acquire(&xmit_lock);
xe = xmit_list + xmit_next;
while(!(xe->info & XMIT_USED)) {
thread_yield();
waited++;
}
if(waited) dprintf(INFO, "W%d\n",waited);
if(xe->addr != 0) {
free((void*) xe->addr);
}
xe->addr = (unsigned) data;
if(xmit_next == (XMIT_ENTRY_COUNT - 1)) {
xe->info = XMIT_LENGTH(len) | XMIT_LAST | XMIT_WRAP;
xmit_next = 0;
} else {
xe->info = XMIT_LENGTH(len) | XMIT_LAST;
xmit_next++;
}
emac->NCR |= NCR_TSTART;
mutex_release(&xmit_lock);
return 0;
}
@@ -0,0 +1,794 @@
/* at91sam7s.h -- AT91SAM7S hardware definitions
**
** Copyright 2006, Brian Swetland. All rights reserved.
** See provided LICENSE file or http://frotz.net/LICENSE for details.
*/
#ifndef __PLATFORM_AT91SAM7_H__
#define __PLATFORM_AT91SAM7_H__
#if !defined(AT91_SAM7X) && !defined(AT91_SAM7S)
#error Unspecified Architecture - AT91SAM7S or AT91SAM7X must be defined
#endif
/* peripheral ids */
#define PID_AIC_FIQ 0
#define PID_SYSIRQ 1
#define PID_PIOA 2
#define PID_USART0 6
#define PID_USART1 7
#define PID_SSC 8
#define PID_TWI 9
#define PID_PWMC 10
#define PID_UDP 11
#define PID_TC0 12
#define PID_TC1 13
#define PID_TC2 14
#if AT91_SAM7X
#define PID_PIOB 3
#define PID_SPI0 4
#define PID_SPI1 5
#define PID_CAN 15
#define PID_EMAC 16
#define PID_ADC 17
#define PID_AIC_IRQ0 30
#define PID_AIC_IRQ1 31
#else
#define PID_ADC 4
#define PID_SPI0 5
#define PID_AIC_IRQ 30
#endif
#define BASE_FLASH 0x00100000
#define BASE_SRAM 0x00200000
#define BASE_TC 0xFFFA0000
#define BASE_UDP 0xFFFB0000
#define BASE_TWI 0xFFFB8000
#define BASE_USART0 0xFFFC0000
#define BASE_USART1 0xFFFC4000
#define BASE_PWMC 0xFFFCC000
#define BASE_SSC 0xFFFD4000
#define BASE_ADC 0xFFFD8000
#define BASE_SPI0 0xFFFE0000
#define BASE_AIC 0xFFFFF000
#define BASE_DBGU 0xFFFFF200
#define BASE_PIOA 0xFFFFF400
#define BASE_PMC 0xFFFFFC00
#define BASE_RSTC 0xFFFFFD00
#define BASE_RTT 0xFFFFFD20
#define BASE_PIT 0xFFFFFD30
#define BASE_WDT 0xFFFFFD40
#define BASE_VREG 0xFFFFFD60
#define BASE_MC 0xFFFFFF00
#if AT91_SAM7X
#define BASE_CAN 0xFFFD0000
#define BASE_EMAC 0xFFFDC000
#define BASE_SPI1 0xFFFE4000
#define BASE_PIOB 0xFFFFF600
#endif
typedef volatile unsigned int vu4;
typedef struct
{
vu4 MR;
vu4 SR;
vu4 PIVR;
vu4 PIIR;
} AT91PIT;
/* MR */
#define PIT_PITEN (1 << 24)
#define PIT_PITIEN (1 << 25)
/* SR */
#define PIT_PITS (1)
/* PIxR */
#define PIT_PICNT(x) (x >> 20)
#define PIT_CPIV(x) (x & 0x000fffff)
#define AT91PIT_ADDR ((AT91PIT*) BASE_PIT)
typedef struct
{
vu4 CR;
vu4 MR;
vu4 IER;
vu4 IDR;
vu4 IMR;
vu4 SR;
vu4 RHR;
vu4 THR;
vu4 BRGR;
vu4 __0[7];
vu4 CIDR;
vu4 EXID;
vu4 FNR;
} AT91DBGU;
/* CR bits */
#define DBGU_RSTRX 0x00000004
#define DBGU_RSTTX 0x00000008
#define DBGU_RXEN 0x00000010
#define DBGU_RXDIS 0x00000020
#define DBGU_TXEN 0x00000040
#define DBGU_TXDIS 0x00000080
#define DBGU_RSTSTA 0x00000100
/* MR bits */
#define DBGU_PAR_EVEN 0x00000000
#define DBGU_PAR_ODD 0x00000200
#define DBGU_PAR_SPACE 0x00000400
#define DBGU_PAR_MARK 0x00000600
#define DBGU_PAR_NONE 0x00000800
#define DBGU_MODE_NORMAL 0x00000000
#define DBGU_MODE_ECHO 0x0000C000
#define DBGU_MODE_LLOOP 0x00008000
#define DBGU_MODE_RLOOP 0x00004000
/* IER, IDR, IMR, and SR bits */
#define DBGU_RXRDY 0x00000001
#define DBGU_TXRDY 0x00000002
#define DBGU_ENDRX 0x00000008
#define DBGU_ENDTX 0x00000010
#define DBGU_OVRE 0x00000020
#define DBGU_FRAME 0x00000040
#define DBGU_PARE 0x00000080
#define DBGU_TXEMPTY 0x00000200
#define DBGU_TXBUFE 0x00000800
#define DBGU_RXBUFF 0x00001000
#define DBGU_COMMTX 0x40000000
#define DBGU_COMMRX 0x80000000
#define AT91DBGU_ADDR ((AT91DBGU*) BASE_DBGU)
typedef struct
{
vu4 pio_enable;
vu4 pio_disable;
vu4 pio_status;
vu4 __0;
vu4 output_enable;
vu4 output_disable;
vu4 output_status;
vu4 __1;
vu4 filter_enable;
vu4 filter_disable;
vu4 filter_status;
vu4 __2;
vu4 data_set;
vu4 data_clear;
vu4 data_status;
vu4 pin_status;
vu4 irq_enable;
vu4 irq_disable;
vu4 irq_mask;
vu4 irq_status;
vu4 multidriver_enable;
vu4 multidriver_disable;
vu4 multidriver_status;
vu4 __3;
vu4 pullup_disable;
vu4 pullup_enable;
vu4 pullup_status;
vu4 __4;
vu4 select_a;
vu4 select_b;
vu4 select_status;
vu4 __5[9];
vu4 write_enable;
vu4 write_disable;
vu4 write_status;
} AT91PIO;
#define AT91PIOA_ADDR ((AT91PIO*) BASE_PIOA)
#if AT91_SAM7X
#define AT91PIOB_ADDR ((AT91PIO*) BASE_PIOB)
#endif
typedef struct
{
vu4 SCER;
vu4 SCDR;
vu4 SCSR;
vu4 __0;
vu4 PCER;
vu4 PCDR;
vu4 PCSR;
vu4 __1;
vu4 MOR;
vu4 MCFR;
vu4 __2;
vu4 PLLR;
vu4 MCKR;
vu4 __3[2];
vu4 PCK0;
vu4 PCK1;
vu4 PCK2;
} AT91PMC;
#define AT91PMC_ADDR ((AT91PMC*) BASE_PMC)
/* PMC_SCER/SCDR */
#define PMC_PCK 0x00000001
#define PMC_UDP 0x00000080
#define PMC_PCK0 0x00000100
#define PMC_PCK1 0x00000200
#define PMC_PCK2 0x00000400
typedef struct
{
vu4 CR;
vu4 MR;
vu4 RDR;
vu4 TDR;
vu4 SR;
vu4 IER;
vu4 IDR;
vu4 IMR;
vu4 __0[4];
vu4 CSR0;
vu4 CSR1;
vu4 CSR2;
vu4 CSR3;
} AT91SPI;
#define AT91SPI0_ADDR ((AT91SPI*) BASE_SPI0)
#if AT91_SAM7X
#define AT91SPI1_ADDR ((AT91SPI*) BASE_SPI0)
#endif
/* CR bits */
#define SPI_SPIEN 0x00000001
#define SPI_SPIDIS 0x00000002
#define SPI_SWRST 0x00000080
#define SPI_LASTXFER 0x01000000
/* MR bits */
#define SPI_MSTR 0x00000001
#define SPI_PS 0x00000002
#define SPI_PCSDEC 0x00000004
#define SPI_MODFDIS 0x00000010
#define SPI_LLB 0x00000080
#define SPI_DLYBCS(n) (((n) & 0xff) << 24)
#define SPI_PCS0 0x000e0000
#define SPI_PCS1 0x000d0000
#define SPI_PCS2 0x000b0000
#define SPI_PCS3 0x00070000
/* SR bits */
#define SPI_RDRF 0x00000001 /* recv data reg full */
#define SPI_TDRE 0x00000002 /* xmit data reg empty */
#define SPI_MODF 0x00000004 /* mode fault error */
#define SPI_OVRES 0x00000008 /* overrun error */
#define SPI_ENDRX 0x00000010 /* end of rx buffer */
#define SPI_ENDTX 0x00000020 /* end of tx buffer */
#define SPI_RXBUFF 0x00000040 /* rx buffer full */
#define SPI_TXBUFE 0x00000080 /* tx buffer empty */
#define SPI_NSSR 0x00000100 /* rising edge on NSS */
#define SPI_TXEMPTY 0x00000200 /* transmission regs empty */
#define SPI_SPIENS 0x00010000
typedef struct
{
vu4 FRM_NUM;
vu4 GLB_STAT;
vu4 FADDR;
vu4 __0;
vu4 IER;
vu4 IDR;
vu4 IMR;
vu4 ISR;
vu4 ICR;
vu4 __1;
vu4 RST_EP;
vu4 __2;
vu4 CSR0;
vu4 CSR1;
vu4 CSR2;
vu4 CSR3;
vu4 __3[4];
vu4 FDR0;
vu4 FDR1;
vu4 FDR2;
vu4 FDR3;
vu4 __4[5];
vu4 TXVC;
} AT91UDP;
#define AT91UDP_ADDR ((AT91UDP*) BASE_UDP)
// GLB_STAT bits
#define UDP_FADDEN 0x00000001
#define UDP_CONFG 0x00000002
#define UDP_ESR 0x00000004
#define UDP_RSMINPR 0x00000008
#define UDP_RMWUPE 0x00000010
// FADDR bits
#define UDP_FEN 0x00000100
// interrupt bits
#define UDP_EP0INT 0x00000001
#define UDP_EP1INT 0x00000002
#define UDP_EP2INT 0x00000004
#define UDP_EP3INT 0x00000008
#define UDP_RXSUSP 0x00000100
#define UDP_RXRSM 0x00000200
#define UDP_EXTRSM 0x00000400
#define UDP_SOFINT 0x00000800
#define UDP_ENDBUSRES 0x00001000
#define UDP_WAKEUP 0x00002000
// RST_EP bits
#define UDP_EP0 0x00000001
#define UDP_EP1 0x00000002
#define UDP_EP2 0x00000004
#define UDP_EP3 0x00000008
// CSR bits
#define UDP_TXCOMP 0x00000001
#define UDP_RX_DATA_BK0 0x00000002
#define UDP_RXSETUP 0x00000004
#define UDP_STALLSENT 0x00000008
#define UDP_ISOERROR 0x00000008
#define UDP_TXPKTRDY 0x00000010
#define UDP_FORCESTALL 0x00000020
#define UDP_RX_DATA_BK1 0x00000040
#define UDP_DIR 0x00000080
#define UDP_DTGL 0x00000800
#define UDP_EPEDS 0x00008000
#define UDP_TYPE_CONTROL 0x00000000
#define UDP_TYPE_ISOCH_OUT 0x00000100
#define UDP_TYPE_BULK_OUT 0x00000200
#define UDP_TYPE_INT_OUT 0x00000300
#define UDP_TYPE_ISOCH_IN 0x00000500
#define UDP_TYPE_BULK_IN 0x00000600
#define UDP_TYPE_INT_IN 0x00000700
typedef struct
{
vu4 SMR[32];
vu4 SVR[32];
vu4 IVR;
vu4 FVR;
vu4 ISR;
vu4 IPR;
vu4 IMR;
vu4 CISR;
vu4 __0[2];
vu4 IECR;
vu4 IDCR;
vu4 ICCR;
vu4 ISCR;
vu4 EOICR;
vu4 SPU;
vu4 DCR;
vu4 __1;
vu4 FFER;
vu4 FFDR;
vu4 FFSR;
} AT91AIC;
#define AT91AIC_ADDR ((AT91AIC*) BASE_AIC)
typedef struct
{
vu4 CR;
vu4 MR;
vu4 IER;
vu4 IDR;
vu4 IMD;
vu4 CSR;
vu4 RHR;
vu4 THR;
vu4 BRGR;
vu4 RTOR;
vu4 TTGR;
vu4 __0[5];
vu4 FIDI;
vu4 NER;
vu4 __1;
vu4 IF;
vu4 MAN;
} AT91USART;
#define AT91USART0_ADDR ((AT91USART*) 0xFFFC0000)
#define AT91USART1_ADDR ((AT91USART*) 0xFFFC4000)
/* CR */
#define USART_RSTRX 0x00000004
#define USART_RSTTX 0x00000008
#define USART_RXEN 0x00000010
#define USART_RXDIS 0x00000020
#define USART_TXEN 0x00000040
#define USART_TXDIS 0x00000080
#define USART_RSTSTA 0x00000100
#define USART_STTBRK 0x00000200
#define USART_STPBRK 0x00000400
#define USART_STTTO 0x00000800
#define USART_SENDA 0x00001000
#define USART_RSTIT 0x00002000
#define USART_RSTNACK 0x00004000
#define USART_RETTO 0x00008000
#define USART_DTREN 0x00010000
#define USART_DTRDIS 0x00020000
#define USART_RTSEN 0x00040000
#define USART_RTSDIS 0x00080000
/* MR */
#define USART_MODE_NORMAL 0x00000000
#define USART_MODE_RS485 0x00000001
#define USART_MODE_HWHS 0x00000002
#define USART_MODE_MODEM 0x00000003
#define USART_MODE_ISO7816T0 0x00000004
#define USART_MODE_ISO7816T1 0x00000006
#define USART_MODE_IRDA 0x00000008
#define USART_CLK_MCK 0x00000000
#define USART_CLK_MCK_DIV 0x00000010
#define USART_CLK_SCK 0x00000030
#define USART_CHRL_5BITS 0x00000000
#define USART_CHRL_6BITS 0x00000040
#define USART_CHRL_7BITS 0x00000080
#define USART_CHRL_8BITS 0x000000C0
#define USART_SYNCHRONOUS 0x00000100
#define USART_PARITY_EVEN 0x00000000
#define USART_PARITY_ODD 0x00000200
#define USART_PARITY_SPACE 0x00000400
#define USART_PARITY_MARK 0x00000600
#define USART_PARITY_NONE 0x00000800
#define USART_PARITY_MULTIDROP 0x00000C00
#define USART_1STOP 0x00000000
#define USART_1X5STOP 0x00001000
#define USART_2STOP 0x00002000
#define USART_CHMODE_NORMAL 0x00000000
#define USART_CHMODE_ECHO 0x00004000
#define USART_CHMODE_LLOOP 0x00008000
#define USART_CHMODE_RLOOP 0x0000C000
#define USART_MSBF 0x00010000
#define USART_MODE9 0x00020000
#define USART_CLKO 0x00040000
#define USART_OVER 0x00080000
#define USART_INACK 0x00100000
#define USART_DSNACK 0x00200000
#define USART_VAR_SYNC 0x00400000
#define USART_FILTER 0x10000000
#define USART_MAN 0x20000000
#define USART_ONEBIT 0x80000000
/* CSR */
#define USART_RXRDY 0x00000001
#define USART_TXRDY 0x00000002
#define USART_RXBRK 0x00000004
#define USART_ENDRX 0x00000008
#define USART_ENDTX 0x00000010
#define USART_OVRE 0x00000020
#define USART_FRAME 0x00000040
#define USART_PARE 0x00000080
#define USART_TIMEOUT 0x00000100
#define USART_TXEMPTY 0x00000200
#define USART_ITERATION 0x00000400
#define USART_TXBUFE 0x00000800
#define USART_RXBUFF 0x00001000
#define USART_NACK 0x00002000
typedef struct
{
vu4 CR;
vu4 SR;
vu4 MR;
} AT91RSTC;
#define RSTC_KEY 0xA5000000
/* cr */
#define RSTC_PROCRST 0x00000001
#define RSTC_PERRST 0x00000004
#define RSTC_EXTRST 0x00000008
/* sr */
#define RSTC_URSTS 0x00000001
#define RSTC_BODSTS 0x00000002
#define RSTC_RSTTYP_MASK 0x00000070
#define RSTC_RSTTYP_COLD 0x00000000
#define RSTC_RSTTYP_WATCHDOG 0x00000020
#define RSTC_RSTTYP_SOFTWARE 0x00000030
#define RSTC_RSTTYP_NRST_PIN 0x00000040
#define RSTC_RSTTYP_BROWNOUT 0x00000060
#define RSTC_NRSTL 0x00010000
#define RSTC_SRCMP 0x00020000
/* mr */
#define RSTC_URSTEN 0x00000001
#define RSTC_URSTIEN 0x00000010
#define RSTC_ERSTL(n) (((n) & 0xf) << 8)
#define RSTC_BODIEN 0x00010000
#define AT91RSTC_ADDR ((AT91RSTC*) BASE_RSTC)
#if AT91_SAM7X
typedef struct
{
vu4 NCR;
vu4 NCFG;
vu4 NSR;
vu4 __0;
vu4 __1;
vu4 TSR;
vu4 RBQP;
vu4 TBQP;
vu4 RSR;
vu4 ISR;
vu4 IER;
vu4 IDR;
vu4 IMR;
vu4 MAN;
vu4 PTR;
vu4 PFR;
vu4 FTO;
vu4 SCF;
vu4 MCF;
vu4 FRO;
vu4 FCSE;
vu4 ALE;
vu4 DTF;
vu4 LCOL;
vu4 ECOL;
vu4 TUND;
vu4 CSE;
vu4 RRE;
vu4 ROV;
vu4 RSE;
vu4 ELE;
vu4 RJA;
vu4 USF;
vu4 STE;
vu4 RLE;
vu4 __2;
vu4 HRB;
vu4 HRT;
vu4 SA1B;
vu4 SA1T;
vu4 SA2B;
vu4 SA2T;
vu4 SA3B;
vu4 SA3T;
vu4 SA4B;
vu4 SA5T;
vu4 TID;
vu4 __3;
vu4 USRIO;
} AT91EMAC;
#define NCR_LB 0x00000001
#define NCR_LLB 0x00000002
#define NCR_RE 0x00000004
#define NCR_TE 0x00000008
#define NCR_MPE 0x00000010
#define NCR_CLRSTAT 0x00000020
#define NCR_INCSTAT 0x00000040
#define NCR_WESTAT 0x00000080
#define NCR_BP 0x00000100
#define NCR_TSTART 0x00000200
#define NCR_THALT 0x00000400
#define NCFG_SPD 0x00000001
#define NCFG_FD 0x00000002
#define NCFG_JFRAME 0x00000008
#define NCFG_CAF 0x00000010
#define NCFG_NBC 0x00000020
#define NCFG_MTI 0x00000040
#define NCFG_UNI 0x00000080
#define NCFG_BIG 0x00000100
#define NCFG_CLK_d8 0x00000000
#define NCFG_CLK_d16 0x00000400
#define NCFG_CLK_d32 0x00000800
#define NCFG_CLK_d64 0x00000C00
#define NCFG_RTY 0x00001000
#define NCFG_PAE 0x00002000
#define NCFG_RBOF_0 0x00000000
#define NCFG_RBOF_1 0x00004000
#define NCFG_RBOF_2 0x00008000
#define NCFG_RBOF_3 0x0000C000
#define NCFG_RLCE 0x00010000
#define NCFG_DRFCS 0x00020000
#define NCFG_EFRHD 0x00040000
#define NCFG_IRXFCS 0x00080000
#define NSR_MDIO 0x00000002
#define NSR_IDLE 0x00000004
#define TSR_UBR 0x00000001
#define TSR_COL 0x00000002
#define TSR_RLE 0x00000004
#define TSR_TGO 0x00000008
#define TSR_BEX 0x00000010
#define TSR_COMP 0x00000020
#define TSR_UND 0x00000040
#define RSR_BNA 0x00000001
#define RSR_REC 0x00000002
#define RSR_OVR 0x00000004
#define ISR_MFD 0x00000001
#define ISR_RCOMP 0x00000002
#define ISR_RXUBR 0x00000004
#define ISR_TXUBR 0x00000008
#define ISR_TUND 0x00000010
#define ISR_RLE 0x00000020
#define ISR_TXERR 0x00000040
#define ISR_TCOMP 0x00000080
#define ISR_ROVR 0x00000400
#define ISR_HRESP 0x00000800
#define ISR_PFR 0x00001000
#define ISR_PTZ 0x00002000
#define USRIO_RMII 0x00000001
#define USRIO_CLKEN 0x00000002
#define AT91EMAC_ADDR ((AT91EMAC*) BASE_EMAC)
typedef struct
{
vu4 addr;
vu4 info;
} emac_xmit_entry;
#define XMIT_USED 0x80000000
#define XMIT_WRAP 0x40000000
#define XMIT_ERR_RETRY 0x20000000
#define XMIT_ERR_UNDERRUN 0x10000000
#define XMIT_ERR_EXHAUSTED 0x08000000
#define XMIT_NO_CRC 0x00010000
#define XMIT_LAST 0x00008000
#define XMIT_LENGTH(n) ((n) & 0x3FF)
/* CAN Registers */
typedef struct
{
vu4 MMR; /* Mailbox Mode Register */
vu4 MAM; /* Mailbox Acceptance Mask Register */
vu4 MID; /* Mailbox ID Register */
vu4 MFID; /* Mailbox Family ID Register */
vu4 MSR; /* Mailbox Status Register */
vu4 MDL; /* Mailbox Data Low Register */
vu4 MDH; /* Mailbox Data High Register */
vu4 MCR; /* Mailbox Control Register */
} AT91CAN_MAILBOX;
typedef struct
{
vu4 MR; /* Mode Register */
vu4 IER; /* Interrupt Enable Register */
vu4 IDR; /* Interrupt Disable Register */
vu4 IMR; /* Interrupt Mask Register */
vu4 SR; /* Status Register */
vu4 BR; /* Baudrate Register */
vu4 TIM; /* Timer Register */
vu4 TIMESTP; /* Timestamp Register */
vu4 ECR; /* Error Counter Register */
vu4 TCR; /* Transfer Command Register */
vu4 ACR; /* Abort Command Register */
vu4 __0[53]; /* 0x002c - 0x0100 is undefined */
vu4 __1[63]; /* 0x0200 - 0x01fc is reserved */
AT91CAN_MAILBOX Mailbox[8];
} AT91CAN;
#define CAN_CANEN 0x00000001 /* CAN Controller Enable */
#define CAN_LPM 0x00000002 /* Enable Low Power Mode */
#define CAN_ABM 0x00000004 /* Enable Autoband/Listen Mode */
#define CAN_OVL 0x00000008 /* Enable Overload Frame */
#define CAN_TEOF 0x00000010 /* Timestamp Messages at each Frame */
#define CAN_TTM 0x00000020 /* Enable Time Trigger Mode */
#define CAN_TIMFRZ 0x00000040 /* Enable Timer Freeze */
#define CAN_DRPT 0x00000080 /* Disable Repeat */
#define CAN_MB(x) (0x00000001 << x) /* Enable Interrupt Enable */
#define CAN_ERRA 0x00010000 /* Enable Error Active Mode Interrupt */
#define CAN_WARN 0x00020000 /* Enable Warning Limit Interrupt */
#define CAN_ERRP 0x00040000 /* Enable Passive mode interrupt */
#define CAN_BOFF 0x00080000 /* Enable Bus-off mode interrupt */
#define CAN_SLEEP 0x00100000 /* Enable Sleep Interrupt */
#define CAN_WAKEUP 0x00200000 /* Enable Wakeup Interrupt */
#define CAN_TOVF 0x00400000 /* Enable Timer Overflow Interrupt */
#define CAN_TSTP 0x00800000 /* Enable TimeStamp Interrupt */
#define CAN_CERR 0x01000000 /* Enable CRC Error Interrupt */
#define CAN_SERR 0x02000000 /* Enable Stuffing Error Interrupt */
#define CAN_AERR 0x04000000 /* Enable Acknowledgement Error Int */
#define CAN_FERR 0x08000000 /* Enable Form Error Interrupt */
#define CAN_BERR 0x10000000 /* Enable Bit Error Interrupt */
#define CAN_RBSY 0x20000000 /* Receiver Busy */
#define CAN_TBSY 0x40000000 /* Transmitter Busy */
#define CAN_OVLSY 0x80000000 /* Overload Busy */
/* Can Baudrate Regiister */
#define CAN_PHASE2(x) (x)
#define CAN_PHASE2_MASK 0x07
#define CAN_PHASE1(x) (x<<4)
#define CAN_PHASE1_MASK (0x07 << 4)
#define CAN_PROPAG(x) (x<<8)
#define CAN_PROPAG_MASK (0x07 << 8)
#define CAN_SJW(x) (x<<12)
#define CAN_SJW_MASK(x) (0x03 << 12)
#define CAN_BRP(x) (x<<16)
#define CAN_BRP_MASK (0x7f << 16)
#define CAN_SMP 0x01000000 /* Sampling Mode */
/* CAN Transfer Command Register */
#define TCR_TIMRST 0x80000000 /* Timer Reset */
/* CAN Message Mode Register */
#define CAN_MTIMEMARK(x) (0x0000001 << x)
#define CAN_PRIOR(x) (x << 16)
#define CAN_MOT(x) (x << 24)
#define CAN_MIDVB(x) (x)
#define CAN_MIDVA(x) (x << 18)
#define CAN_MIDE 0x20000000
/* CAN MSRx */
/* These are receive, so pass in the value of the register... */
#define CAN_MTIMESTAMP(x) (x & 0x0000ffff)
#define CAN_MDLC(x) ( (x >> 16) & 0x0f) /* Mailbox code length */
#define CAN_MRTR 0x00100000 /* Mailbox Remote Trx Request*/
#define CAN_MABT 0x00400000 /* Mailbox Message Abort */
#define CAN_MRDY 0x00800000 /* Mailbox Ready */
#define CAN_MMI 0x01000000 /* Mailbox Message Ignored */
/* Message Control Register */
//#define CAN_MDLC(x) (x<<16) /* Mailbox Data Length Code */
#define CAN_MACR (0x01 << 22) /* Abort Request */
#define CAN_MTCR (0x01 << 23) /* Mailbox Transfer Command */
#define AT91CAN_ADDR ((AT91CAN*) BASE_CAN)
#endif
#endif
@@ -0,0 +1,101 @@
/* init_clock.S -- AT91SAM7 clock coldstart code
**
** Copyright 2006, Brian Swetland. All rights reserved.
** See provided LICENSE file or http://frotz.net/LICENSE for details.
*/
.globl init_clock
init_clock:
/* init flash controller timing for 18.432MHz */
mov r1, #0xffffff00
ldr r0, =0x00340100
str r0, [r1, #0x60]
#define PMC_MOR 0x20
#define PMC_MCFR 0x24
#define PMC_PLLR 0x2c
#define PMC_MCKR 0x30
#define PMC_SR 0x68
/* PMC_MOR */
#define PMC_MOSCEN 0x01
#define PMC_OSCBYPASS 0x02
/* PMC_MCFR */
#define PMC_MAINRDY 0x00010000
/* PMC_SR */
#define PMC_MOSCS 0x01
#define PMC_LOCK 0x04
#define PMC_MCKRDY 0x08
/* PMC_MCKR */
#define PMC_CSS_SLOW 0x00
#define PMC_CSS_MAIN 0x01
#define PMC_CSS_PLL 0x03
#define PMC_PRES_NONE 0x00
#define PMC_PRES_DIV2 0x04
#define PMC_PRES_DIV4 0x08
/* Oscillator Init Sequence based on the Atmel sample code
** in cstartup_boot_SAM7S32_64.s
**
** I cleaned it up a bit -- why they use a temporary register,
** AND and then CMP instead of just TSTing against an immediate
** boggles my mind. I think this could be a bit simpler yet,
** but debugging it is a pain, so Good Enough wins for now.
*/
ldr r1, =0xfffffc00
/* bypass main oscillator */
mov r0, #PMC_OSCBYPASS
str r0, [r1, #PMC_MOR]
/* compensate MAINRDY rising flag (45 SCLK) */
mov r0, #45
1: subs r0, r0, #1
bhi 1b
/* if MAINRDY is set, we have an external oscillator */
ldr r0, [r1, #PMC_MCFR]
tst r0, #PMC_MAINRDY
bne ext_osc_found
/* reset MOSCS flag */
mov r0, #0
str r0, [r1, #PMC_MOR]
/* enable main oscillator */
ldr r0, =((0x40 << 8) | PMC_MOSCEN)
str r0, [r1, #PMC_MOR]
/* wait for main oscillator to come online */
1: ldr r0, [r1, #PMC_SR]
tst r0, #PMC_MOSCS
beq 1b
ext_osc_found:
/* select main oscillator, no prescaler for MCK */
mov r0, #(PMC_CSS_MAIN | PMC_PRES_NONE)
str r0, [r1, #PMC_MCKR]
/* wait until MCK settles to continue */
1: ldr r0, [r1, #PMC_SR]
tst r0, #PMC_MCKRDY
beq 1b
/* this is a bit of voodoo for selecting a 96.109MHz PLL
** freq (MUL=72, DIV=14, OUT=0, USBDIV=/1) from the 18.432MHz
** main clock.
*/
ldr r0, =0x10483f0e
str r0, [r1, #PMC_PLLR]
/* let the PLL lock before we continue */
1: ldr r0, [r1, #PMC_SR]
tst r0, #PMC_LOCK
beq 1b
mov pc, lr
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
.globl init_48mhz_clock
#define PMC_MCKR 0x30
#define PMC_SR 0x68
#define PMC_MCKRDY 0x08
#define PMC_PRES_DIV2 0x04
#define PMC_CSS_PLL 0x03
/* BUG?
**
** If I try to exit by bx lr, lr is corrupted somewhere in here.
** No clue why. FIQ USB wedge not playing nice? Am I cheating
** with my CPSR calls?
*/
init_48mhz_clock:
ldr r1, =0xfffffc00
mov r2, lr
// turn on /2 prescaler
mov r0, #PMC_PRES_DIV2
str r0, [r1, #PMC_MCKR]
wait_for_clock1:
ldr r0, [r1, #PMC_SR]
tst r0, #PMC_MCKRDY
beq wait_for_clock1
// switch to pll clock
mov r0, #(PMC_PRES_DIV2 | PMC_CSS_PLL)
str r0, [r1, #PMC_MCKR]
wait_for_clock2:
ldr r0, [r1, #PMC_SR]
tst r0, #PMC_MCKRDY
beq wait_for_clock2
bx r2
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <err.h>
#include <sys/types.h>
#include <kernel/thread.h>
#include <platform.h>
#include <platform/interrupts.h>
#include <platform/at91sam7.h>
#include <arch/arm.h>
static int do_nothing()
{
return INT_NO_RESCHEDULE;
}
void platform_init_interrupts(void)
{
AT91AIC *aic = AT91AIC_ADDR;
int n;
for(n = 0; n < 31; n++) {
aic->SVR[n] = (unsigned) do_nothing;
}
aic->SPU = (unsigned) do_nothing;
}
status_t mask_interrupt(unsigned int vector)
{
AT91AIC *aic = AT91AIC_ADDR;
if(vector > 31) return ERR_INVALID_ARGS;
aic->IDCR = (1 << vector);
return NO_ERROR;
}
status_t unmask_interrupt(unsigned int vector)
{
AT91AIC *aic = AT91AIC_ADDR;
if(vector > 31) return ERR_INVALID_ARGS;
aic->IECR = (1 << vector);
return NO_ERROR;
}
void platform_irq(struct arm_iframe *frame)
{
AT91AIC *aic = AT91AIC_ADDR;
int_handler func;
enum handler_return ret;
inc_critical_section();
func = (int_handler) aic->IVR;
// dprintf("platform_irq() -> %p\n", func);
ret = func(0);
aic->EOICR = (unsigned) aic;
if(ret == INT_RESCHEDULE) {
thread_preempt();
}
dec_critical_section();
}
void platform_fiq(struct arm_iframe *frame)
{
}
void register_int_handler(unsigned int vector, int_handler handler, void *arg)
{
AT91AIC *aic = AT91AIC_ADDR;
if(vector > 31) return;
aic->SVR[vector] = (unsigned) handler;
}
+178
View File
@@ -0,0 +1,178 @@
#!/usr/bin/python
## mkboard.py -- atmel pio mux utility
##
## Copyright 2006, Brian Swetland. All rights reserved.
## See provided LICENSE file or http://frotz.net/LICENSE for details.
##
import os, sys, string
# pindef -> num, out, pull, pio, sela, selb
reg_output_disable = 0
reg_output_enable = 0
reg_pullup_disable = 0
reg_pullup_enable = 0
reg_pio_disable = 0
reg_pio_enable = 0
reg_select_a = 0
reg_select_b = 0
def setup_registers(pindef):
global reg_output_disable
global reg_output_enable
global reg_pullup_disable
global reg_pullup_enable
global reg_pio_disable
global reg_pio_enable
global reg_select_a
global reg_select_b
(num, out, pull, pio, sela, selb) = pindef
bit = 1 << num
if out:
reg_output_enable |= bit
reg_output_disable &= (~bit)
else:
reg_output_enable &= (~bit)
reg_output_disable |= bit
if pull:
reg_pullup_enable |= bit
reg_pullup_disable &= (~bit)
else:
reg_pullup_enable &= (~bit)
reg_pullup_disable |= bit
if pio:
reg_pio_enable |= bit
reg_pio_disable &= (~bit)
else:
reg_pio_enable &= (~bit)
reg_pio_disable |= bit
if sela:
reg_select_a |= bit
if selb:
reg_select_b |= bit
def import_pindef(fn):
pass
def read_pins_def(fn, table):
output = ""
fd = open(fn,'r')
for line in fd.xreadlines():
line = line.split('#')[0].strip()
if not line: continue
(gpio,pa,pb) = line.split()
num = int(gpio[2:])
table[gpio+"_IN"] = (num, 0, 0, 1, 0, 0)
table[gpio+"_IN_PULLUP"] = (num, 0, 1, 1, 0, 0)
table[gpio+"_OUT"] = (num, 1, 0, 1, 0, 0)
table[gpio+"_"+pa] = (num, 0, 0, 0, 1, 0)
table[gpio+"_"+pb] = (num, 0, 0, 0, 0, 1)
return output
def read_board_def(fn, table):
pins = {}
output = ""
for n in range(0,32):
pins[n] = ''
fd = open(fn,'r')
for line in fd.xreadlines():
line = line.split('#')[0].strip()
if not line: continue
if len(line.split('=')) == 2:
(line,func) = line.split('=')
line = line.strip()
func = func.strip()
else:
func = ''
parts = line.split()
if len(parts) < 2:
print "ERROR: invalid definition '%s'" % line
sys.exit(1)
if not func:
if (parts[1] == 'IN') or (parts[1] == 'OUT'):
func = parts[0]
else:
func = parts[1]
pin = string.join(parts,"_")
if not table.has_key(pin):
print "ERROR: pin '%s' does not exist" % pin
sys.exit(1)
pindef = table[pin]
num = pindef[0]
if pins[num]:
print "ERROR: pin '%s' conflicts with pin '%s'" % (pin, pins[num])
sys.exit(1)
pins[num] = pin
setup_registers(pindef)
output += "#define PIN_%-12s (1 << %d)\n" % (func, num)
return output
table = {}
output = ""
for fn in sys.argv[1:]:
if fn.endswith('.pins'):
if table:
print "ERROR: only one pin definition file allowed"
sys.exit(1)
output = read_pins_def(fn, table)
continue
if fn.endswith('.def'):
if not table:
print "ERROR: must specify a pin definition file first"
sys.exit(1)
reg_output_disable = 0xffffffffL
reg_output_enable = 0L
reg_pullup_disable = 0L
reg_pullup_enable = 0xffffffffL
reg_pio_disable = 0L
reg_pio_enable = 0xffffffffL
reg_select_a = 0L
reg_select_b = 0L
output = read_board_def(fn, table)
fd = open(fn[:-4] + ".h", 'w')
fd.write("/* DO NOT EDIT -- AUTOGENERATED FROM '%s' */\n\n" % fn)
fd.write("#ifndef __BOARD_DEFINITION_FILE__\n")
fd.write("#define __BOARD_DEFINITION_FILE__\n\n")
fd.write(output)
fd.write("\n")
fd.write("#define BOARD_OUTPUT_DISABLE 0x%08x\n" % reg_output_disable)
fd.write("#define BOARD_OUTPUT_ENABLE 0x%08x\n" % reg_output_enable)
fd.write("#define BOARD_PULLUP_DISABLE 0x%08x\n" % reg_pullup_disable)
fd.write("#define BOARD_PULLUP_ENABLE 0x%08x\n" % reg_pullup_enable)
fd.write("#define BOARD_PIO_DISABLE 0x%08x\n" % reg_pio_disable)
fd.write("#define BOARD_PIO_ENABLE 0x%08x\n" % reg_pio_enable)
fd.write("#define BOARD_SELECT_A 0x%08x\n" % reg_select_a)
fd.write("#define BOARD_SELECT_B 0x%08x\n" % reg_select_b)
fd.write("\n#endif\n")
fd.close()
continue
print "ERROR: what is '%s'?" % fn
sys.exit(1)
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <platform/at91sam7.h>
#include <platform/mux.h>
void mux_init(void)
{
AT91PIO *pio = AT91PIOA_ADDR;
pio->output_disable = BOARD_OUTPUT_DISABLE;
pio->output_enable = BOARD_OUTPUT_ENABLE;
pio->pullup_disable = BOARD_PULLUP_DISABLE;
pio->pullup_enable = BOARD_PULLUP_ENABLE;
pio->pio_disable = BOARD_PIO_DISABLE;
pio->pio_enable = BOARD_PIO_ENABLE;
pio->select_a = BOARD_SELECT_A;
pio->select_b = BOARD_SELECT_B;
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
void emac_init();
void platform_init(void)
{
#if AT91_SAM7X
emac_init();
#endif
}
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
.globl platform_early_init
platform_early_init:
stmdb sp!, {lr}
/* enable the NRST reset pin */
ldr r1, =0xfffffd08
ldr r0, =0xa5000401
str r0, [r1]
/* disable watchdog */
ldr r1, =0xfffffd44
ldr r0, =0x3fff8fff
str r0, [r1]
bl init_clock
bl init_48mhz_clock
/* copy the .data section from ROM to RAM */
ldr r0, =__rodata_end
ldr r1, =__data_start
ldr r2, =__bss_start
__data_loop:
cmp r1, r2
ldrlt r3, [r0], #4
strlt r3, [r1], #4
blt __data_loop
bl mux_init
bl ser_init
bl platform_init_interrupts
ldmia sp!, {lr}
bx lr
@@ -0,0 +1,70 @@
#
# The TARGET is expected to indicate which *specific* AT91SAM7 chip
# is being used, since features and memory vary from chip to chip
#
# chip ram rom EMAC CAN
# AT91CHIP := sam7s64 16k 64k N N
# AT91CHIP := sam7s256 64k 256k N N
# AT91CHIP := sam7x256 64k 256k Y Y
#
# ROMBASE, MEMBASE, and MEMSIZE are required for the linker script
ROMBASE := 0x0
MEMBASE := 0x200000
TMP_CFG := bad
ifeq ($(AT91CHIP), sam7x256)
DEFINES += AT91_SAM7X=1
DEFINES += AT91_RAMSIZE=65536
DEFINES += AT91_ROMSIZE=262144
MEMSIZE := 65536
TMP_CFG := ok
endif
ifeq ($(AT91CHIP), sam7s256)
DEFINES += AT91_SAM7S=1
DEFINES += AT91_RAMSIZE=65536
DEFINES += AT91_ROMSIZE=262144
MEMSIZE := 65536
TMP_CFG := ok
endif
ifeq ($(AT91CHIP), sam7s64)
DEFINES += AT91_SAM7S=1
DEFINES += AT91_RAMSIZE=16384
DEFINES += AT91_ROMSIZE=65536
MEMSIZE := 16384
TMP_CFG := ok
endif
ifeq ($(TMP_CFG), bad)
$(error The AT91SAM7 platform requires AT91CHIP be set by the target)
endif
LOCAL_DIR := $(GET_LOCAL_DIR)
ARCH := arm
ARM_CPU := arm7tdmi
DEFINES += AT91_MCK_MHZ=48000000
INCLUDES += \
-I$(LOCAL_DIR)/include
OBJS += \
$(LOCAL_DIR)/debug.o \
$(LOCAL_DIR)/interrupts.o \
$(LOCAL_DIR)/platform_early.o \
$(LOCAL_DIR)/platform.o \
$(LOCAL_DIR)/timer.o \
$(LOCAL_DIR)/init_clock.o \
$(LOCAL_DIR)/init_clock_48mhz.o \
$(LOCAL_DIR)/mux.o \
$(LOCAL_DIR)/emac_dev.o
# use a two segment memory layout, where all of the read-only sections
# of the binary reside in rom, and the read/write are in memory. The
# ROMBASE, MEMBASE, and MEMSIZE make variables are required to be set
# for the linker script to be generated properly.
#
LINKER_SCRIPT += \
$(BUILDDIR)/system-twosegment.ld
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <err.h>
#include <debug.h>
#include <sys/types.h>
#include <kernel/thread.h>
#include <platform/timer.h>
#include <platform/interrupts.h>
#include <platform/debug.h>
#include <platform/at91sam7.h>
#define FIXED_1KHZ_TIMER 0
static platform_timer_callback timer_func;
static volatile time_t ticks = 0;
#if FIXED_1KHZ_TIMER
static volatile int timer_interval;
static volatile int timer_downcount;
#else
static int timer_ms_per_tick;
#endif
time_t current_time(void)
{
return ticks;
}
bigtime_t current_time_hires(void)
{
return ticks * 1000ULL;
}
static enum handler_return pit_irq_handler(void *arg)
{
AT91PIT *pit = AT91PIT_ADDR;
unsigned n = PIT_PICNT(pit->PIVR);
#if FIXED_1KHZ_TIMER
ticks += n;
timer_downcount -= n;
if(timer_downcount <= 0) {
timer_downcount = timer_interval;
return timer_func(0, ticks);
} else {
return INT_NO_RESCHEDULE;
}
#else
ticks += (n * timer_ms_per_tick);
return timer_func(0, ticks);
#endif
}
status_t platform_set_periodic_timer(platform_timer_callback callback,
void *arg, time_t interval)
{
unsigned n;
AT91PIT *pit = AT91PIT_ADDR;
n = AT91_MCK_MHZ / 16 / 1000;
dprintf(INFO, "timer: MCK=%dKHz, n=%d\n", AT91_MCK_MHZ / 1000, n);
enter_critical_section();
timer_func = callback;
#if FIXED_1KHZ_TIMER
timer_interval = interval;
timer_downcount = interval;
#else
timer_ms_per_tick = interval;
n *= interval;
#endif
pit->MR = PIT_PITEN | PIT_PITIEN | (n & 0xfffff);
register_int_handler(PID_SYSIRQ, pit_irq_handler, 0);
unmask_interrupt(PID_SYSIRQ);
exit_critical_section();
return NO_ERROR;
}