summaryrefslogtreecommitdiffstats
path: root/c/src/lib
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-09-10 12:16:39 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-09-10 12:16:39 +0000
commiteff217e095ea1f77e0549a32e170e43b4e637eee (patch)
tree0343667169379aaf282f0c183a4de94411845bfe /c/src/lib
parentAdded section on format of the configuration space file. (diff)
downloadrtems-eff217e095ea1f77e0549a32e170e43b4e637eee.tar.bz2
Patch from Emmanuel Raguet <raguet@crf.canon.fr>:
After some good comments from Eric Norum [thanks, Eric !], I have added some modifications to my previous driver patch : - wait for transmitter ready before sending a packet, - new delay management in case of ring-overwritting.
Diffstat (limited to 'c/src/lib')
-rw-r--r--c/src/lib/libbsp/i386/pc386/network/network.c19
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c6
-rw-r--r--c/src/lib/libbsp/i386/pc386/timer/timer.c99
3 files changed, 114 insertions, 10 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/network/network.c b/c/src/lib/libbsp/i386/pc386/network/network.c
index 1f937bc009..ab12f1c0e7 100644
--- a/c/src/lib/libbsp/i386/pc386/network/network.c
+++ b/c/src/lib/libbsp/i386/pc386/network/network.c
@@ -129,7 +129,7 @@ static struct wd_softc wd_softc[NWDDRIVER];
static rtems_isr
wd8003Enet_interrupt_handler (rtems_vector_number v)
{
- unsigned int tport, nowTicks, bootTicks;
+ unsigned int tport;
unsigned char status, status2;
tport = wd_softc[0].port ;
@@ -146,9 +146,7 @@ wd8003Enet_interrupt_handler (rtems_vector_number v)
if (status & MSK_OVW){
outport_byte(tport+CMDR, MSK_STP + MSK_RD2); /* stop 8390 */
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &bootTicks );
- while(nowTicks < bootTicks+loopc) /* 2ms delay */
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &nowTicks );
+ Wait_X_ms(2);
outport_byte(tport+RBCR0, 0); /* clear byte count */
outport_byte(tport+RBCR1, 0);
inport_byte(tport+ISR, status2);
@@ -361,11 +359,16 @@ sendpacket (struct ifnet *ifp, struct mbuf *m)
struct wd_softc *dp = ifp->if_softc;
struct mbuf *n;
unsigned int len, tport;
- char *shp;
+ char *shp, txReady;
tport = dp->port;
-
+ /*
+ * Waiting for Transmitter ready
+ */
+ inport_byte(tport+CMDR, txReady);
+ while(txReady & MSK_TXP)
+ inport_byte(tport+CMDR, txReady);
len = 0;
shp = dp->base + (SHAPAGE * OUTPAGE);
@@ -639,10 +642,6 @@ rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *config)
if (ifp->if_snd.ifq_maxlen == 0)
ifp->if_snd.ifq_maxlen = ifqmaxlen;
- /* calibrate a delay loop for 2 milliseconds */
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &loopc );
- loopc /= 500;
-
/*
* init some variables
*/
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
index 7ebcc60685..7927ef2c0b 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -146,6 +146,12 @@ void bsp_pretasking_hook(void)
+--------------------------------------------------------------------------*/
void bsp_start( void )
{
+
+ /*
+ * Calibrate variable for 1ms-loop (see timer.c)
+ */
+ Calibrate_loop_1ms();
+
rtemsFreeMemStart = (rtems_unsigned32)&_end + _stack_size;
/* set the value of start of free memory. */
diff --git a/c/src/lib/libbsp/i386/pc386/timer/timer.c b/c/src/lib/libbsp/i386/pc386/timer/timer.c
index 8ae7f7c011..47e4894e00 100644
--- a/c/src/lib/libbsp/i386/pc386/timer/timer.c
+++ b/c/src/lib/libbsp/i386/pc386/timer/timer.c
@@ -45,12 +45,19 @@
+--------------------------------------------------------------------------*/
#define AVG_OVERHEAD 0 /* 0.1 microseconds to start/stop timer. */
#define LEAST_VALID 1 /* Don't trust a value lower than this. */
+#define SLOW_DOWN_IO 0x80 /* io which does nothing */
+#define TWO_MS (rtems_unsigned32)(2000) /* TWO_MS = 2000us (sic!) */
+
+#define MSK_NULL_COUNT 0x40 /* bit counter available for reading */
+
+#define CMD_READ_BACK_STATUS 0xE2 /* command read back status */
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
volatile rtems_unsigned32 Ttimer_val;
rtems_boolean Timer_driver_Find_average_overhead = TRUE;
+ unsigned int loop1ms;
/*-------------------------------------------------------------------------+
| External Prototypes
@@ -293,3 +300,95 @@ Set_find_average_overhead(rtems_boolean find_flag)
{
Timer_driver_Find_average_overhead = find_flag;
} /* Set_find_average_overhead */
+
+/*-------------------------------------------------------------------------+
+| Function: Calibrate_loop_1ms
+| Description: Set loop variable to calibrate a 1ms loop
+| Global Variables: loop1ms
+| Arguments: none
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+void
+Calibrate_loop_1ms(void){
+ unsigned int i;
+ unsigned short loadedValue, offset;
+ unsigned int timerValue;
+ rtems_interrupt_level level;
+ unsigned short lsb, msb;
+ unsigned char status;
+
+
+ loop1ms = 100 ;
+ timerValue = 2000;
+ loadedValue = US_TO_TICK(2000);
+
+ rtems_interrupt_disable(level);
+
+ /*
+ * Compute the offset to apply due to read counter register
+ */
+ outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
+ outport_byte(TIMER_CNTR0, loadedValue >> 0 & 0xff);
+ outport_byte(TIMER_CNTR0, loadedValue >> 8 & 0xff);
+
+ outport_byte(TIMER_MODE, CMD_READ_BACK_STATUS); /* read Status counter 0 */
+ inport_byte(TIMER_CNTR0, status);
+ while (status & MSK_NULL_COUNT){ /* wait for counter ready */
+ outport_byte(TIMER_MODE, CMD_READ_BACK_STATUS);
+ inport_byte(TIMER_CNTR0, status);
+ }
+
+ outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_LATCH);
+ inport_byte(TIMER_CNTR0, lsb);
+ inport_byte(TIMER_CNTR0, msb);
+ offset = loadedValue - (unsigned short)((msb << 8) | lsb);
+
+ while (timerValue > 1000){
+ loop1ms++;
+
+ /* load timer for 2ms+offset period */
+ outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
+ outport_byte(TIMER_CNTR0, (loadedValue+offset) >> 0 & 0xff);
+ outport_byte(TIMER_CNTR0, (loadedValue+offset) >> 8 & 0xff);
+
+ outport_byte(TIMER_MODE, CMD_READ_BACK_STATUS); /* read Status counter 0 */
+ inport_byte(TIMER_CNTR0, status);
+ while (status & MSK_NULL_COUNT) { /* wait for counter ready */
+ outport_byte(TIMER_MODE, CMD_READ_BACK_STATUS);
+ inport_byte(TIMER_CNTR0, status);
+ }
+
+ for (i=0; i<loop1ms; i++)
+ outport_byte(SLOW_DOWN_IO, 0); /* write is # 1us */
+
+ outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_LATCH);
+ inport_byte(TIMER_CNTR0, lsb);
+ inport_byte(TIMER_CNTR0, msb);
+ timerValue = TICK_TO_US((msb << 8) | lsb);
+ }
+
+ rtems_interrupt_enable(level);
+}
+
+/*-------------------------------------------------------------------------+
+| Function: Wait_X_1ms
+| Description: loop which waits at least timeToWait ms
+| Global Variables: loop1ms
+| Arguments: timeToWait
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+void
+Wait_X_ms( unsigned int timeToWait){
+
+ unsigned int i, j;
+
+ for (j=0; j<timeToWait ; j++)
+ for (i=0; i<loop1ms; i++)
+ outport_byte(SLOW_DOWN_IO, 0); /* write is # 1us */
+}
+
+
+
+
+
+