Exemplo n.º 1
0
/* 
 * Crude way of flushing the Tx/Rx FIFO: write the first byte as 0, indicating
 * a zero-length frame in the buffer. This is interpreted by the driver as an
 * empty buffer.
 */
static void
flush_buffer(void)
{
  /* NB: tentative untested implementation */
  uint8_t temp = 0;
  trx_frame_write(&temp, 1);
}
Exemplo n.º 2
0
void tal_tx_beacon(frame_info_t *tx_frame)
{
	tal_trx_status_t trx_status;

	/* Set pointer to actual mpdu to be downloaded to the transceiver. */
	uint8_t *tal_beacon_to_tx = tx_frame->mpdu;

	/* Avoid that the beacon is transmitted while other transmision is
	 * on-going. */
	if (tal_state == TAL_TX_AUTO) {
		Assert(
				"trying to transmit beacon while ongoing transmission" ==
				0);
		return;
	}

	/* Send the pre-created beacon frame to the transceiver. */
	do {
		trx_status = set_trx_state(CMD_PLL_ON);
#if (_DEBUG_ > 1)
		if (trx_status != PLL_ON) {
			Assert("PLL_ON failed for beacon transmission" == 0);
		}
#endif
	} while (trx_status != PLL_ON);

	/* \TODO wait for talbeaconTxTime */

	pal_trx_irq_dis();

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * + 1 extra octet (see datasheet)
	 * - 2 octets FCS
	 */
	trx_frame_write(tal_beacon_to_tx, tal_beacon_to_tx[0]);

	tal_beacon_transmission = true;

#ifndef NON_BLOCKING_SPI
	pal_trx_irq_en();
#endif
#ifdef TX_OCTET_COUNTER
	tal_tx_octet_cnt += PHY_OVERHEAD + LENGTH_FIELD_LEN +
			tal_beacon_to_tx[0];
#endif
}
Exemplo n.º 3
0
void radio_send_frame(uint8_t len, uint8_t *frm, uint8_t compcrc)
{
    trx_frame_write(len, frm);
//    frm[2] = frm[2]+1;
    TRX_SLPTR_HIGH();
    TRX_SLPTR_LOW();
}
Exemplo n.º 4
0
void radio_send_frame(uint8_t len, uint8_t *frm, uint8_t compcrc)
{
    /* this block should be made atomic */
    trx_frame_write(len, frm);
    TRX_SLPTR_HIGH();
    TRX_SLPTR_LOW();
    /***********************************/
}
Exemplo n.º 5
0
void tal_tx_beacon(frame_info_t *tx_frame)
{
	tal_trx_status_t trx_status;

	/* Set pointer to actual mpdu to be downloaded to the transceiver. */
	uint8_t *tal_beacon_to_tx = tx_frame->mpdu;

	/* Avoid that the beacon is transmitted while other transmision is
	 *on-going. */
	if (tal_state == TAL_TX_AUTO) {
		Assert(
				"trying to transmit beacon while ongoing transmission" ==
				0);
		return;
	}

	/* Send the pre-created beacon frame to the transceiver. */
	do {
		trx_status = set_trx_state(CMD_PLL_ON);
#if (_DEBUG_ > 1)
		if (trx_status != PLL_ON) {
			Assert("PLL_ON failed for beacon transmission" == 0);
		}

#endif
	} while (trx_status != PLL_ON);

	/* \TODO wait for talbeaconTxTime */

	ENTER_CRITICAL_REGION(); /* prevent from buffer underrun */

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * - 2 octets FCS
	 */
	trx_frame_write(tal_beacon_to_tx, tal_beacon_to_tx[0] - 1);

	tal_beacon_transmission = true;

	LEAVE_CRITICAL_REGION();
}
Exemplo n.º 6
0
void radio_send_frame(uint8_t len, uint8_t *frm, uint8_t compcrc)
{
#ifdef TRX_TX_PA_EI
    if (radiostatus.tx_pa)
    {
        TRX_TX_PA_EI();
    }
#endif
    /* this block should be made atomic */
    TRX_SLPTR_HIGH();
    TRX_SLPTR_LOW();
    trx_frame_write(len, frm);
    /***********************************/
}
Exemplo n.º 7
0
/*
 * \brief Starts continuous transmission on current channel
 *
 * \param tx_mode Mode of continuous transmission (CW or PRBS)
 * \param random_content Use random content if true
 */
