Ejemplo n.º 1
0
void
Enc28J60Network::memblock_mv_cb(uint16_t dest, uint16_t src, uint16_t len)
{
  //as ENC28J60 DMA is unable to copy single bytes:
  if (len == 1)
    {
      writeByte(dest,readByte(src));
    }
  else
    {
      // calculate address of last byte
      len += src - 1;

      /*  1. Appropriately program the EDMAST, EDMAND
       and EDMADST register pairs. The EDMAST
       registers should point to the first byte to copy
       from, the EDMAND registers should point to the
       last byte to copy and the EDMADST registers
       should point to the first byte in the destination
       range. The destination range will always be
       linear, never wrapping at any values except from
       8191 to 0 (the 8-Kbyte memory boundary).
       Extreme care should be taken when
       programming the start and end pointers to
       prevent a never ending DMA operation which
       would overwrite the entire 8-Kbyte buffer.
       */
      writeRegPair(EDMASTL, src);
      writeRegPair(EDMADSTL, dest);

      if ((src <= RXSTOP_INIT)&& (len > RXSTOP_INIT))len -= (RXSTOP_INIT-RXSTART_INIT);
      writeRegPair(EDMANDL, len);

      /*
       2. If an interrupt at the end of the copy process is
       desired, set EIE.DMAIE and EIE.INTIE and
       clear EIR.DMAIF.

       3. Verify that ECON1.CSUMEN is clear. */
      writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);

      /* 4. Start the DMA copy by setting ECON1.DMAST. */
      writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);

      // wait until runnig DMA is completed
      while (readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST);
    }
}
Ejemplo n.º 2
0
Value InterpretedVM::IndexMemberValue(uint32 typeId, byte* val, uint32 index) const {
  Value result;

  SOp compDef = prog.DefinedTypes.at(typeId);
  switch (compDef.Op) {
  case Op::OpTypeVector: {
    auto vec = (STypeVector*)compDef.Memory;
    uint32 offset = GetTypeByteSize(vec->ComponenttypeId) * index;
    result.TypeId = vec->ComponenttypeId;
    result.Memory = val + offset;
    break;
  }
  case Op::OpTypeStruct: {
    auto s = (STypeStruct*)compDef.Memory;
    result.TypeId = s->MembertypeIds[index];
    result.Memory = val;
    for (int i = 0; i < index; i++) {
      result.Memory += GetTypeByteSize(s->MembertypeIds[i]);
    }
    break;
  }
  case Op::OpTypePointer: {
    auto p = (STypePointer*)compDef.Memory;
    result = IndexMemberValue(p->TypeId, (byte*)*(void**)val, index);
    break;
  }
  default:
    result.Memory = nullptr;
    result.TypeId = 0;
    std::cout << "Not a composite type def: " << writeOp(compDef);
  }

  return result;
}
Ejemplo n.º 3
0
memhandle
Enc28J60Network::receivePacket()
{
  uint8_t rxstat;
  uint16_t len;
  // check if a packet has been received and buffered
  //if( !(readReg(EIR) & EIR_PKTIF) ){
  // The above does not work. See Rev. B4 Silicon Errata point 6.
  if (readReg(EPKTCNT) != 0)
    {
      uint16_t readPtr = nextPacketPtr+6 > RXSTOP_INIT ? nextPacketPtr+6-RXSTOP_INIT+RXSTART_INIT : nextPacketPtr+6;
      // Set the read pointer to the start of the received packet
      writeRegPair(ERDPTL, nextPacketPtr);
      // read the next packet pointer
      nextPacketPtr = readOp(ENC28J60_READ_BUF_MEM, 0);
      nextPacketPtr |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
      // read the packet length (see datasheet page 43)
      len = readOp(ENC28J60_READ_BUF_MEM, 0);
      len |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
      len -= 4; //remove the CRC count
      // read the receive status (see datasheet page 43)
      rxstat = readOp(ENC28J60_READ_BUF_MEM, 0);
      //rxstat |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
#ifdef ENC28J60DEBUG
      Serial.print("receivePacket [");
      Serial.print(readPtr,HEX);
      Serial.print("-");
      Serial.print((readPtr+len) % (RXSTOP_INIT+1),HEX);
      Serial.print("], next: ");
      Serial.print(nextPacketPtr,HEX);
      Serial.print(", stat: ");
      Serial.print(rxstat,HEX);
      Serial.print(", count: ");
      Serial.print(readReg(EPKTCNT));
      Serial.print(" -> ");
      Serial.println((rxstat & 0x80)!=0 ? "OK" : "failed");
#endif
      // decrement the packet counter indicate we are done with this packet
      writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
      // check CRC and symbol errors (see datasheet page 44, table 7-3):
      // The ERXFCON.CRCEN is set by default. Normally we should not
      // need to check this.
      if ((rxstat & 0x80) != 0)
        {
          receivePkt.begin = readPtr;
          receivePkt.size = len;
#ifdef ENC28J60DEBUG
          Serial.print("receivePkt.size=");
          Serial.println(len);
#endif
          return UIP_RECEIVEBUFFERHANDLE;
        }
      // Move the RX read pointer to the start of the next received packet
      // This frees the memory we just read out
      setERXRDPT();
    }
  return (NOBLOCK);
}
Ejemplo n.º 4
0
void
Enc28J60Network::sendPacket(memhandle handle)
{
  memblock *packet = &blocks[handle];
  uint16_t start = packet->begin-1;
  uint16_t end = start + packet->size;

  // backup data at control-byte position
  uint8_t data = readByte(start);
  // write control-byte (if not 0 anyway)
  if (data)
    writeByte(start, 0);

#ifdef ENC28J60DEBUG
  Serial.print("sendPacket(");
  Serial.print(handle);
  Serial.print(") [");
  Serial.print(start);
  Serial.print("-");
  Serial.print(end);
  Serial.println("]:");
  for (uint16_t i=start; i<=end; i++)
    {
      Serial.print(readByte(i),HEX);
      Serial.print(" ");
    }
  Serial.println();
#endif

  // TX start
  writeRegPair(ETXSTL, start);
  // Set the TXND pointer to correspond to the packet size given
  writeRegPair(ETXNDL, end);
  // send the contents of the transmit buffer onto the network
  writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
  // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
  if( (readReg(EIR) & EIR_TXERIF) )
    {
      writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
    }

  //restore data on control-byte position
  if (data)
    writeByte(start, data);
}
Ejemplo n.º 5
0
uint32 InterpretedVM::GetTypeByteSize(uint32 typeId) const {
  if (TypeByteSizes.find(typeId) != TypeByteSizes.end()) {
    return TypeByteSizes.at(typeId);
  }

  auto definedType = prog.DefinedTypes.at(typeId);
  uint32 size = 0;

  switch (definedType.Op)
  {
  case Op::OpTypeArray: {
    auto arr = (STypeArray*)definedType.Memory;
    size = GetTypeByteSize(size) * *(uint32*)env.Values[arr->LengthId].Memory;
    break;
  }
  case Op::OpTypeInt: {
    auto i = (STypeInt*)definedType.Memory;
    assert(i->Width % 8 == 0);
    size = i->Width / 8;
    break;
  }
  case Op::OpTypeFloat: {
    auto f = (STypeFloat*)definedType.Memory;
    assert(f->Width % 8 == 0);
    size = f->Width / 8;
    break;
  }
  case Op::OpTypeBool: {
    size = sizeof(bool);
    break;
  }
  case Op::OpTypePointer: {
    size = sizeof(void*);
    break;
  }
  case Op::OpTypeStruct: {
    auto s = (STypeStruct*)definedType.Memory;
    for (int i = 0; i < s->MembertypeIdsCount; i++) {
      uint32 id = s->MembertypeIds[i];
      size += GetTypeByteSize(id);
    }
    break;
  }
  case Op::OpTypeVector: {
    auto v = (STypeVector*)definedType.Memory;
    size = GetTypeByteSize(v->ComponenttypeId) * v->Componentcount;
    break;
  }
  default:
    std::cout << "Not a type definition: " << writeOp(definedType);
  }

  //TODO: Precalc type sizes
  //TypeByteSizes[typeId] = size;
  return size;
}
Ejemplo n.º 6
0
	void CEnc28J60::setBank(uint8_t address)
	{
		// set the bank (if needed)
		if((address & BANK_MASK) != mEnc28j60Bank)
		{
			// set the bank
			writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
			writeOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);
			mEnc28j60Bank = (address & BANK_MASK);
		}
