/** * \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\n", payload_len); if (rf233_prepare(payload, payload_len) != RADIO_TX_OK) { return RADIO_TX_ERR; } return rf233_transmit(); }
/** * \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; }