void tfa_continuous_tx_start(continuous_tx_mode_t tx_mode, bool random_content)
{
	uint8_t txcwdata[128];

	trx_bit_write(SR_TX_AUTO_CRC_ON, TX_AUTO_CRC_DISABLE);
	trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);
	trx_reg_write(0x36, 0x0F); /*TST_CTRL_DIGI*/

	/* Here: use 2MBPS mode for PSD measurements.
	 * Omit the two following lines, if 250k mode is desired for PRBS mode.
	 **/
	trx_reg_write(RG_TRX_CTRL_2, 0x03);
	trx_reg_write(RG_RX_CTRL, 0xA7);
	if (tx_mode == CW_MODE) {
		txcwdata[0] = 1; /* length */
		/* Step 12 - frame buffer write access */
		txcwdata[1] = 0x00; /* f=fch-0.5 MHz; set value to 0xFF for
		                     * f=fch+0.5MHz */
		trx_frame_write(txcwdata, 2);
	} else { /* PRBS mode */
		txcwdata[0] = 127; /* = max length */
		for (uint8_t i = 1; i < 128; i++) {
			if (random_content) {
				txcwdata[i] = (uint8_t)rand();
			} else {
				txcwdata[i] = 0;
			}
		}
		trx_frame_write(txcwdata, 128);
	}

	trx_reg_write(RG_PART_NUM, 0x54);
	trx_reg_write(RG_PART_NUM, 0x46);
	set_trx_state(CMD_PLL_ON);
	TRX_SLP_TR_HIGH();
	TRX_SLP_TR_LOW();
}
Exemplo n.º 8
0
/**
 * \brief Transmits the frame over-the-air
 */
