OpenCores
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.