OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

[/] [plasma/] [trunk/] [kernel/] [ethernet.c] - Diff between revs 385 and 416

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 385 Rev 416
Line 32... Line 32...
static unsigned char reflect[256];
static unsigned char reflect[256];
static unsigned char reflectNibble[256];
static unsigned char reflectNibble[256];
static OS_Semaphore_t *SemEthernet, *SemEthTransmit;
static OS_Semaphore_t *SemEthernet, *SemEthTransmit;
static int gIndex;          //byte index into 0x13ff0000 receive buffer
static int gIndex;          //byte index into 0x13ff0000 receive buffer
static int gCheckedBefore;
static int gCheckedBefore;
static int gEmptyBefore;
 
 
 
 
 
//Read received data from 0x13ff0000.  Data starts with 0x5d+MACaddress.
//Read received data from 0x13ff0000.  Data starts with 0x5d+MACaddress.
//Data is being received while processing the data.  Therefore,
//Data is being received while processing the data.  Therefore,
//all errors require waiting and then re-processing the data
//all errors require waiting and then re-processing the data
//to see if the error is fixed by receiving the rest of the packet.
//to see if the error is fixed by receiving the rest of the packet.
int EthernetReceive(unsigned char *buffer, int length)
int EthernetReceive(unsigned char *buffer, int length)
{
{
   int count;
   int count;
   int start, i, j, shift, offset;
   int start, i, j, shift, offset, index;
   int byte, byteNext;
   int byte, byteNext;
   unsigned long crc;
   unsigned long crc;
   int byteCrc;
   int byteCrc;
   volatile unsigned char *buf = (unsigned char*)ETHERNET_RECEIVE;
   volatile unsigned char *buf = (unsigned char*)ETHERNET_RECEIVE;
   int countEmpty, countEmptyGoal, countOk, needWait;
 
   int packetExpected;
   int packetExpected;
 
 
   //Find the start of a frame
   //Find the start of a frame
   countEmpty = 0;
 
   countOk = 0;
 
   needWait = 0;
 
   countEmptyGoal = COUNT_EMPTY;
 
   packetExpected = MemoryRead(IRQ_STATUS) & IRQ_ETHERNET_RECEIVE;
   packetExpected = MemoryRead(IRQ_STATUS) & IRQ_ETHERNET_RECEIVE;
   if(packetExpected && buf[gIndex] == BYTE_EMPTY && gEmptyBefore)
 
   {
 
      //printf("Check ");
 
      countEmptyGoal = 1500;
 
   }
 
   MemoryRead(ETHERNET_REG);        //clear receive interrupt
   MemoryRead(ETHERNET_REG);        //clear receive interrupt
   for(i = 0; i < INDEX_MASK; ++i)
 
   {
 
      //Check if partial packet possibly received
 
      if(needWait && gCheckedBefore == 0 && countOk != i && countEmpty != i)
 
      {
 
         gCheckedBefore = 1;
 
         //printf("W(%d,%d,%d)", i, countOk, countEmpty);
 
         return 0;                  //Wait for more data
 
      }
 
 
 
      //Detect start of frame
   //Find dest MAC address
      byte = buf[(gIndex + i) & INDEX_MASK];
   for(offset = 0; offset <= INDEX_MASK; ++offset)
      if(byte == gDestMac[countOk] || (countOk && byte == 0xff))
 
      {
      {
         if(++countOk == sizeof(gDestMac))
      index = (gIndex + offset) & INDEX_MASK;
         {
      byte = buf[index];
            //Set bytes before 0x5d to BYTE_EMPTY
      if(byte == 0x5d)  //bit pattern 01011101
            offset = i - (int)sizeof(gDestMac);
      {
            //if(offset > 3)
         for(i = 1; i < sizeof(gDestMac); ++i)
            //   printf("es%d ", offset);
         {
            for(j = 0; j <= offset; ++j)
            j = (index + i) & INDEX_MASK;
            {
            byte = buf[j];
               buf[gIndex] = BYTE_EMPTY;
            if(byte != 0xff && byte != gDestMac[i])
               gIndex = (gIndex + 1) & INDEX_MASK;
 
            }
 
            break;
            break;
         }
         }
 
         if(i == sizeof(gDestMac))
 
            break;    //found dest MAC
      }
      }
      else
      else if(byte == BYTE_EMPTY && packetExpected == 0)
      {
         return 0;
         //if(countOk)
 
         //   printf("N%d ", countOk);
 
         if(countOk == 3 && byte == BYTE_EMPTY)
 
            needWait = 1;
 
         if(byte == 0x5d)
 
            countOk = 1;
 
         else
 
            countOk = 0;
 
      }
      }
 
   if(offset > INDEX_MASK)
      //Check if remainder of buffer is empty
      return 0;
      if(byte == BYTE_EMPTY)
   while(gIndex != index)
      {
 
         if(++countEmpty >= countEmptyGoal)
 
         {
 
            //Set skiped bytes to BYTE_EMPTY
 
            //if(i - countEmpty > 3)
 
            //{
 
            //   printf("eb%d \n", i - countEmpty);
 
            //   //dump((char*)buf+gIndex, 0x200);
 
            //}
 
            for(j = 0; j <= i - countEmpty; ++j)
 
            {
            {
               buf[gIndex] = BYTE_EMPTY;
               buf[gIndex] = BYTE_EMPTY;
               gIndex = (gIndex + 1) & INDEX_MASK;
               gIndex = (gIndex + 1) & INDEX_MASK;
            }
            }
            gCheckedBefore = 0;
 
            if(countEmpty >= i && packetExpected)
 
               gEmptyBefore = 1;
 
            return 0;
 
         }
 
      }
 
      else
 
      {
 
         if(countEmpty > 2 || (countEmpty > 0 && countEmpty == i))
 
            needWait = 1;
 
         countEmpty = 0;
 
         gEmptyBefore = 0;
 
      }
 
   }
 
 
 
   //Found start of frame.  Now find end of frame and check CRC.
   //Found start of frame.  Now find end of frame and check CRC.
   start = gIndex;
   start = gIndex;
   gIndex = (gIndex + 1) & INDEX_MASK;           //skip 0x5d byte
   gIndex = (gIndex + 1) & INDEX_MASK;           //skip 0x5d byte
   crc = 0xffffffff;
   crc = 0xffffffff;
Line 183... Line 130...
            }
            }
         }
         }
      }
      }
   }
   }
   gIndex = start;
   gIndex = start;
   if(gCheckedBefore)
   if(gCheckedBefore++ > 1)
   {
   {
      //printf("CRC failure\n");
 
      buf[gIndex] = BYTE_EMPTY;
      buf[gIndex] = BYTE_EMPTY;
 
      gIndex = (gIndex + 1) & INDEX_MASK;
   }
   }
   gCheckedBefore = 1;
 
   return 0;        //wait for more data
   return 0;        //wait for more data
}
}
 
 
 
 
//Copy transmit data to 0x13fe0000 with preamble and CRC32
//Copy transmit data to 0x13fe0000 with preamble and CRC32
Line 252... Line 198...
void EthernetThread(void *arg)
void EthernetThread(void *arg)
{
{
   int length;
   int length;
   int rc;
   int rc;
   unsigned int ticks, ticksLast=0;
   unsigned int ticks, ticksLast=0;
 
   int ticksWait=50;
   IPFrame *ethFrame=NULL;
   IPFrame *ethFrame=NULL;
   static int ethErrorCount=0;
 
   (void)arg;
   (void)arg;
 
 
   for(;;)
   for(;;)
   {
   {
      OS_InterruptMaskSet(IRQ_ETHERNET_RECEIVE);
      OS_InterruptMaskSet(IRQ_ETHERNET_RECEIVE);      //enable interrupt
      OS_SemaphorePend(SemEthernet, 50);  //wait for interrupt
      rc = OS_SemaphorePend(SemEthernet, ticksWait);  //wait for interrupt
 
      if(rc)
 
         ticksWait = 50;
 
      else
 
         ticksWait = 2;
 
 
      //Process all received packets
      //Process all received packets
      for(;;)
      for(;;)
      {
      {
         if(ethFrame == NULL)
         if(ethFrame == NULL)
            ethFrame = IPFrameGet(FRAME_COUNT_RCV);
            ethFrame = IPFrameGet(FRAME_COUNT_RCV);
         if(ethFrame == NULL)
         if(ethFrame == NULL)
         {
 
            OS_ThreadSleep(50);
 
            break;
            break;
         }
 
         length = EthernetReceive(ethFrame->packet, PACKET_SIZE);
         length = EthernetReceive(ethFrame->packet, PACKET_SIZE);
         if(length == 0)
         if(length == 0)
         {
 
#if 1       //Disable this on quiet networks
 
            //No Ethernet packets seen for 60 seconds?
 
            if(++ethErrorCount >= 120)
 
            {
 
               printf("\nEthernetInit\n");
 
               ethErrorCount = 0;
 
               EthernetInit(NULL);  //Need to re-initialize
 
            }
 
#endif
 
            break;
            break;
         }
 
         ethErrorCount = 0;
 
         Led(1, 1);
         Led(1, 1);
         rc = IPProcessEthernetPacket(ethFrame, length);
         rc = IPProcessEthernetPacket(ethFrame, length);
         Led(1, 0);
         Led(1, 0);
         if(rc)
         if(rc)
            ethFrame = NULL;
            ethFrame = NULL;
Line 306... Line 241...
 
 
 
 
void EthernetIsr(void *arg)
void EthernetIsr(void *arg)
{
{
   (void)arg;
   (void)arg;
   OS_InterruptMaskClear(IRQ_ETHERNET_TRANSMIT | IRQ_ETHERNET_RECEIVE);
   OS_InterruptMaskClear(IRQ_ETHERNET_RECEIVE);
   OS_SemaphorePost(SemEthernet);
   OS_SemaphorePost(SemEthernet);
}
}
 
 
 
 
/******************* CRC32 calculations **********************
/******************* CRC32 calculations **********************

powered by: WebSVN 2.1.0

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