static void tx_frame(void)
{
	tal_trx_status_t trx_status;

	/*
	 * Trigger transmission
	 * In case of an ongoing reception,
	 * the incoming frame is handled first within ISR.
	 */
	do {
		trx_status = set_trx_state(CMD_TX_ARET_ON);
	} while (trx_status != TX_ARET_ON);

	pal_trx_irq_dis();

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * + 1 extra octet (see datasheet)
	 * - 2 octets FCS
	 */
	trx_frame_write(tal_frame_to_tx, tal_frame_to_tx[0]);

	tal_state = TAL_TX_AUTO;

#ifndef NON_BLOCKING_SPI
	pal_trx_irq_en();
#endif
#ifdef TX_OCTET_COUNTER
	tal_tx_octet_cnt += PHY_OVERHEAD + LENGTH_FIELD_LEN +
			tal_frame_to_tx[0];
#endif
}
Exemplo n.º 9
0
Arquivo: rf233.c Projeto: Idolf/tock
int rf233_prepare(const void *payload, unsigned short payload_len) {
  int i;
  uint8_t templen;
  uint8_t radio_status;
  uint8_t data[130];

  /* Add length of the FCS (2 bytes) */
  templen = payload_len + 2; 
  data[0] = templen;
  for (i = 0; i < templen; i++) {
    data[i + 1] = ((uint8_t*)payload)[i];
  }
  data[3] = (uint8_t)(counter & 0xff);
  counter++;

#if DEBUG_PRINTDATA
  PRINTF("RF233 prepare (%u/%u): 0x", payload_len, templen);
  for(i = 0; i < templen; i++) {
    PRINTF("%02x", *(uint8_t *)(payload + i));
  }
  PRINTF("\n");
#endif  /* DEBUG_PRINTDATA */
   
  PRINTF("RF233: prepare %u\n", payload_len);
  if(payload_len > MAX_PACKET_LEN) {
    PRINTF("RF233: error, frame too large to tx\n");
    return RADIO_TX_ERR;
  }

  /* check that the FIFO is clear to access */
  radio_status = rf233_status();
  if (radio_status == STATE_BUSY_RX_AACK ||
      radio_status == STATE_BUSY_RX || 
      radio_status == STATE_BUSY_TX_ARET) {
    PRINTF("RF233: TRX buffer unavailable: prep when state %s\n", state_str(radio_status));
    return RADIO_TX_ERR;
  }

  /* Write packet to TX FIFO. */
  PRINTF("RF233: sqno: %02x len = %u\n", counter, payload_len);
  trx_frame_write((uint8_t *)data, templen+1);
  return RADIO_TX_OK;
}
Exemplo n.º 10
0
uint8_t wibo_run(void)
{
	uint8_t isLeave=0;
	uint8_t isStay=0;
	unsigned long timeout = WIBO_TIMEOUT;
	
	while(!isLeave) {
#if !defined(NO_LEDS)
		LED_CLR(PROGLED);
#endif
		if (!(isStay))
		{
			while(!(wibo_available()) && (timeout--))  _delay_ms(1);	// minimum frame time @ 250kbps ~ 2ms.
		
			if (!(wibo_available()))	// no packets received, bye bye!
			{
				isLeave=1;
				return isLeave;
			}			
		}
		else
		{
			while(!(wibo_available()));	// wait for next packet
		}

		trx_reg_write(RG_IRQ_STATUS, TRX_IRQ_RX_END); /* clear the flag */

		trx_frame_read(rxbuf.data, sizeof(rxbuf.data) / sizeof(rxbuf.data[0]),
				&tmp); /* dont use LQI, write into tmp variable */

#if !defined(NO_LEDS)
		LED_SET(PROGLED);
		/* light as long as actions are running */
#endif

		switch (rxbuf.hdr.cmd)
		{

		case P2P_PING_REQ:
			isStay=1;
			if (0 == deaf)
			{
				pingrep.hdr.dst = rxbuf.hdr.src;
				pingrep.hdr.seq++;
				pingrep.crc = datacrc;

				trx_reg_write(RG_TRX_STATE, CMD_TX_ARET_ON);

				/* no need to make block atomic since no IRQs are used */
				TRX_SLPTR_HIGH()
				;
				TRX_SLPTR_LOW()
				;
				trx_frame_write(sizeof(p2p_ping_cnf_t) + sizeof(BOARD_NAME) + 2,
						(uint8_t*) &pingrep);
				/*******************************************************/

#if defined(_DEBUG_SERIAL_)
				printf("Pinged by 0x%04X"EOL, rxbuf.hdr.src);
#endif

#if defined(TRX_IF_RFA1)
				while (!(trx_reg_read(RG_IRQ_STATUS) & TRX_IRQ_TX_END))
					;
				trx_reg_write(RG_IRQ_STATUS, TRX_IRQ_TX_END); /* clear the flag */
#else
				while (!(trx_reg_read(RG_IRQ_STATUS) & TRX_IRQ_TRX_END))
				;
#endif /* defined(TRX_IF_RFA1) */
				trx_reg_write(RG_TRX_STATE, CMD_RX_AACK_ON);
			} /* (0 == deaf) */
			break;

		case P2P_WIBO_TARGET:
			isStay=1;
			target = rxbuf.wibo_target.targmem;
#if defined(_DEBUG_SERIAL_)
			printf("Set Target to %c"EOL, target);
#endif
			break;

		case P2P_WIBO_RESET:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Reset"EOL);
#endif

			addr = SPM_PAGESIZE; /* misuse as counter */
			ptr = pagebuf;
			do
			{
				*ptr++ = 0xFF;
			} while (--addr);

			addr = 0;
			datacrc = 0;
			pagebufidx = 0;
			deaf = 0;
			break;

		case P2P_WIBO_ADDR:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Set address: 0x%08lX"EOL, rxbuf.wibo_addr.address);
#endif
			addr = rxbuf.wibo_addr.address;
			pagebufidx = 0;
			break;

		case P2P_WIBO_DATA:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Data[%d]", rxbuf.wibo_data.dsize);
			uint8_t len = rxbuf.wibo_data.dsize;
			if (len > 10) len = 10;
			for(uint8_t j=0;j<len;j++)
			{
				printf(" %02X", rxbuf.wibo_data.data[j]);
			}
			if (len != rxbuf.wibo_data.dsize)
				printf("...");
			printf(EOL);
#endif
			tmp = rxbuf.wibo_data.dsize;
			ptr = rxbuf.wibo_data.data;
			do
			{
				datacrc = _crc_ccitt_update(datacrc, *ptr);
				pagebuf[pagebufidx++] = *ptr;
				if (pagebufidx >= PAGEBUFSIZE)
				{
					/* LED off to save current and avoid flash corruption
					 *  because of possible voltage drops
					 */
#if !defined(NO_LEDS)
					LED_CLR(PROGLED);
#endif

					if (target == 'F') /* Flash memory */
					{
						boot_program_page(addr, pagebuf);
					}
					else if (target == 'E')
					{
						/* not implemented */
					}
					else
					{
						/* unknown target, dry run */
					}

					/* also for dry run! */
					addr += SPM_PAGESIZE;
					pagebufidx = 0;
				}
				ptr++;
			} while (--tmp);
			break;
#if defined(WIBO_FLAVOUR_BOOTLUP)
		case P2P_WIBO_BOOTLUP:
			isStay=1;
			bootlup();
		break;
#endif

		case P2P_WIBO_FINISH:
			isStay=1;
#if defined(_DEBUG_SERIAL_)
			printf("Finish"EOL);
#endif
			if (target == 'F') /* Flash memory */
			{
				boot_program_page(addr, pagebuf);
			}
			else if (target == 'E')
			{
				/* not implemented */
			}
			else
			{
				/* unknown target, dry run */
			}

			/* also for dry run! */
			addr += SPM_PAGESIZE;
			pagebufidx = 0;

			break;

		case P2P_WIBO_EXIT:
#if defined(_DEBUG_SERIAL_)
			printf("Exit"EOL);
#endif
#if !defined(NO_LEDS)
			LED_CLR(PROGLED);
#endif
			isLeave=1;
			break;

		case P2P_WIBO_DEAF:
			isStay=1;
			deaf = 1;
			break;
		default:
			/* unknown or unhandled command */
			if (!(isStay)) {
				if (!(timeout--)) {
					isLeave = 1;
				}
			}
			break;
		}; /* switch (rxbuf.hdr.cmd) */
	}

	return isLeave;
}
Exemplo n.º 11
0
/*
 * \brief Sends frame
 *
 * \param use_csma Flag indicating if CSMA is requested
 * \param tx_retries Flag indicating if transmission retries are requested
 *                   by the MAC layer
 */
