void enc28j60_send_packet(unsigned int len, unsigned char *buffer) { unsigned int tmp; //still sending ? //wait max 50*10 = 500ms: for(tmp=0; tmp<50; tmp++){ if (!(enc28j60_read_address(ENC28J60_REG_ECON1) & (1<<ENC28J60_BIT_TXRTS))){ //send finished -> tx packet break; } //tx not finished yet, wait 10ms _delay_ms(1); } //send anyway... //setup write pointer: enc28j60_write_address(ENC28J60_REG_EWRPTL, (ENC28J60_TX_BUFFER_START&0xFF)); enc28j60_write_address(ENC28J60_REG_EWRPTH, (ENC28J60_TX_BUFFER_START)>>8); //set tx end pointer to [start+len]: enc28j60_write_address(ENC28J60_REG_ETXNDL, (ENC28J60_TX_BUFFER_START+len)&0xFF); enc28j60_write_address(ENC28J60_REG_ETXNDH, (ENC28J60_TX_BUFFER_START+len)>>8); //start buffer write command enc28j60_spi_write_word(ENC28J60_OP_WRITE_BUF_MEM, 0x00); //copy buffer to enc28j60: enc28j60_write_buffer(buffer, len); //bad silicon workaround: //reset tx logic: enc28j60_spi_write_word(ENC28J60_OP_BFS | ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_TXRST)); enc28j60_spi_write_word(ENC28J60_OP_BFC | ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_TXRST)); //activate transmission enc28j60_spi_write_word(ENC28J60_OP_BFS | ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_TXRTS)|(1<<ENC28J60_BIT_RXEN)); }
/** * Writes a packet to the RAM buffer of the ENC28J60 and starts transmission. * * The packet buffer contains the ethernet header and the payload without CRC. * The checksum is automatically generated by the on-chip calculator. * * \param[in] buffer A pointer to the buffer containing the packet to be sent. * \param[in] buffer_len The length of the ethernet packet header plus payload. * \returns \c true if the packet was sent, \c false otherwise. */ bool enc28j60_send_packet(uint8_t* buffer, uint16_t buffer_len) { if(!buffer || !buffer_len) return false; /* DS80349C.errata #12 */ if(enc28j60_read(EIR) & (1 << EIR_TXERIF)) { enc28j60_set_bits(ECON1, (1 << ECON1_TXRST)); enc28j60_clear_bits(ECON1, (1 << ECON1_TXRST)); } /* wait until previous packet was sent */ while(enc28j60_read(ECON1) & (1 << ECON1_TXRTS)); /* set start of packet */ enc28j60_write(ETXSTL, TX_START & 0xff); enc28j60_write(ETXSTH, TX_START >> 8); /* set end of packet */ enc28j60_write(ETXNDL, (TX_START + buffer_len) & 0xff); enc28j60_write(ETXNDH, (TX_START + buffer_len) >> 8); /* set write pointer */ enc28j60_write(EWRPTL, TX_START & 0xff); enc28j60_write(EWRPTH, TX_START >> 8); /* per packet control byte */ enc28j60_write_buffer_byte(0x00); /* send packet */ enc28j60_write_buffer(buffer, buffer_len); /* start transmission */ enc28j60_set_bits(ECON1, (1 << ECON1_TXRTS)); return true; }