Exemplo n.º 1
0
static void ni5010_transmit(struct nic *nic,
	const char *d,	/* Destination */
	unsigned int t,	/* Type */
	unsigned int s,	/* size */
	const char *p)	/* Packet */
{
	unsigned int	len;
	int		buf_offs, xmt_stat;
	unsigned long	time;

	len = s + ETH_HLEN;
	if (len < ETH_ZLEN)
		len = ETH_ZLEN;
	buf_offs = NI5010_BUFSIZE - len;
	outb(0, EDLC_RMASK);	/* Mask all receive interrupts */
	outb(0, IE_MMODE);	/* Put Xmit buffer on system bus */
	outb(0xFF, EDLC_RCLR);	/* Clear out pending rcv interrupts */
	outw(buf_offs, IE_GP);	/* Point GP at start of packet */
	outsb(IE_XBUF, d, ETH_ALEN);	/* Put dst in buffer */
	outsb(IE_XBUF, nic->node_addr, ETH_ALEN);/* Put src in buffer */
	outb(t >> 8, IE_XBUF);
	outb(t, IE_XBUF);
	outsb(IE_XBUF, p, s);	/* Put data in buffer */
	while (s++ < ETH_ZLEN - ETH_HLEN)	/* Pad to min size */
		outb(0, IE_XBUF);
	outw(buf_offs, IE_GP);	/* Rewrite where packet starts */
	/* should work without that outb() (Crynwr used it) */
	/*outb(MM_MUX, IE_MMODE);*/
	/* Xmt buffer to EDLC bus */
	outb(MM_EN_XMT | MM_MUX, IE_MMODE);	/* Begin transmission */
	/* wait for transmit complete */
	while (((xmt_stat = inb(IE_ISTAT)) & IS_EN_XMT) != 0)
		;
	reset_receiver();	/* Immediately switch to receive */
}
Exemplo n.º 2
0
uint8_t radio_resize_receiver_buffer(Radio * radio, size_t size)
{
	uint8_t receiver_powered = radio->receiver_powered();

	if(receiver_powered && radio->received_bytes_count)
		return 1;

	radio->receiver_power(0);
	radio->received_bytes_count = 0;
	radio->buffer_size = 0;

	if(radio->received_message) {
		free(radio->received_message);
		radio->received_message = 0;
	}

	radio->received_message = malloc(size);

	if(!radio->received_message)
		return 1;

	radio->buffer_size = size;
	reset_receiver(radio);

	if(receiver_powered)
		radio->receiver_power(1);

	return 0;
}
Exemplo n.º 3
0
uint8_t radio_send(void * radio_pointer, const uint8_t * content,
                   size_t content_size)
{
	Radio * radio = (Radio *)radio_pointer;
	uint8_t receiver_powered = radio->receiver_powered();

	if(receiver_powered) {
		if(radio->received_bytes_count)
			return 1;

		radio->receiver_power(0);
		radio->received_bytes_count = 0;
		reset_receiver(radio);
	}

	radio->transmitting = 1;
	radio->transmitter_power(1);
	radio_transmit_bytes(radio, content, content_size);
	radio->transmitter_power(0);
	radio->transmitting = 0;

	if(receiver_powered)
		radio->receiver_power(1);

	return 0;
}
Exemplo n.º 4
0
static void ni5010_reset(struct nic *nic)
{
	int		i;

	/* Reset the hardware here.  Don't forget to set the station address. */
	outb(RS_RESET, EDLC_RESET);	/* Hold up EDLC_RESET while configing board */
	outb(0, IE_RESET);	/* Hardware reset of ni5010 board */
	outb(0, EDLC_XMASK);	/* Disable all Xmt interrupts */
	outb(0, EDLC_RMASK);	/* Disable all Rcv interrupt */
	outb(0xFF, EDLC_XCLR);	/* Clear all pending Xmt interrupts */
	outb(0xFF, EDLC_RCLR);	/* Clear all pending Rcv interrupts */
	outb(XMD_LBC, EDLC_XMODE);	/* Only loopback xmits */
	/* Set the station address */
	for(i = 0; i < ETH_ALEN; i++)
		outb(nic->node_addr[i], EDLC_ADDR + i);
	outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE); 
				/* Normal packet xmit mode */
	outb(RMD_BROADCAST, EDLC_RMODE);
				/* Receive broadcast and normal packets */
	reset_receiver();
	outb(0x00, EDLC_RESET);	/* Un-reset the ni5010 */
}
Exemplo n.º 5
0
void radio_on_receive(Radio * radio)
{
	if(radio->transmitting || !radio->callback_receive)
		return;

	radio_time time = radio->microseconds();
	radio_time duration = time - radio->last_time;
	radio->last_time = time;

	if(time < radio->last_time) {
		reset_receiver(radio);
		return;
	}

	if(duration < 300) {
		reset_receiver(radio);
		return;
	}

	if(!radio->receiving) {
		radio->receiving = 1;
		radio->delay = duration /* sync */ / 31;
		radio->delay_tolerance = radio->delay * radio->tolerance * 0.01;
		radio->bit_count = 0;
		radio->received_bytes_count = 0;
	}

	if(between(duration, radio->delay, 3 * radio->delay, radio->delay_tolerance)) {
		if(byte_odd(radio->change_count)) {
			if(radio->received_bytes_count >= radio->buffer_size) {
				// Overflow
				// Realloc on simple uc would result in memory fragmentation
				// and freeze
				radio->received_bytes_count = 0;
				reset_receiver(radio);
				return;
			}

			if(received_one(radio, duration))
				bit_on(&radio->received_message[radio->received_bytes_count],
				       7 - radio->bit_count++);
			else if(received_zero(radio, duration))
				bit_off(&radio->received_message[radio->received_bytes_count],
				        7 - radio->bit_count++);
			else {
				reset_receiver(radio);
				return;
			}

			if(radio->bit_count == 8) {
				radio->bit_count = 0;
				radio->received_bytes_count++;
			}
		}
	} else if(radio->change_count > 1) {
		reset_receiver(radio);
		return;
	}

	radio->change_count++;
}