void send_frame(csma_mode_t csma_mode, bool tx_retries)
{
	tal_trx_status_t trx_status;

	/* Configure tx according to tx_retries */
	if (tx_retries) {
		trx_bit_write(SR_MAX_FRAME_RETRIES,
				tal_pib.MaxFrameRetries);
	} else {
		trx_bit_write(SR_MAX_FRAME_RETRIES, 0);
	}

	/* Configure tx according to csma usage */
	if ((csma_mode == NO_CSMA_NO_IFS) || (csma_mode == NO_CSMA_WITH_IFS)) {
		if (tx_retries) {
			trx_bit_write(SR_MAX_CSMA_RETRIES,
					tal_pib.MaxCSMABackoffs);
			trx_reg_write(RG_CSMA_BE, 0x00);
		} else {
			trx_bit_write(SR_MAX_CSMA_RETRIES, 7);
		}
	} else {
		trx_reg_write(RG_CSMA_BE,
				((tal_pib.MaxBE << 4) | tal_pib.MinBE));
		trx_bit_write(SR_MAX_CSMA_RETRIES, tal_pib.MaxCSMABackoffs);
	}

	do {
		trx_status = set_trx_state(CMD_TX_ARET_ON);
	} while (trx_status != TX_ARET_ON);

	/* Handle interframe spacing */
	if (csma_mode == NO_CSMA_WITH_IFS) {
		if (last_frame_length > aMaxSIFSFrameSize) {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinLIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		} else {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinSIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		}
	} else {
		/*
		 * If no delay is applied after switching to TX_ARET_ON,
		 * a short delay is required that allows that a pending TX_END
		 * IRQ for
		 * ACK transmission gets served.
		 */
		pal_timer_delay(TRX_IRQ_DELAY_US);
	}

	ENTER_CRITICAL_REGION(); /* prevent from buffer underrun */

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * - 2 octets FCS
	 */
	trx_frame_write(tal_frame_to_tx, tal_frame_to_tx[0] - 1);

	tal_state = TAL_TX_AUTO;

	LEAVE_CRITICAL_REGION();
}
Exemplo n.º 12
0
/*
 * \brief Sends frame using trx features to handle CSMA and re-transmissions
 *
 * \param use_csma Flag indicating if CSMA is requested
 * \param tx_retries Flag indicating if transmission retries are requested
 *                   by the MAC layer
 */
void send_frame(csma_mode_t csma_mode, bool tx_retries)
{
	tal_trx_status_t trx_status;

	/* Configure tx according to tx_retries */
	if (tx_retries) {
		trx_bit_write(SR_MAX_FRAME_RETRIES,
				tal_pib.MaxFrameRetries);
	} else {
		trx_bit_write(SR_MAX_FRAME_RETRIES, 0);
	}

	/* Configure tx according to csma usage */
	if ((csma_mode == NO_CSMA_NO_IFS) || (csma_mode == NO_CSMA_WITH_IFS)) {
		trx_bit_write(SR_MAX_CSMA_RETRIES, 7); /* immediate
		                                        * transmission */
	} else {
		trx_bit_write(SR_MAX_CSMA_RETRIES, tal_pib.MaxCSMABackoffs);
	}

	do {
		trx_status = set_trx_state(CMD_TX_ARET_ON);
	} while (trx_status != TX_ARET_ON);

	pal_trx_irq_dis();

	/* Handle interframe spacing */
	if (csma_mode == NO_CSMA_WITH_IFS) {
		if (last_frame_length > aMaxSIFSFrameSize) {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinLIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		} else {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinSIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		}
	}

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * - 2 octets FCS
	 */
	trx_frame_write(tal_frame_to_tx, tal_frame_to_tx[0] - 1);

	tal_state = TAL_TX_AUTO;

#ifndef NON_BLOCKING_SPI
	pal_trx_irq_en();
#endif
#ifdef TX_OCTET_COUNTER
	tal_tx_octet_cnt += PHY_OVERHEAD + LENGTH_FIELD_LEN + frame_tx[0];
#endif
}
Exemplo n.º 13
0
/**
 * \brief      prepare a frame and the radio for immediate transmission 
 * \param payload         Pointer to data to copy/send
 * \param payload_len     length of data to copy
 * \return     Returns success/fail, refer to radio.h for explanation
 */
