URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/tags/initial/orpmon/drivers
- from Rev 811 to Rev 1765
- ↔ Reverse comparison
Rev 811 → Rev 1765
/eth.c
0,0 → 1,246
#include "common.h" |
#include "support.h" |
#include "board.h" |
#include "uart.h" |
#include "eth.h" |
#include "spr_defs.h" |
|
extern int printf (const char *fmt, ...); |
extern void lolev_ie(void); |
extern void lolev_idis(void); |
|
int tx_next; /* Next buffer to be given to the user */ |
int tx_last; /* Next buffer to be checked if packet sent */ |
int tx_full; |
int rx_next; /* Next buffer to be checked for new packet and given to the user */ |
void (*receive)(void *add, int len); /* Pointer to function to be called |
when frame is received */ |
|
void init_tx_bd_pool(void) |
{ |
eth_bd *bd; |
int i; |
|
bd = (eth_bd *)ETH_BD_BASE; |
|
for(i = 0; i < ETH_TXBD_NUM; i++){ |
|
/* Set Tx BD status */ |
bd[i].status = ETH_TX_BD_PAD | ETH_TX_BD_CRC | ETH_RX_BD_IRQ; |
|
/* Initialize Tx buffer pointer */ |
bd[i].addr = ETH_DATA_BASE + i * ETH_MAXBUF_LEN; |
} |
|
bd[i-1].status |= ETH_TX_BD_WRAP; // Last Tx BD - Wrap |
} |
|
void init_rx_bd_pool(void) |
{ |
eth_bd *bd; |
int i; |
|
bd = (eth_bd *)ETH_BD_BASE + ETH_TXBD_NUM; |
|
for(i = 0; i < ETH_RXBD_NUM; i++){ |
|
/* Set Tx BD status */ |
bd[i].status = ETH_RX_BD_EMPTY | ETH_RX_BD_IRQ; |
|
/* Initialize Tx buffer pointer */ |
bd[i].addr = ETH_DATA_BASE + (ETH_TXBD_NUM + i) * ETH_MAXBUF_LEN; |
} |
|
bd[i-1].status |= ETH_TX_BD_WRAP; // Last Rx BD - Wrap |
} |
|
void eth_init (void (*rec)(volatile unsigned char *, int)) |
{ |
|
/* Reset ethernet core */ |
REG32(ETH_REG_BASE + ETH_MODER) = ETH_MODER_RST; /* Reset ON */ |
REG32(ETH_REG_BASE + ETH_MODER) &= ~ETH_MODER_RST; /* Reset OFF */ |
|
/* Setting TX BD number */ |
REG32(ETH_REG_BASE + ETH_TX_BD_NUM) = ETH_TXBD_NUM << 1; |
|
/* Set min/max packet length */ |
REG32(ETH_REG_BASE + ETH_PACKETLEN) = 0x003c0600; |
|
/* Set IPGT register to recomended value */ |
REG32(ETH_REG_BASE + ETH_IPGT) = 0x00000012; |
|
/* Set IPGR1 register to recomended value */ |
REG32(ETH_REG_BASE + ETH_IPGR1) = 0x0000000c; |
|
/* Set IPGR2 register to recomended value */ |
REG32(ETH_REG_BASE + ETH_IPGR2) = 0x00000012; |
|
/* Set COLLCONF register to recomended value */ |
REG32(ETH_REG_BASE + ETH_COLLCONF) = 0x0000003f; |
|
#if 0 |
REG32(ETH_REG_BASE + ETH_CTRLMODER) = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW; |
#else |
REG32(ETH_REG_BASE + ETH_CTRLMODER) = 0; |
#endif |
|
/* Initialize RX and TX buffer descriptors */ |
init_rx_bd_pool(); |
init_tx_bd_pool(); |
|
/* Initialize tx pointers */ |
tx_next = 0; |
tx_last = 0; |
tx_full = 0; |
|
/* Initialize rx pointers */ |
rx_next = 0; |
receive = rec; |
|
/* Set local MAC address */ |
REG32(ETH_REG_BASE + ETH_MAC_ADDR1) = ETH_MACADDR0 << 8 | |
ETH_MACADDR1; |
REG32(ETH_REG_BASE + ETH_MAC_ADDR0) = ETH_MACADDR2 << 24 | |
ETH_MACADDR3 << 16 | |
ETH_MACADDR4 << 8 | |
ETH_MACADDR5; |
|
/* Clear all pending interrupts */ |
REG32(ETH_REG_BASE + ETH_INT) = 0xffffffff; |
|
/* Promisc, IFG, CRCEn */ |
REG32(ETH_REG_BASE + ETH_MODER) |= ETH_MODER_PAD | ETH_MODER_IFG | ETH_MODER_CRCEN; |
|
/* Enable interrupt sources */ |
#if 0 |
regs->int_mask = ETH_INT_MASK_TXB | |
ETH_INT_MASK_TXE | |
ETH_INT_MASK_RXF | |
ETH_INT_MASK_RXE | |
ETH_INT_MASK_BUSY | |
ETH_INT_MASK_TXC | |
ETH_INT_MASK_RXC; |
#endif |
|
/* Enable receiver and transmiter */ |
REG32(ETH_REG_BASE + ETH_MODER) |= ETH_MODER_RXEN | ETH_MODER_TXEN; |
|
} |
|
/* Returns pointer to next free buffer; NULL if none available */ |
void *eth_get_tx_buf () |
{ |
eth_bd *bd; |
unsigned long add; |
|
if(tx_full) |
return (void *)0; |
|
bd = (eth_bd *)ETH_BD_BASE; |
|
if(bd[tx_next].status & ETH_TX_BD_READY) |
return (void *)0; |
|
add = bd[tx_next].addr; |
|
tx_next = (tx_next + 1) & ETH_TXBD_NUM_MASK; |
|
if(tx_next == tx_last) |
tx_full = 1; |
|
return (void *)add; |
} |
|
/* Send a packet at address */ |
void eth_send (void *buf, unsigned long len) |
{ |
eth_bd *bd; |
|
bd = (eth_bd *)ETH_BD_BASE; |
|
bd[tx_last].addr = (unsigned long)buf; |
|
bd[tx_last].status &= ~ETH_TX_BD_STATS; |
bd[tx_last].status |= ETH_TX_BD_READY; |
|
tx_last = (tx_last + 1) & ETH_TXBD_NUM_MASK; |
tx_full = 0; |
} |
|
/* Waits for packet and pass it to the upper layers */ |
unsigned long eth_rx (void) |
{ |
eth_bd *bd; |
unsigned long len = 0; |
|
bd = (eth_bd *)ETH_BD_BASE + ETH_TXBD_NUM; |
|
while(1) { |
|
int bad = 0; |
|
if(bd[rx_next].status & ETH_RX_BD_EMPTY) |
return len; |
|
if(bd[rx_next].status & ETH_RX_BD_OVERRUN) { |
printf("eth rx: ETH_RX_BD_OVERRUN\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_INVSIMB) { |
printf("eth rx: ETH_RX_BD_INVSIMB\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_DRIBBLE) { |
printf("eth rx: ETH_RX_BD_DRIBBLE\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_TOOLONG) { |
printf("eth rx: ETH_RX_BD_TOOLONG\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_SHORT) { |
printf("eth rx: ETH_RX_BD_SHORT\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_CRCERR) { |
printf("eth rx: ETH_RX_BD_CRCERR\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_LATECOL) { |
printf("eth rx: ETH_RX_BD_LATECOL\n"); |
bad = 1; |
} |
|
if(!bad) { |
receive((void *)bd[rx_next].addr, bd[rx_next].len); |
len += bd[rx_next].len; |
} |
|
bd[rx_next].status &= ~ETH_RX_BD_STATS; |
bd[rx_next].status |= ETH_RX_BD_EMPTY; |
|
rx_next = (rx_next + 1) & ETH_RXBD_NUM_MASK; |
} |
} |
|
void eth_int_enable(void) |
{ |
REG32(ETH_REG_BASE + ETH_INT_MASK) = ETH_INT_MASK_TXB | |
ETH_INT_MASK_TXE | |
ETH_INT_MASK_RXF | |
ETH_INT_MASK_RXE | |
ETH_INT_MASK_BUSY | |
ETH_INT_MASK_TXC | |
ETH_INT_MASK_RXC; |
} |
|
void eth_halt(void) |
{ |
/* Enable receiver and transmiter */ |
REG32(ETH_REG_BASE + ETH_MODER) &= ~(ETH_MODER_RXEN | ETH_MODER_TXEN); |
} |
|
void eth_int(void) |
{ |
} |
/tick.c
0,0 → 1,20
|
#include "common.h" |
#include "support.h" |
#include "spr_defs.h" |
|
#define TICKS_PER_SEC 100 |
|
void tick_init(void) |
{ |
mtspr(SPR_SR, SPR_SR_TEE | mfspr(SPR_SR)); |
mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | ((TICKS_PER_SEC/IN_CLK) & SPR_TTMR_PERIOD)); |
} |
|
void tick_interrupt(void) |
{ |
timestamp++; |
mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | ((TICKS_PER_SEC/IN_CLK) & SPR_TTMR_PERIOD)); |
} |
|
|
/uart.c
0,0 → 1,77
#include "support.h" |
#include "board.h" |
#include "uart.h" |
|
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) |
|
#define WAIT_FOR_XMITR \ |
do { \ |
lsr = REG8(UART_BASE + UART_LSR); \ |
} while ((lsr & BOTH_EMPTY) != BOTH_EMPTY) |
|
#define WAIT_FOR_THRE \ |
do { \ |
lsr = REG8(UART_BASE + UART_LSR); \ |
} while ((lsr & UART_LSR_THRE) != UART_LSR_THRE) |
|
#define CHECK_FOR_CHAR (REG8(UART_BASE + UART_LSR) & UART_LSR_DR) |
|
#define WAIT_FOR_CHAR \ |
do { \ |
lsr = REG8(UART_BASE + UART_LSR); \ |
} while ((lsr & UART_LSR_DR) != UART_LSR_DR) |
|
#define UART_TX_BUFF_LEN 32 |
#define UART_TX_BUFF_MASK (UART_TX_BUFF_LEN -1) |
|
char tx_buff[UART_TX_BUFF_LEN]; |
volatile int tx_level, rx_level; |
|
void uart_init(void) |
{ |
int divisor; |
|
/* Reset receiver and transmiter */ |
REG8(UART_BASE + UART_FCR) = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_14; |
|
/* Disable all interrupts */ |
REG8(UART_BASE + UART_IER) = 0x00; |
|
/* Set 8 bit char, 1 stop bit, no parity */ |
REG8(UART_BASE + UART_LCR) = UART_LCR_WLEN8 & ~(UART_LCR_STOP | UART_LCR_PARITY); |
|
/* Set baud rate */ |
divisor = IN_CLK/(16 * UART_BAUD_RATE); |
REG8(UART_BASE + UART_LCR) |= UART_LCR_DLAB; |
REG8(UART_BASE + UART_DLL) = divisor & 0x000000ff; |
REG8(UART_BASE + UART_DLM) = (divisor >> 8) & 0x000000ff; |
REG8(UART_BASE + UART_LCR) &= ~(UART_LCR_DLAB); |
} |
|
void uart_putc(char c) |
{ |
unsigned char lsr; |
|
WAIT_FOR_THRE; |
REG8(UART_BASE + UART_TX) = c; |
if(c == '\n') { |
WAIT_FOR_THRE; |
REG8(UART_BASE + UART_TX) = '\r'; |
} |
WAIT_FOR_XMITR; |
} |
|
char uart_getc(void) |
{ |
unsigned char lsr; |
char c; |
|
WAIT_FOR_CHAR; |
c = REG8(UART_BASE + UART_RX); |
return c; |
} |
|
char uart_testc(void) |
{ |
return ((REG8(UART_BASE + UART_LSR) & UART_LSR_DR) == UART_LSR_DR); |
} |
uart.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: Makefile
===================================================================
--- Makefile (nonexistent)
+++ Makefile (revision 1765)
@@ -0,0 +1,12 @@
+
+LIB = drivers.o
+OBJS = eth.o uart.o tick.o
+
+all: $(LIB)
+
+$(LIB): $(OBJS)
+ $(LD) -r -o $@ $(OBJS)
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+sinclude .depend