Ejemplo n.º 7
0
bool InterpretedVM::InitializeConstants() {
  for (auto& constant : prog.Constants) {
    auto op = constant.second;
    switch (op.Op) {
    case Op::OpConstant: {
      auto constant = (SConstant*)op.Memory;
      Value val = { constant->ResultTypeId, (byte*)constant->Values };
      env.Values[constant->ResultId] = val;
      break;
    }
    case Op::OpConstantComposite: {
      auto constant = (SConstantComposite*)op.Memory;
      Value val = { constant->ResultTypeId, VmAlloc(constant->ResultTypeId) };
      env.Values[constant->ResultId] = val;
      byte* memPtr = val.Memory;
      for (int i = 0; i < constant->ConstituentsIdsCount; i++) {
        auto memVal = env.Values[constant->ConstituentsIds[i]];
        uint32 memSize = GetTypeByteSize(memVal.TypeId);
        memcpy(memPtr, memVal.Memory, memSize);
        memPtr += memSize;
      }
      assert( memPtr - val.Memory == GetTypeByteSize(constant->ResultTypeId));
      break;
    }
    case Op::OpConstantFalse: {
      auto constant = (SConstantFalse*)op.Memory;
      Value val = { constant->ResultTypeId, VmAlloc(constant->ResultTypeId) };
      *(bool*)val.Memory = false;
      break;
    }
    case Op::OpConstantTrue: {
      auto constant = (SConstantTrue*)op.Memory;
      Value val = { constant->ResultTypeId, VmAlloc(constant->ResultTypeId) };
      *(bool*)val.Memory = true;
      break;
    }
    default:
      std::cout << "Operation does not define a constant: " << writeOp(op);
      return false;
    }
  }

  return true;
}
Ejemplo n.º 8
0
bool Parser::ParseProgram(Program* prog) {
    if (!expectAndEat(spv::MagicNumber)) {
        return false;
    }

    prog->Version = getAndEat();
    std::cout << "Version: " << prog->Version << std::endl;

    prog->GeneratorMagic = getAndEat();
    std::cout << "Generator Magic: " << prog->GeneratorMagic << std::endl;

    prog->IDBound = getAndEat();
    std::cout << "ID Bound: " << prog->IDBound << std::endl;

    prog->InstructionSchema = getAndEat();
    std::cout << "Instruction Schema: " << prog->InstructionSchema << std::endl;
    std::cout << "=================================================" << std::endl;

    int instructionIndex = 0;

    prog->NextOp = readInstruction();

    do {
        SOp op = prog->NextOp;
        std::cout << std::setw(3) << instructionIndex << ": " << writeOp(op);
        instructionIndex++;
        if (!end()) {
            prog->NextOp = readInstruction();
        }
        else {
            prog->NextOp = SOp{ Op::OpNop, nullptr };
        }

        LUTHandlerMethods[op.Op]((void*)op.Memory, prog);

        if (prog->InFunction && prog->CurrentFunction->InBlock) {
            addOp(prog, op);
        }

    } while (prog->NextOp.Op != Op::OpNop);

    return true;
}
Ejemplo n.º 9
0
memhandle
Enc28J60Network::receivePacket()
{
  uint16_t rxstat;
  uint16_t len;
  // check if a packet has been received and buffered
  //if( !(readReg(EIR) & EIR_PKTIF) ){
  // The above does not work. See Rev. B4 Silicon Errata point 6.
  if (readReg(EPKTCNT) != 0)
    {
      readPtr = nextPacketPtr+6;
      // Set the read pointer to the start of the received packet
      writeReg(ERDPTL, (nextPacketPtr));
      writeOp(ENC28J60_WRITE_CTRL_REG, ERDPTH, (nextPacketPtr) >> 8);
      // read the next packet pointer
      nextPacketPtr = readOp(ENC28J60_READ_BUF_MEM, 0);
      nextPacketPtr |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
      // read the packet length (see datasheet page 43)
      len = readOp(ENC28J60_READ_BUF_MEM, 0);
      len |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
      len -= 4; //remove the CRC count
      // read the receive status (see datasheet page 43)
      rxstat = readOp(ENC28J60_READ_BUF_MEM, 0);
      rxstat |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
      // decrement the packet counter indicate we are done with this packet
      writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
      // check CRC and symbol errors (see datasheet page 44, table 7-3):
      // The ERXFCON.CRCEN is set by default. Normally we should not
      // need to check this.
      if ((rxstat & 0x80) != 0)
        {
          receivePkt.begin = readPtr;
          receivePkt.size = len;
          return UIP_RECEIVEBUFFERHANDLE;
        }
      // Move the RX read pointer to the start of the next received packet
      // This frees the memory we just read out
      writeReg(ERXRDPTL, (nextPacketPtr));
      writeReg(ERXRDPTH, (nextPacketPtr) >> 8);
    }
Ejemplo n.º 10
0
static asynStatus writeOpOnce(const char *port, int addr,
    epicsFloat64 value,double timeout,const char *drvInfo)
{
    asynStatus status;
    asynUser   *pasynUser;

    status = connect(port,addr,&pasynUser,drvInfo);
    if(status!=asynSuccess) {
       asynPrint(pasynUser, ASYN_TRACE_ERROR,
           "asynFloat64SyncIO connect failed %s\n",
           pasynUser->errorMessage);
        disconnect(pasynUser);
        return status;
    }
    status = writeOp(pasynUser,value,timeout);
    if(status!=asynSuccess) {
       asynPrint(pasynUser, ASYN_TRACE_ERROR,
            "asynFloat64SyncIO writeOp failed %s\n",pasynUser->errorMessage);
    }
    disconnect(pasynUser);
    return status;
}
Ejemplo n.º 11
0
static void SetBank (byte address) {
    if ((address & BANK_MASK) != Enc28j60Bank) {
        writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_BSEL1|ECON1_BSEL0);
        Enc28j60Bank = address & BANK_MASK;
        writeOp(ENC28J60_BIT_FIELD_SET, ECON1, Enc28j60Bank>>5);
    }
Ejemplo n.º 12
0
void Enc28J60Network::init(uint8_t* macaddr)
{
  // initialize I/O
  // ss as output:
  pinMode(ENC28J60_CONTROL_CS, OUTPUT);
  CSPASSIVE; // ss=0
  //
  pinMode(SPI_MOSI, OUTPUT);

  pinMode(SPI_SCK, OUTPUT);

  pinMode(SPI_MISO, INPUT);


  digitalWrite(SPI_MOSI, LOW);

  digitalWrite(SPI_SCK, LOW);

  /*DDRB  |= 1<<PB3 | 1<<PB5; // mosi, sck output
  cbi(DDRB,PINB4); // MISO is input
  //
  cbi(PORTB,PB3); // MOSI low
  cbi(PORTB,PB5); // SCK low
  */
  //
  // initialize SPI interface
  // master mode and Fosc/2 clock:
  SPCR = (1<<SPE)|(1<<MSTR);
  SPSR |= (1<<SPI2X);
  // perform system reset
  writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
  delay(50);
  // check CLKRDY bit to see if reset is complete
  // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
  //while(!(readReg(ESTAT) & ESTAT_CLKRDY));
  // do bank 0 stuff
  // initialize receive buffer
  // 16-bit transfers, must write low byte first
  // set receive buffer start address
  nextPacketPtr = RXSTART_INIT;
  // Rx start
  writeRegPair(ERXSTL, RXSTART_INIT);
  // set receive pointer address
  writeRegPair(ERXRDPTL, RXSTART_INIT);
  // RX end
  writeRegPair(ERXNDL, RXSTOP_INIT);
  // TX start
  //writeRegPair(ETXSTL, TXSTART_INIT);
  // TX end
  //writeRegPair(ETXNDL, TXSTOP_INIT);
  // do bank 1 stuff, packet filter:
  // For broadcast packets we allow only ARP packtets
  // All other packets should be unicast only for our mac (MAADR)
  //
  // The pattern to match on is therefore
  // Type     ETH.DST
  // ARP      BROADCAST
  // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
  // in binary these poitions are:11 0000 0011 1111
  // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
  //TODO define specific pattern to receive dhcp-broadcast packages instead of setting ERFCON_BCEN!
  writeReg(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN);
  writeRegPair(EPMM0, 0x303f);
  writeRegPair(EPMCSL, 0xf7f9);
  //
  //
  // do bank 2 stuff
  // enable MAC receive
  // and bring MAC out of reset (writes 0x00 to MACON2)
  writeRegPair(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
  // enable automatic padding to 60bytes and CRC operations
  writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
  // set inter-frame gap (non-back-to-back)
  writeRegPair(MAIPGL, 0x0C12);
  // set inter-frame gap (back-to-back)
  writeReg(MABBIPG, 0x12);
  // Set the maximum packet size which the controller will accept
  // Do not send packets longer than MAX_FRAMELEN:
  writeRegPair(MAMXFLL, MAX_FRAMELEN);
  // do bank 3 stuff
  // write MAC address
  // NOTE: MAC address in ENC28J60 is byte-backward
  writeReg(MAADR5, macaddr[0]);
  writeReg(MAADR4, macaddr[1]);
  writeReg(MAADR3, macaddr[2]);
  writeReg(MAADR2, macaddr[3]);
  writeReg(MAADR1, macaddr[4]);
  writeReg(MAADR0, macaddr[5]);
  // no loopback of transmitted frames
  phyWrite(PHCON2, PHCON2_HDLDIS);
  // switch to bank 0
  setBank(ECON1);
  // enable interrutps
  writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
  // enable packet reception
  writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
  //Configure leds
  phyWrite(PHLCON,0x476);
}
Ejemplo n.º 13
0
/* ======================================================================= */
ENC28J60Driver::ENC28J60Driver(uint8_t* macaddr, uint8_t csPin): 
  EthernetDriver(macaddr){

  this->sendBuffer = new ENC28J60Buffer(this,TXSTART_INIT+1,
					TXSTOP_INIT,
					MAX_FRAMELEN,
					0,false);
  this->recvBuffer = new ENC28J60Buffer(this,RXSTART_INIT,
					RXSTOP_INIT,
					MAX_FRAMELEN,
					0,true);
  this->stashBuffer = new ENC28J60Buffer(this,STASH_START_INIT,
					 STASH_STOP_INIT,
					 STASH_STOP_INIT - STASH_START_INIT +1,
					 0,false);
					 

  if (bitRead(SPCR, SPE) == 0)
    initSPI();

  selectPin = csPin;  
  pinMode(selectPin, OUTPUT);
  disableChip();

  writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
  delay(2); // errata B7/2

  while (!readOp(ENC28J60_READ_CTRL_REG, ESTAT) & ESTAT_CLKRDY)
    ;
  
  gNextPacketPtr = RXSTART_INIT;
  writeReg(ERXST, RXSTART_INIT);
  writeReg(ERXRDPT, RXSTART_INIT);
  writeReg(ERXND, RXSTOP_INIT);
  writeReg(ETXST, TXSTART_INIT);
  writeReg(ETXND, TXSTOP_INIT);
  
  writeRegByte(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN);

  writeReg(EPMM0, 0x303f);
  writeReg(EPMCS, 0xf7f9);
  writeRegByte(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
  writeRegByte(MACON2, 0x00);
  writeOp(ENC28J60_BIT_FIELD_SET, MACON3,
	  MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
  writeReg(MAIPG, 0x0C12);
  writeRegByte(MABBIPG, 0x12);
  writeReg(MAMXFL, MAX_FRAMELEN);  
  writeRegByte(MAADR5, macaddr[0]);
  writeRegByte(MAADR4, macaddr[1]);
  writeRegByte(MAADR3, macaddr[2]);
  writeRegByte(MAADR2, macaddr[3]);
  writeRegByte(MAADR1, macaddr[4]);
  writeRegByte(MAADR0, macaddr[5]);
  writePhy(PHCON2, PHCON2_HDLDIS);
  SetBank(ECON1);
  writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
  writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
  
  this->revision = readRegByte(EREVID);
  // microchip forgot to step the number on the silcon when they
  // released the revision B7. 6 is now rev B7. We still have
  // to see what they do when they release B8. At the moment
  // there is no B8 out yet
  if (this->revision > 5) this->revision++;
}
Ejemplo n.º 14
0
void Enc28J60Network::init(uint8_t* macaddr)
{
  MemoryPool::init(); // 1 byte in between RX_STOP_INIT and pool to allow prepending of controlbyte
  // initialize I/O
  // ss as output:
  pinMode(ENC28J60_CONTROL_CS, OUTPUT);
  CSPASSIVE; // ss=0
  //

#ifdef ENC28J60DEBUG
  Serial.println("ENC28J60::initialize / before initSPI()");
#endif
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
//  SPI.setDataMode(SPI_MODE0);
//  SPI.setClockDivider(SPI_CLOCK_DIV16);
#ifdef ENC28J60DEBUG
  Serial.println("ENC28J60::initialize / after initSPI()");
  Serial.print("ENC28J60::initialize / csPin = ");
  Serial.println(SPI.nssPin());
  Serial.print("ENC28J60::initialize / miso = ");
  Serial.println(SPI.misoPin());
  Serial.print("ENC28J60::initialize / mosi = ");
  Serial.println(SPI.mosiPin());
  Serial.print("ENC28J60::initialize / sck = ");
  Serial.println(SPI.sckPin());
#endif
  selectPin = ENC28J60_CONTROL_CS;
  pinMode(selectPin, OUTPUT);
  digitalWrite(selectPin, HIGH);
	
  // perform system reset
  writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
  delay(2); // errata B7/2
  delay(50);
  // check CLKRDY bit to see if reset is complete
  // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
  //while(!(readReg(ESTAT) & ESTAT_CLKRDY));
  // do bank 0 stuff
  // initialize receive buffer
  // 16-bit transfers, must write low byte first
  // set receive buffer start address
#ifdef ENC28J60DEBUG
  Serial.println("ENC28J60::initialize / before readOp(ENC28J60_READ_CTRL_REG, ESTAT)");
#endif
  while (!readOp(ENC28J60_READ_CTRL_REG, ESTAT) & ESTAT_CLKRDY)
      ;
#ifdef ENC28J60DEBUG
  Serial.println("ENC28J60::initialize / after readOp(ENC28J60_READ_CTRL_REG, ESTAT)");
#endif
  nextPacketPtr = RXSTART_INIT;
  // Rx start
  writeRegPair(ERXSTL, RXSTART_INIT);
  // set receive pointer address
  writeRegPair(ERXRDPTL, RXSTART_INIT);
  // RX end
  writeRegPair(ERXNDL, RXSTOP_INIT);
  // TX start
  //-------------writeRegPair(ETXSTL, TXSTART_INIT);
  // TX end
  //-------------writeRegPair(ETXNDL, TXSTOP_INIT);
  // do bank 1 stuff, packet filter:
  // For broadcast packets we allow only ARP packtets
  // All other packets should be unicast only for our mac (MAADR)
  //
  // The pattern to match on is therefore
  // Type     ETH.DST
  // ARP      BROADCAST
  // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
  // in binary these poitions are:11 0000 0011 1111
  // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
  //TODO define specific pattern to receive dhcp-broadcast packages instead of setting ERFCON_BCEN!
//    enableBroadcast(); // change to add ERXFCON_BCEN recommended by epam
  writeReg(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN|ERXFCON_BCEN);
  writeRegPair(EPMM0, 0x303f);
  writeRegPair(EPMCSL, 0xf7f9);
  //
  //
  // do bank 2 stuff
  // enable MAC receive
  // and bring MAC out of reset (writes 0x00 to MACON2)
  writeRegPair(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
  //----------------writeRegPair(MACON2, 0x00);
  // enable automatic padding to 60bytes and CRC operations
  writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
  // set inter-frame gap (non-back-to-back)
  writeRegPair(MAIPGL, 0x0C12);
  // set inter-frame gap (back-to-back)
  writeReg(MABBIPG, 0x12);
  // Set the maximum packet size which the controller will accept
  // Do not send packets longer than MAX_FRAMELEN:
  writeRegPair(MAMXFLL, MAX_FRAMELEN);
  // do bank 3 stuff
  // write MAC address
  // NOTE: MAC address in ENC28J60 is byte-backward
  writeReg(MAADR5, macaddr[0]);
  writeReg(MAADR4, macaddr[1]);
  writeReg(MAADR3, macaddr[2]);
  writeReg(MAADR2, macaddr[3]);
  writeReg(MAADR1, macaddr[4]);
  writeReg(MAADR0, macaddr[5]);
  // no loopback of transmitted frames
  phyWrite(PHCON2, PHCON2_HDLDIS);
  // switch to bank 0
  setBank(ECON1);
  // enable interrutps
  writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
  // enable packet reception
  writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
  //Configure leds
  phyWrite(PHLCON,0x476);

  byte rev = readReg(EREVID);
  // microchip forgot to step the number on the silcon when they
  // released the revision B7. 6 is now rev B7. We still have
  // to see what they do when they release B8. At the moment
  // there is no B8 out yet
  if (rev > 5) ++rev;
#ifdef ENC28J60DEBUG
  Serial.print("ENC28J60::initialize returns ");
  Serial.println(rev);
#endif
//  return rev;
}
Ejemplo n.º 15
0
void Enc28J60Network::writeRegByte (uint8_t address, uint8_t data) {
    setBank(address);
    writeOp(ENC28J60_WRITE_CTRL_REG, address, data);
}
Ejemplo n.º 16
0
uint32 InterpretedVM::Execute(Function* func) {
  prog.CurrentFunction = func;

  int pc = 0;

  for (;;) {
    auto op = func->Ops[pc];
    switch (op.Op) {
    case Op::OpBranch: {
      auto branch = (SBranch*)op.Memory;
      pc = func->Labels.at(branch->TargetLabelId);
      break;
    }
    case Op::OpBranchConditional: {
      auto branch = (SBranchConditional*)op.Memory;
      uint32 labelID;
      Value val = Dereference(env.Values[branch->ConditionId]);
      if (*(bool*)val.Memory) {
        labelID = branch->TrueLabelId;
      } else {
        labelID = branch->FalseLabelId;
      }
      pc = func->Labels.at(labelID);
      break;
    }
    case Op::OpFunctionCall: {
      auto call = (SFunctionCall*)op.Memory;
      Function toCall = prog.FunctionDefinitions.at(call->FunctionId);
      for (int i = 0; i < call->ArgumentIdsCount; i++) {
        env.Values[toCall.Parameters[i].ResultId] = Dereference(env.Values.at(call->ArgumentIds[i]));
      }
      uint32 resultId = Execute(&toCall);
      if (resultId == -1) {
        return -1;
      }
      prog.CurrentFunction = func;
      env.Values[call->ResultId] = env.Values[resultId];
      break;
    }
    case Op::OpExtInst: {
      auto extInst = (SExtInst*)op.Memory;
      Value* ops = new Value[extInst->OperandIdsCount];
      for (int i = 0; i < extInst->OperandIdsCount; i++) {
        ops[i] = Dereference(env.Values.at(extInst->OperandIds[i]));
      }

      ExtInstFunc* func = env.Extensions[extInst->SetId][extInst->Instruction];
      env.Values[extInst->ResultId] = func(this, extInst->ResultTypeId, extInst->OperandIdsCount, ops);
      break;
    }
    case Op::OpConvertSToF: {
      auto convert = (SConvertSToF*)op.Memory;
      Value op1 = Dereference(env.Values[convert->SignedValueId]);
      env.Values[convert->ResultId] = DoOp(convert->ResultTypeId, Convert<int32, float>, op1);
      break;
    }
    case Op::OpFAdd: {
      auto add = (SFAdd*)op.Memory;
      Value op1 = Dereference(env.Values[add->Operand1Id]);
      Value op2 = Dereference(env.Values[add->Operand2Id]);
      env.Values[add->ResultId] = DoOp(add->ResultTypeId, Add<float>, op1, op2);
      break;
    }
    case Op::OpIAdd: {
      auto add = (SIAdd*)op.Memory;
      Value op1 = Dereference(env.Values[add->Operand1Id]);
      Value op2 = Dereference(env.Values[add->Operand2Id]);
      env.Values[add->ResultId] = DoOp(add->ResultTypeId, Add<int>, op1, op2);
      break;
    }
    case Op::OpFSub: {
      auto sub = (SFSub*)op.Memory;
      Value op1 = Dereference(env.Values[sub->Operand1Id]);
      Value op2 = Dereference(env.Values[sub->Operand2Id]);
      env.Values[sub->ResultId] = DoOp(sub->ResultTypeId, Sub<float>, op1, op2);
      break;
    }
    case Op::OpISub: {
      auto sub = (SISub*)op.Memory;
      Value op1 = Dereference(env.Values[sub->Operand1Id]);
      Value op2 = Dereference(env.Values[sub->Operand2Id]);
      env.Values[sub->ResultId] = DoOp(sub->ResultTypeId, Sub<int>, op1, op2);
      break;
    }
    case Op::OpFDiv: {
      auto div = (SFDiv*)op.Memory;
      Value op1 = Dereference(env.Values[div->Operand1Id]);
      Value op2 = Dereference(env.Values[div->Operand2Id]);
      env.Values[div->ResultId] = DoOp(div->ResultTypeId, Div<float>, op1, op2);
      break;
    }
    case Op::OpFMul: {
      auto mul = (SFMul*)op.Memory;
      Value op1 = Dereference(env.Values[mul->Operand1Id]);
      Value op2 = Dereference(env.Values[mul->Operand2Id]);
      env.Values[mul->ResultId] = DoOp(mul->ResultTypeId, Mul<float>, op1, op2);
      break;
    }
    case Op::OpIMul: {
      auto mul = (SFMul*)op.Memory;
      Value op1 = Dereference(env.Values[mul->Operand1Id]);
      Value op2 = Dereference(env.Values[mul->Operand2Id]);
      env.Values[mul->ResultId] = DoOp(mul->ResultTypeId, Mul<int>, op1, op2);
      break;
    }
    case Op::OpVectorTimesScalar: {
      auto vts = (SVectorTimesScalar*)op.Memory;
      Value scalar = Dereference(env.Values[vts->ScalarId]);
      Value vector = Dereference(env.Values[vts->VectorId]);
      env.Values[vts->ResultId] = DoOp(vts->ResultTypeId, [scalar](Value comp) {return Mul<float>(scalar, comp);}, vector);
      break;
    }
    case Op::OpSLessThan: {
      auto lessThan = (SSLessThan*)op.Memory;
      Value op1 = Dereference(env.Values[lessThan->Operand1Id]);
      Value op2 = Dereference(env.Values[lessThan->Operand2Id]);
      env.Values[lessThan->ResultId] = DoOp(lessThan->ResultTypeId, [](Value a, Value b) { return Cmp<int32>(a, b) == -1; }, op1, op2);
      break;
    }
    case Op::OpSGreaterThan: {
      auto greaterThan = (SSLessThan*)op.Memory;
      Value op1 = Dereference(env.Values[greaterThan->Operand1Id]);
      Value op2 = Dereference(env.Values[greaterThan->Operand2Id]);
      env.Values[greaterThan->ResultId] = DoOp(greaterThan->ResultTypeId, [](Value a, Value b) { return Cmp<int32>(a, b) == 1; }, op1, op2);
      break;
    }
    case Op::OpLoad: {
      auto load = (SLoad*)op.Memory;
      auto valueToLoad = env.Values.at(load->PointerId);
      env.Values[load->ResultId] = valueToLoad;
      break;
    }
    case Op::OpStore: {
      auto store = (SStore*)op.Memory;
      auto val = env.Values[store->ObjectId];
      auto var = GetType(val.TypeId);
      if (var.Op == Op::OpTypePointer) {
        SetVariable(store->PointerId, val.Memory);
      } else {
        SetVariable(store->PointerId, &val.Memory);
      }
      break;
    }
    case Op::OpTextureSample: {
      auto sample = (STextureSample*)op.Memory;
      auto sampler = Dereference(env.Values.at(sample->SamplerId));
      auto coord = Dereference(env.Values.at(sample->CoordinateId));
      Value bias = { 0, 0 };
      if (sample->BiasId != 0) {
        bias = Dereference(env.Values.at(sample->BiasId));
      }

      env.Values[sample->ResultId] = TextureSample(sampler, coord, bias, sample->ResultTypeId);
      break;
    }
    case Op::OpLabel:
    case Op::OpSelectionMerge:
    case Op::OpLoopMerge:
      break;
    case Op::OpAccessChain: {
      auto access = (SAccessChain*)op.Memory;
      auto val = Dereference(env.Values.at(access->BaseId));

      uint32* indices = new uint32[access->IndexesIdsCount];
      for (int i = 0; i < access->IndexesIdsCount; i++) {
        indices[i] = *(uint32*)Dereference(env.Values[access->IndexesIds[i]]).Memory;
      }

      byte* mem = GetPointerInComposite(val.TypeId, val.Memory, access->IndexesIdsCount, indices);
      delete indices;

      Value res = VmInit(access->ResultTypeId, &mem);
      env.Values[access->ResultId] = res;
      break;
    }
    case Op::OpVectorShuffle: {
      auto vecShuffle = (SVectorShuffle*)op.Memory;
      auto vec1 = Dereference(env.Values.at(vecShuffle->Vector1Id));
      auto vec2 = Dereference(env.Values.at(vecShuffle->Vector2Id));

      auto result = VmInit(vecShuffle->ResultTypeId, nullptr);
      int v1ElCount = ElementCount(vec1.TypeId);
      for (int i = 0; i < vecShuffle->ComponentsCount; i++) {
        int index = vecShuffle->Components[i];
        Value toCopy;
        if (index < v1ElCount) {
          toCopy = vec1;
        } else {
          index -= v1ElCount;
          toCopy = vec2;
        }

        Value elToCopy = IndexMemberValue(toCopy, index);
        memcpy(IndexMemberValue(result, i).Memory, elToCopy.Memory, GetTypeByteSize(elToCopy.TypeId));
      }

      env.Values[vecShuffle->ResultId] = result;
      break;
    }
    //TODO: FIX INDICES (NOT HIERARCHY!)
    case Op::OpCompositeExtract: {
      auto extract = (SCompositeExtract*)op.Memory;
      auto composite = env.Values[extract->CompositeId];
      byte* mem = GetPointerInComposite(composite.TypeId, composite.Memory, extract->IndexesCount, extract->Indexes);
      Value val = { extract->ResultTypeId, VmAlloc(extract->ResultTypeId) };
      memcpy(val.Memory, mem, GetTypeByteSize(val.TypeId));
      env.Values[extract->ResultId] = val;
      break;
    }
    case Op::OpCompositeInsert: {
      auto insert = (SCompositeInsert*)op.Memory;
      auto composite = Dereference(env.Values[insert->CompositeId]);
      Value val = Dereference(env.Values.at(insert->ObjectId));
      byte* mem = GetPointerInComposite(composite.TypeId, composite.Memory, insert->IndexesCount, insert->Indexes);
      memcpy(mem, val.Memory, GetTypeByteSize(val.TypeId));
      env.Values[insert->ResultId] = VmInit(composite.TypeId, composite.Memory);
      break;
    }
    case Op::OpCompositeConstruct: {
      auto construct = (SCompositeConstruct*)op.Memory;
      Value val = { construct->ResultTypeId, VmAlloc(construct->ResultTypeId) };
      env.Values[construct->ResultId] = val;
      byte* memPtr = val.Memory;
      for (int i = 0; i < construct->ConstituentsIdsCount; i++) {
        auto memVal = env.Values[construct->ConstituentsIds[i]];
        uint32 memSize = GetTypeByteSize(memVal.TypeId);
        memcpy(memPtr, memVal.Memory, memSize);
        memPtr += memSize;
      }
      assert(memPtr - val.Memory == GetTypeByteSize(construct->ResultTypeId));
      break;
    }
    case Op::OpVariable: {
      auto var = (SVariable*)op.Memory;
      Value val = { var->ResultTypeId, VmAlloc(var->ResultTypeId) };
      if (var->InitializerId) {
        memcpy(val.Memory, env.Values[var->InitializerId].Memory, GetTypeByteSize(val.TypeId));
      }
      else {
        memset(val.Memory, 0, GetTypeByteSize(val.TypeId));
      }
      env.Values[var->ResultId] = val;
      break;
    }
    case Op::OpReturnValue: {
      auto ret = (SReturnValue*)op.Memory;
      return ret->ValueId;
    }
    case Op::OpReturn:
      return 0;
    default:
      std::cout << "Unimplemented operation: " << writeOp(op);
      return -1;
    }

    pc++;
  }
  return 0;
}
Ejemplo n.º 17
0
void ENC28J60Driver::SetBank (uint8_t address) {
    if ((address & BANK_MASK) != Enc28j60Bank) {
        writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_BSEL1|ECON1_BSEL0);
        Enc28j60Bank = address & BANK_MASK;
        writeOp(ENC28J60_BIT_FIELD_SET, ECON1, Enc28j60Bank>>5);
    }