int
rf233_prepare(const void *payload, unsigned short payload_len)
{
#if DEBUG_PRINTDATA
  int i;
#endif  /* DEBUG_PRINTDATA */
  uint8_t templen;
  uint8_t radio_status;
  uint8_t data[130];

#if USE_HW_FCS_CHECK
  /* Add length of the FCS (2 bytes) */
  templen = payload_len + 2;
#else   /* USE_HW_FCS_CHECK */
  /* FCS is assumed to already be included in the payload */
  templen = payload_len;
#endif  /* USE_HW_FCS_CHECK */
 //data = templen;
 
/*
for(i = 0; i < templen; i++) {
	data++;
	data =(uint8_t *)(payload + i);
	
}*/
//memcpy(data,&templen,1);
data[0] = templen;
memcpy(&data[1],payload,templen);
//data--;
#if DEBUG_PRINTDATA
  PRINTF("RF233 prepare (%u/%u): 0x", payload_len, templen);
  for(i = 0; i < templen; i++) {
    PRINTF("%02x", *(uint8_t *)(payload + i));
  }
  PRINTF("\r\n");
#endif  /* DEBUG_PRINTDATA */
   
  PRINTF("RF233: prepare %u\r\n", payload_len);
  if(payload_len > MAX_PACKET_LEN) {
    PRINTF("RF233: error, frame too large to tx\r\n");
    return RADIO_TX_ERR;
  }

  /* check that the FIFO is clear to access */
  radio_status=rf233_status();
  #if NULLRDC_CONF_802154_AUTOACK_HW
  if(radio_status == STATE_BUSY_RX_AACK || radio_status == STATE_BUSY_TX_ARET) {
	  PRINTF("RF233: TRX buffer unavailable: prep when %s\r\n", radio_status == STATE_BUSY_RX_AACK ? "rx" : "tx");
  #else
   if(radio_status == STATE_BUSY_RX || radio_status == STATE_BUSY_TX) {
	   PRINTF("RF233: TRX buffer unavailable: prep when %s\r\n", radio_status == STATE_BUSY_RX? "rx" : "tx");
  #endif
    
    return RADIO_TX_ERR;
  }

  /* Write packet to TX FIFO. */
  PRINTF("RF233 len = %u\r\n", payload_len);
  trx_frame_write((uint8_t *)data, templen+1);
  return RADIO_TX_OK;
}
/*---------------------------------------------------------------------------*/
/**
 * \brief      Transmit a frame already put in the radio with 'prepare'
 * \param payload_len    Length of the frame to send
 * \return     Returns success/fail, refer to radio.h for explanation
 */
int
rf233_transmit(unsigned short payload_len)
{
  static uint8_t status_now;
  PRINTF("RF233: tx %u\r\n", payload_len);

  /* prepare for TX */
  
  status_now = rf233_status();
   //status_now = trx_reg_read(RF233_REG_TRX_RPC);
  #if NULLRDC_CONF_802154_AUTOACK_HW
  if(status_now == STATE_BUSY_RX_AACK || status_now == STATE_BUSY_TX_ARET) {
  #else
  if(status_now == STATE_BUSY_RX || status_now == STATE_BUSY_TX) {
  #endif
    PRINTF("RF233: collision, was receiving 0x%02X\r\n",status_now);
    /* NOTE: to avoid loops */
    return RADIO_TX_ERR;;
    // return RADIO_TX_COLLISION;
  }
  if(status_now != STATE_PLL_ON) {
    /* prepare for going to state TX, should take max 80 us */
    //RF233_COMMAND(TRXCMD_PLL_ON);
	trx_reg_write(RF233_REG_TRX_STATE,0x09);
   // BUSYWAIT_UNTIL(trx_reg_read(RF233_REG_TRX_STATUS) == STATE_PLL_ON, 1 * RTIMER_SECOND/1000);
   //delay_ms(10);
   //status_now = trx_reg_read(RF233_REG_TRX_STATE);
   do 
   {
	   status_now = trx_bit_read(0x01, 0x1F, 0);
   } while (status_now == 0x1f);
  }

  if(rf233_status() != STATE_PLL_ON) {
    /* failed moving into PLL_ON state, gracefully try to recover */
    PRINTF("RF233: failed going to PLLON\r\n");
    RF233_COMMAND(TRXCMD_PLL_ON);   /* try again */
	static uint8_t state;
	state = rf233_status();
    if(state != STATE_PLL_ON) {
      /* give up and signal big fail (should perhaps reset radio core instead?) */
      PRINTF("RF233: graceful recovery (in tx) failed, giving up. State: 0x%02X\r\n", rf233_status());
      return RADIO_TX_ERR;
    }
  }

  /* perform transmission */
  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
#if NULLRDC_CONF_802154_AUTOACK_HW
  RF233_COMMAND(TRXCMD_TX_ARET_ON);
#endif
  RF233_COMMAND(TRXCMD_TX_START);
   flag_transmit=1;
   //delay_ms(5);
  //printf("RTIMER value %d",RTIMER_NOW());

#if !NULLRDC_CONF_802154_AUTOACK_HW
    BUSYWAIT_UNTIL(rf233_status() == STATE_BUSY_TX, RTIMER_SECOND/2000);
   // printf("RTIMER value1 %d",RTIMER_NOW());
   // printf("\r\nSTATE_BUSY_TX");
  BUSYWAIT_UNTIL(rf233_status() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  // printf("RTIMER value2 %d",RTIMER_NOW());
#endif

  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
  ENERGEST_ON(ENERGEST_TYPE_LISTEN);

#if !NULLRDC_CONF_802154_AUTOACK_HW
   if(rf233_status() != STATE_PLL_ON) {
    // something has failed 
    PRINTF("RF233: radio fatal err after tx\r\n");
    radiocore_hard_recovery();
    return RADIO_TX_ERR;
  }
  RF233_COMMAND(TRXCMD_RX_ON);
#else
	BUSYWAIT_UNTIL(ack_status == 1, 10 * RTIMER_SECOND/1000);
	if((ack_status))
	{
	//	printf("\r\nrf233 sent\r\n ");
		ack_status=0;
	//	printf("\nACK received");
		return RADIO_TX_OK;
	}
	else
	{
	//	printf("\nNOACK received");		
		return RADIO_TX_NOACK;
	}
	
#endif

  PRINTF("RF233: tx ok\r\n");
  return RADIO_TX_OK;
}
/*---------------------------------------------------------------------------*/
/**
 * \brief      Send data: first prepares, then transmits
 * \param payload         Pointer to data to copy/send
 * \param payload_len     length of data to copy
 * \return     Returns success/fail, refer to radio.h for explanation
 */
int
rf233_send(const void *payload, unsigned short payload_len)
{
  PRINTF("RF233: send %u\r\n", payload_len);
  if(rf233_prepare(payload, payload_len) == RADIO_TX_ERR) {
  return RADIO_TX_ERR;
  } 
  return rf233_transmit(payload_len);
}
/*---------------------------------------------------------------------------*/
/**
 * \brief      read a received frame out of the radio buffer 
 * \param buf         pointer to where to copy received data
 * \param bufsize     Maximum size we can copy into bufsize
 * \return     Returns length of data read (> 0) if successful
 * \retval -1  Failed, was transmitting so FIFO is invalid
 * \retval -2  Failed, rx timed out (stuck in rx?)
 * \retval -3  Failed, too large frame for buffer
 * \retval -4  Failed, CRC/FCS failed (if USE_HW_FCS_CHECK is true)
 */
int
rf233_read(void *buf, unsigned short bufsize)
{
//  uint8_t radio_state;
  uint8_t ed;       /* frame metadata */
  uint8_t frame_len = 0;
  uint8_t len = 0;
  int rssi;
#if DEBUG_PRINTDATA
  uint8_t tempreadlen;
#endif  /* DEBUG_PRINTDATA */

  if(pending_frame == 0) {
    return 0;
  }
  pending_frame = 0;

 /* / * check that data in FIFO is valid * /
  radio_state = RF233_STATUS();
  if(radio_state == STATE_BUSY_TX) {
    / * data is invalid, bail out * /
    PRINTF("RF233: read while in BUSY_TX ie invalid, dropping.\n");
    return -1;
  }
  if(radio_state == STATE_BUSY_RX) {
    / * still receiving - data is invalid, wait for it to finish * /
    PRINTF("RF233: read while BUSY_RX, waiting.\n");
    BUSYWAIT_UNTIL(RF233_STATUS() != STATE_BUSY_RX, 10 * RTIMER_SECOND/1000);
	if(RF233_STATUS() == STATE_BUSY_RX) {
      PRINTF("RF233: timed out, still BUSY_RX, dropping.\n");
      return -2;
    }
  }
*/

  /* get length of data in FIFO */
  trx_frame_read(&frame_len, 1);
#if DEBUG_PRINTDATA
  tempreadlen = frame_len;
#endif  /* DEBUG_PRINTDATA */
  if(frame_len == 1) {
    frame_len = 0;
  }

  len = frame_len;
#if USE_HW_FCS_CHECK
  /* FCS has already been stripped */
  len = frame_len - 2;
#endif  /* USE_HW_FCS_CHECK */

  if(frame_len == 0) {
    return 0;
  }
  if(len > bufsize) {
    /* too large frame for the buffer, drop */
    PRINTF("RF233: too large frame for buffer, dropping (%u > %u).\r\n", frame_len, bufsize);
    flush_buffer();
    return -3;
  }
  PRINTF("RF233 read %u B\r\n", frame_len);

  /* read out the data into the buffer, disregarding the length and metadata bytes */
  trx_sram_read(1,(uint8_t *)buf, len);
#if DEBUG_PRINTDATA
  {
    int k;
    PRINTF("RF233: Read frame (%u/%u): ", tempreadlen, frame_len);
    for(k = 0; k < frame_len; k++) {
      PRINTF("%02x", *((uint8_t *)buf + k));
    }
    PRINTF("\r\n");
  }
#endif  /* DEBUG_PRINTDATA */

  /* 
   * Energy level during reception, ranges from 0x00 to 0x53 (=83d) with a
   * resolution of 1dB and accuracy of +/- 5dB. 0xFF means invalid measurement.
   * 0x00 means <= RSSI(base_val), which is -91dBm (typ). See datasheet 12.7.
   * Ergo, real RSSI is (ed-91) dBm or less.
   */
  #define RSSI_OFFSET       (91)
  ed = trx_reg_read(RF233_REG_PHY_ED_LEVEL);
  rssi = (int) ed - RSSI_OFFSET;
  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
  flush_buffer();

/*
#if USE_HW_FCS_CHECK
  {
    uint8_t crc_ok;   / * frame metadata * /
    crc_ok = rf233_arch_read_reg(RF233_REG_PHY_RSSI) & PHY_RSSI_CRC_VALID;
    if(crc_ok == 0) {
      / * CRC/FCS fail, drop * /
      PRINTF("RF233: CRC/FCS fail, dropping.\n");
      flush_buffer();
      return -4;
    }
  }
#endif  / * USE_HW_FCS_CHECK * /*/

  return len;
}
Exemplo n.º 14
0
/**
 * \brief      prepare a frame and the radio for immediate transmission 
 * \param payload         Pointer to data to copy/send
 * \param payload_len     length of data to copy
 * \return     Returns success/fail, refer to radio.h for explanation
 */
static int
rf212_prepare(const void *payload, unsigned short payload_len)
{
#if DEBUG_PRINTDATA
  int i;
#endif  /* DEBUG_PRINTDATA */
  uint8_t templen;
  uint8_t radio_status;
  uint8_t data[130];

#if USE_HW_FCS_CHECK
  /* Add length of the FCS (2 bytes) */
  templen = payload_len + 2;
#else   /* USE_HW_FCS_CHECK */
  /* FCS is assumed to already be included in the payload */
  templen = payload_len;
#endif  /* USE_HW_FCS_CHECK */
data[0] = templen;
memcpy(&data[1],payload,templen);
#if DEBUG_PRINTDATA
  PRINTF("RF212 prepare (%u/%u): 0x", payload_len, templen);
  for(i = 0; i < templen; i++) {
    PRINTF("%02x", *(uint8_t *)(payload + i));
  }
  PRINTF("\n");
#endif  /* DEBUG_PRINTDATA */

  PRINTF("RF212: prepare %u\n", payload_len);
  if(payload_len > MAX_PACKET_LEN) {
    PRINTF("RF212: error, frame too large to tx\n");
    return RADIO_TX_ERR;
  }

  /* check that the FIFO is clear to access */
  radio_status = rf212_status();
  #if NULLRDC_CONF_802154_AUTOACK_HW
  if(radio_status == STATE_BUSY_RX_AACK || radio_status == STATE_BUSY_TX_ARET) {
	  PRINTF("RF212B: TRX buffer unavailable: prep when %s\n", radio_status == STATE_BUSY_RX_AACK ? "rx" : "tx");
  #else
   if(radio_status == STATE_BUSY_RX || radio_status == STATE_BUSY_TX) {
	   PRINTF("RF212B: TRX buffer unavailable: prep when %s\n", radio_status == STATE_BUSY_RX? "rx" : "tx");
  #endif
    return RADIO_TX_ERR;
  }

  /* Write packet to TX FIFO. */
  PRINTF("RF212 len = %u\n", payload_len);
  trx_frame_write((uint8_t *)data, templen+1);
  return RADIO_TX_OK;
}
/*---------------------------------------------------------------------------*/
/**
 * \brief      Transmit a frame already put in the radio with 'prepare'
 * \param payload_len    Length of the frame to send
 * \return     Returns success/fail, refer to radio.h for explanation
 */
static int
rf212_transmit(unsigned short payload_len)
{
  uint8_t status_now;//,temp;
  PRINTF("RF212: tx %u\n", payload_len);

  /* prepare for TX */
  status_now = rf212_status();
  #if NULLRDC_CONF_802154_AUTOACK_HW
  if(status_now == STATE_BUSY_RX_AACK || status_now == STATE_BUSY_TX_ARET) {
  #else
  if(status_now == STATE_BUSY_RX || status_now == STATE_BUSY_TX) {
  #endif
    PRINTF("RF212: collision, was receiving\n");
    /* NOTE: to avoid loops */
    return RADIO_TX_ERR;
    // return RADIO_TX_COLLISION;
  }
  if(status_now != STATE_PLL_ON) {
    /* prepare for going to state TX, should take max 80 us */
    //RF212_COMMAND(TRXCMD_PLL_ON);
	trx_reg_write(RF212_REG_TRX_STATE,0x09);
	do 
   {
	   status_now = trx_bit_read(0x01, 0x1F, 0);
   } while (status_now == 0x1f);
    //BUSYWAIT_UNTIL(RF212_STATUS() == STATE_PLL_ON, 1 * RTIMER_SECOND/1000);
  }

  if(rf212_status() != STATE_PLL_ON) {
    /* failed moving into PLL_ON state, gracefully try to recover */
    PRINTF("RF212: failed going to PLLON\n");
    RF212_COMMAND(TRXCMD_PLL_ON);   /* try again */
    if(rf212_status() != STATE_PLL_ON) {
      /* give up and signal big fail (should perhaps reset radio core instead?) */
      PRINTF("RF212: graceful recovery (in tx) failed, giving up. State: 0x%02X\n", RF212_STATUS());
      return RADIO_TX_ERR;
    }
  }

  /* perform transmission */
  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
#if NULLRDC_CONF_802154_AUTOACK_HW
  RF212_COMMAND(TRXCMD_TX_ARET_ON);
#endif  
  RF212_COMMAND(TRXCMD_TX_START);
  flag_transmit=1;

#if !NULLRDC_CONF_802154_AUTOACK_HW  
  BUSYWAIT_UNTIL(RF212_STATUS() == STATE_BUSY_TX, RTIMER_SECOND/2000);
  BUSYWAIT_UNTIL(RF212_STATUS() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  #if (DATA_RATE==BPSK_20||BPSK_40||OQPSK_SIN_RC_100)
  BUSYWAIT_UNTIL(RF212_STATUS() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  BUSYWAIT_UNTIL(RF212_STATUS() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  BUSYWAIT_UNTIL(RF212_STATUS() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  #endif
#endif  
  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
#if !NULLRDC_CONF_802154_AUTOACK_HW  
  if(RF212_STATUS() != STATE_PLL_ON) {
    /* something has failed */
    printf("RF212: radio fatal err after tx\n");
    radiocore_hard_recovery();
	return RADIO_TX_ERR;
  }
 // printf("#RTIMER_SECOND");
  RF212_COMMAND(TRXCMD_RX_ON);
#else
	BUSYWAIT_UNTIL(ack_status == 1, 10 * RTIMER_SECOND/1000);
	if((ack_status))
	{
	//	printf("\r\nrf233 sent\r\n ");
		ack_status=0;
	//	printf("\nACK received");
		return RADIO_TX_OK;
	}
	else
	{
	//	printf("\nNOACK received");		
		return RADIO_TX_NOACK;
	}
	
#endif  

 PRINTF("RF212: tx ok\n");
  return RADIO_TX_OK;
}
void
goto_sleep(void)
{
	port_pin_set_output_level(AT86RFX_SLP_PIN, true);
}
Exemplo n.º 15
0
/*
 * \brief Starts continuous transmission on current channel
 *
 * \param tx_mode Mode of continuous transmission (CW or PRBS)
 * \param random_content Use random content if true
 *
 * The comment 'step #' refers to the step mentioned in the RF212's datasheet.
 */
void tfa_continuous_tx_start(continuous_tx_mode_t tx_mode, bool random_content)
{
	uint8_t txcwdata[128];
	uint8_t i;

	/* step 3,6: Channel is assumed to be set before */
	trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);
	/* step 7: Enable continuous transmission - step #1 */
	trx_reg_write(0x36, 0x0F);
	if (tx_mode == CW_MODE) {
		/* step 8: Register access: CW at Fc +/- 0.1 MHz */
		if (((tal_pib.CurrentPage == 0) || (tal_pib.CurrentPage == 2) || \
				(tal_pib.CurrentPage == 16) ||
				(tal_pib.CurrentPage == 17)) &&
				(tal_pib.CurrentChannel == 0)) {                                          /*
			                                                                                   *
			                                                                                   *868.3MHz
			                                                                                   **/
			trx_reg_write(RG_TRX_CTRL_2, 0x0A); /* 400 kchip/s
			                                     * mode, step 8
			                                     * ,SUB_MODE = 0 */
		} else {
			trx_reg_write(RG_TRX_CTRL_2, 0x0E); /* 1000kchip/s
			                                     * ,SUB_MODE = 1 */
		}

		txcwdata[0] = 1; /* length */
		txcwdata[1] = 0;
		/* step 9: Frame buffer access */
		trx_frame_write(txcwdata, 2);
	} else { /* PRBS mode */
		 /* step 8: */

		/*
		 * Step 8 is not explicitly written here, because the proper
		 * value is set during reset or by updating the Channel Page.
		 * After finishing CW/PRBS another reset is performed with
		 * parameter set_default_pib set to false, which restores the
		 * original value based on the current Channel Page.
		 *
		 * I.e., in order to use PRBS with a specific data rate,
		 * the Channel Page needs to be udpated before starting PRBS.
		 */

		txcwdata[0] = 127; /* = max length */
		for (i = 1; i < 128; i++) {
			if (random_content) {
				txcwdata[i] = (uint8_t)rand();
			} else {
				txcwdata[i] = 0;
			}
		}
		/* step 9: Frame buffer access */
		trx_frame_write(txcwdata, 128);
	}

	/* step 10: Enable continuous transmission - step #2 */
	trx_reg_write(RG_PART_NUM, 0x54);
	/* step 11: Enable continuous transmission - step #3 */
	trx_reg_write(RG_PART_NUM, 0x46);
	/* step 12, 13: Stwitch PLL on */
	set_trx_state(CMD_PLL_ON);
	/* step 14: Initiate transmission using SLP_TR line */
	TRX_SLP_TR_HIGH();
	TRX_SLP_TR_LOW();
}