/** \brief This function writes a new value to one of the radio transceiver's * registers. * * \see Look at the at86rf230_registermap.h file for register address definitions. * * \param address Address of register to write. * \param value Value to write. */ void hal_register_write(uint8_t address, uint8_t value) { /* Add the Register Write (short mode) command to the address. */ address = 0xc0 | address; HAL_SPI_TRANSFER_OPEN(); /*Send Register address and write register content.*/ HAL_SPI_TRANSFER(address); HAL_SPI_TRANSFER(value); HAL_SPI_TRANSFER_CLOSE(); }
/** \brief This function will download a frame to the radio transceiver's frame * buffer. * * \param write_buffer Pointer to data that is to be written to frame buffer. * \param length Length of data. The maximum length is 127 bytes. */ void hal_frame_write(uint8_t *write_buffer, uint8_t length) { #if defined(__AVR_ATmega128RFA1__) uint8_t *tx_buffer; tx_buffer=(uint8_t *)0x180; //start of fifo in i/o space /* Write frame length, including the two byte checksum */ /* The top bit of the length field shall be set to 0 for IEEE 802.15.4 compliant frames */ /* It should already be clear, so bypassing the masking is sanity check of the uip stack */ // length &= 0x7f; _SFR_MEM8(tx_buffer++) = length; /* Download to the Frame Buffer. * When the FCS is autogenerated there is no need to transfer the last two bytes * since they will be overwritten. */ #if !RF230_CONF_CHECKSUM length -= 2; #endif do _SFR_MEM8(tx_buffer++)= *write_buffer++; while (--length); #else /* defined(__AVR_ATmega128RFA1__) */ /* Optionally truncate length to maximum frame length. * Not doing this is a fast way to know when the application needs fixing! */ // length &= 0x7f; HAL_SPI_TRANSFER_OPEN(); /* Send Frame Transmit (long mode) command and frame length */ HAL_SPI_TRANSFER(0x60); HAL_SPI_TRANSFER(length); /* Download to the Frame Buffer. * When the FCS is autogenerated there is no need to transfer the last two bytes * since they will be overwritten. */ #if !RF230_CONF_CHECKSUM length -= 2; #endif do HAL_SPI_TRANSFER(*write_buffer++); while (--length); HAL_SPI_TRANSFER_CLOSE(); #endif /* defined(__AVR_ATmega128RFA1__) */ }
/** \brief This function reads data from one of the radio transceiver's registers. * * \param address Register address to read from. See datasheet for register * map. * * \see Look at the at86rf230_registermap.h file for register address definitions. * * \returns The actual value of the read register. */ uint8_t hal_register_read(uint8_t address) { uint8_t register_value; /* Add the register read command to the register address. */ /* Address should be < 0x2f so no need to mask */ // address &= 0x3f; address |= 0x80; HAL_SPI_TRANSFER_OPEN(); /*Send Register address and read register content.*/ HAL_SPI_TRANSFER(address); register_value = HAL_SPI_TRANSFER(0); HAL_SPI_TRANSFER_CLOSE(); return register_value; }
/** \brief Write SRAM * * This function writes into the SRAM of the radio transceiver. It can reduce * SPI transfers if only part of a frame is to be changed before retransmission. * * \param address Address in the TRX's SRAM where the write burst should start * \param length Length of the write burst * \param data Pointer to an array of bytes that should be written */ void hal_sram_write(uint8_t address, uint8_t length, uint8_t *data) { HAL_SPI_TRANSFER_OPEN(); /*Send SRAM write command.*/ HAL_SPI_TRANSFER(0x40); /*Send address where to start writing to.*/ HAL_SPI_TRANSFER(address); /*Upload the chosen memory area.*/ do{ HAL_SPI_TRANSFER(*data++); } while (--length > 0); HAL_SPI_TRANSFER_CLOSE(); }
void hal_sram_read(uint8_t address, uint8_t length, uint8_t *data) { HAL_SPI_TRANSFER_OPEN(); /*Send SRAM read command and address to start*/ HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER(address); HAL_SPI_TRANSFER_WRITE(0); HAL_SPI_TRANSFER_WAIT(); /*Upload the chosen memory area.*/ do{ *data++ = HAL_SPI_TRANSFER_READ(); HAL_SPI_TRANSFER_WRITE(0); HAL_SPI_TRANSFER_WAIT(); } while (--length > 0); HAL_SPI_TRANSFER_CLOSE(); }
/** \brief This function will upload a frame from the radio transceiver's frame * buffer. * * If the frame currently available in the radio transceiver's frame buffer * is out of the defined bounds. Then the frame length, lqi value and crc * be set to zero. This is done to indicate an error. * This version is optimized for use with contiki RF230BB driver. * The callback routine and CRC are left out for speed in reading the rx buffer. * Any delays here can lead to overwrites by the next packet! * * \param rx_frame Pointer to the data structure where the frame is stored. * \param rx_callback Pointer to callback function for receiving one byte at a time. */ void //hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback) hal_frame_read(hal_rx_frame_t *rx_frame) { #if defined(__AVR_ATmega128RFA1__) uint8_t frame_length,*rx_data,*rx_buffer; rx_data = (rx_frame->data); frame_length = TST_RX_LENGTH; //frame length, not including lqi? rx_frame->length = frame_length; rx_buffer=(uint8_t *)0x180; //start of fifo in i/o space do{ *rx_data++ = _SFR_MEM8(rx_buffer++); } while (--frame_length > 0); /*Read LQI value for this frame.*/ rx_frame->lqi = *rx_buffer; if (1) { #else /* defined(__AVR_ATmega128RFA1__) */ uint8_t *rx_data; /* check that we have either valid frame pointer or callback pointer */ // if (!rx_frame && !rx_callback) // return; HAL_SPI_TRANSFER_OPEN(); /*Send frame read (long mode) command.*/ HAL_SPI_TRANSFER(0x20); /*Read frame length. This includes the checksum. */ uint8_t frame_length = HAL_SPI_TRANSFER(0); /*Check for correct frame length.*/ // if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)){ if (1) { // uint16_t crc = 0; // if (rx_frame){ rx_data = (rx_frame->data); rx_frame->length = frame_length; // } else { // rx_callback(frame_length); // } /*Upload frame buffer to data pointer */ HAL_SPI_TRANSFER_WRITE(0); HAL_SPI_TRANSFER_WAIT(); do{ *rx_data++ = HAL_SPI_TRANSFER_READ(); HAL_SPI_TRANSFER_WRITE(0); // if (rx_frame){ // *rx_data++ = tempData; // } else { // rx_callback(tempData); // } /* RF230 does crc in hardware, doing the checksum here ensures the rx buffer has not been overwritten by the next packet */ /* Since doing the checksum makes such overwrites more probable, we skip it and hope for the best. */ /* A full buffer should be read in 320us at 2x spi clocking, so with a low interrupt latency overwrites should not occur */ // crc = _crc_ccitt_update(crc, tempData); HAL_SPI_TRANSFER_WAIT(); } while (--frame_length > 0); /*Read LQI value for this frame.*/ // if (rx_frame){ rx_frame->lqi = HAL_SPI_TRANSFER_READ(); // } else { // rx_callback(HAL_SPI_TRANSFER_READ()); // } #endif /* defined(__AVR_ATmega128RFA1__) */ /*Check calculated crc, and set crc field in hal_rx_frame_t accordingly.*/ // if (rx_frame){ rx_frame->crc = 1; // } else { // rx_callback(crc != 0); // } } else { // if (rx_frame){ rx_frame->length = 0; rx_frame->lqi = 0; rx_frame->crc = false; // } } HAL_SPI_TRANSFER_CLOSE(); } /*----------------------------------------------------------------------------*/ /** \brief This function will download a frame to the radio transceiver's frame * buffer. * * \param write_buffer Pointer to data that is to be written to frame buffer. * \param length Length of data. The maximum length is 127 bytes. */ void hal_frame_write(uint8_t *write_buffer, uint8_t length) { #if defined(__AVR_ATmega128RFA1__) uint8_t *tx_buffer; tx_buffer=(uint8_t *)0x180; //start of fifo in i/o space /* Write frame length, including the two byte checksum */ /* The top bit of the length field shall be set to 0 for IEEE 802.15.4 compliant frames */ /* It should already be clear, so bypassing the masking is sanity check of the uip stack */ // length &= 0x7f; _SFR_MEM8(tx_buffer++) = length; /* Download to the Frame Buffer. * When the FCS is autogenerated there is no need to transfer the last two bytes * since they will be overwritten. */ #if !RF230_CONF_CHECKSUM length -= 2; #endif do _SFR_MEM8(tx_buffer++)= *write_buffer++; while (--length); #else /* defined(__AVR_ATmega128RFA1__) */ /* Optionally truncate length to maximum frame length. * Not doing this is a fast way to know when the application needs fixing! */ // length &= 0x7f; HAL_SPI_TRANSFER_OPEN(); /* Send Frame Transmit (long mode) command and frame length */ HAL_SPI_TRANSFER(0x60); HAL_SPI_TRANSFER(length); /* Download to the Frame Buffer. * When the FCS is autogenerated there is no need to transfer the last two bytes * since they will be overwritten. */ #if !RF230_CONF_CHECKSUM length -= 2; #endif do HAL_SPI_TRANSFER(*write_buffer++); while (--length); HAL_SPI_TRANSFER_CLOSE(); #endif /* defined(__AVR_ATmega128RFA1__) */ }
int run_tests(void) { uint8_t i,j; uint8_t failed = 0; uwb_fsm = UWB_STATE_IN_TEST; HAL_DISABLE_IRQ0( ); HAL_DISABLE_IRQ1( ); /* Do full uwb-phy Reset */ HAL_ASSERT_RST(); delay_us(2); HAL_DEASSERT_RST(); delay_us(2); PRINTF("uwb: SPI pattern test ...\r\n"); i=0; ram_tx_buffer[i++] = 0x00; /* skipped */ ram_tx_buffer[i++] = 0xFF; ram_tx_buffer[i++] = 0xCC; ram_tx_buffer[i++] = 0x33; ram_tx_buffer[i++] = 0xAA; ram_tx_buffer[i++] = 0x55; ram_tx_buffer[i++] = 0x0F; ram_tx_buffer[i++] = 0xF0; ram_tx_buffer[i++] = 0x00; /* skipped */ HAL_SPI_TRANSFER_OPEN(); HAL_SPI_TRANSFER(CMD_SPI_LOOPBACK); /* loop-back cmd */ for (j=0;j<(i-1);j++) { ram_rx_buffer[j] = HAL_SPI_TRANSFER(ram_tx_buffer[j+1]); if (ram_rx_buffer[j] != ram_tx_buffer[j]) { PRINTF("uwb: Pattern 0x%02x FAILED - was 0x%02x\r\n", ram_tx_buffer[j], ram_rx_buffer[j]); failed++; break; } } HAL_SPI_TRANSFER_CLOSE(); if (failed == 0) PRINTF("uwb: ... PASSED\r\n"); delay_us(10000); /* Do full uwb-phy Reset */ HAL_ASSERT_RST(); delay_us(2); HAL_DEASSERT_RST(); delay_us(2); PRINTF("uwb: SPI RAM_TX test with DMA ...\r\n"); i=0; ram_tx_buffer[i++] = CMD_WRITE_RAM_TX; ram_tx_buffer[i++] = 127; for (j=0;j<ram_tx_buffer[1];j++) ram_tx_buffer[i++] = j; ram_tx_buffer[i++] = 0x00; /* additional zero required by PHY ??? */ PRINTF("uwb: starting dma write ... "); hal_spi_dma_transfer(ram_tx_buffer, NULL, ram_tx_buffer[1]+3); while (hal_spi_dma_busy()) {;} PRINTF("done\r\n"); delay_us(10); PRINTF("uwb: starting dma read ... "); ram_tx_buffer[0] = CMD_READ_RAM_TX; hal_spi_dma_transfer(ram_tx_buffer, ram_rx_buffer, ram_tx_buffer[1]+3); while (hal_spi_dma_busy()) {;} PRINTF("done\r\n"); if (memcmp(&ram_tx_buffer[1],&ram_rx_buffer[2],ram_tx_buffer[1]+1) == 0) PRINTF("uwb: ... PASSED\r\n"); else { PRINTF("uwb: ... buffers DIFFER - FAILED\r\n"); failed++; } delay_us(10000); /* Do full uwb-phy Reset */ HAL_ASSERT_RST(); delay_us(2); HAL_DEASSERT_RST(); delay_us(2); PRINTF("uwb: SPI RAM_RX test with DMA ...\r\n"); i=0; ram_tx_buffer[i++] = CMD_WRITE_RAM_RX; ram_tx_buffer[i++] = 127; for (j=0;j<ram_tx_buffer[1];j++) ram_tx_buffer[i++] = j; ram_tx_buffer[i++] = 0x00; /* additional zero required by PHY ??? */ PRINTF("uwb: starting dma write ... "); hal_spi_dma_transfer(ram_tx_buffer, NULL, ram_tx_buffer[1]+3); while (hal_spi_dma_busy()) {;} PRINTF("done\r\n"); delay_us(10); PRINTF("uwb: starting dma read ... "); ram_tx_buffer[0] = CMD_READ_RAM_RX; hal_spi_dma_transfer(ram_tx_buffer, ram_rx_buffer, ram_tx_buffer[1]+3); while (hal_spi_dma_busy()) {;} PRINTF("done\r\n"); if (memcmp(&ram_tx_buffer[1],&ram_rx_buffer[2],ram_tx_buffer[1]+1) == 0) PRINTF("uwb: ... PASSED\r\n"); else { PRINTF("uwb: ... buffers DIFFER - FAILED\r\n"); failed++; } delay_us(10000); /* Do full uwb-phy Reset */ HAL_ASSERT_RST(); delay_us(2); HAL_DEASSERT_RST(); delay_us(2); /* we need to cycle IRQs here to make sure that there are none pending - as we later check for ints! */ /* do NOT remove unless you know what you are doing!!! */ HAL_ENABLE_IRQ0(); HAL_ENABLE_IRQ1(); HAL_DISABLE_IRQ0(); HAL_DISABLE_IRQ1(); PRINTF("uwb: Internal loopback test with interrupts...\r\n"); i=0; ram_tx_buffer[i++] = CMD_WRITE_RAM_TX; ram_tx_buffer[i++] = 96; for (j=0;j<ram_tx_buffer[1];j++) ram_tx_buffer[i++] = ~j; ram_tx_buffer[i++] = 0x00; /* additional zero required by PHY ??? */ // PRINTF("uwb: starting dma write ... "); hal_spi_dma_transfer(ram_tx_buffer, NULL, ram_tx_buffer[1]+3); while (hal_spi_dma_busy()) {;} // PRINTF("done\r\n"); delay_us(2); HAL_SPI_TRANSFER_OPEN(); HAL_SPI_TRANSFER(CMD_CONFIG_MODE); /* config mode cmd */ HAL_SPI_TRANSFER(0x09); // oder 0x0A HAL_SPI_TRANSFER(0xFF); /* all off */ // für external test: 0x00 HAL_SPI_TRANSFER(0x00); // für external 0x10-0x13 HAL_SPI_TRANSFER(0xEF); // (MODULE_TX_RS | MODULE_TX | MODULE_RX_RS | MODULE_RX | MODULE_LOOPBACK); HAL_SPI_TRANSFER(0x11); /* Preamble length... */ HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER_CLOSE(); /* wait for ints */ PRINTF("uwb: waiting for tx-interrupt ... "); /* encoding time depends on frame length - so make it length-dependend */ for (i=0;i<ram_tx_buffer[1];i++) { if (HAL_CHECK_IRQ1()) break; delay_us(12); } if (i < 100) PRINTF("ok\r\n"); else { PRINTF("FAILED\r\n"); failed++; } /* wait for ints */ PRINTF("uwb: waiting for rx-interrupt ... "); for (i=0;i<50;i++) { if (HAL_CHECK_IRQ0()) break; delay_us(5); } if (i < 50) PRINTF("ok\r\n"); else { PRINTF("FAILED\r\n"); failed++; } /* read frame */ // PRINTF("uwb: starting frame download ... "); HAL_SS_LOW(); HAL_SPI_TRANSFER(CMD_READ_RAM_RX); HAL_SPI_TRANSFER(0x00); i = HAL_SPI_TRANSFER(0x00); if (i>0) { hal_spi_dma_transfer(NULL, ram_rx_buffer, i); while (hal_spi_dma_busy()) {;} } HAL_SS_HIGH(); // PRINTF("done\r\n"); /* do reset to release IRQs */ HAL_ASSERT_RST(); delay_us(2); HAL_DEASSERT_RST(); delay_us(2); if ((i == ram_tx_buffer[1]) && (memcmp(&ram_tx_buffer[2],ram_rx_buffer,i) == 0)) PRINTF("uwb: ... PASSED\r\n"); else { if (i != ram_tx_buffer[1]) PRINTF("uwb: ... length is %u, expected %u - FAILED\r\n", i, ram_tx_buffer[1]); else PRINTF("uwb: ... buffers differ - FAILED\r\n"); failed++; } delay_us(10000); /* Do full uwb-phy Reset */ HAL_ASSERT_RST(); delay_us(2); HAL_DEASSERT_RST(); delay_us(2); /* we need to cycle IRQs here to make sure that there are none pending - as we later check for ints! */ /* do NOT remove unless you know what you are doing!!! */ HAL_ENABLE_IRQ0(); HAL_ENABLE_IRQ1(); HAL_DISABLE_IRQ0(); HAL_DISABLE_IRQ1(); PRINTF("uwb: External loopback test with interrupts...\r\n"); i=0; ram_tx_buffer[i++] = CMD_WRITE_RAM_TX; ram_tx_buffer[i++] = 96; for (j=0;j<ram_tx_buffer[1];j++) ram_tx_buffer[i++] = j; ram_tx_buffer[i++] = 0x00; /* additional zero required by PHY ??? */ // PRINTF("uwb: starting dma write ... "); hal_spi_dma_transfer(ram_tx_buffer, NULL, ram_tx_buffer[1]+3); while (hal_spi_dma_busy()) {;} // PRINTF("done\r\n"); delay_us(2); HAL_SPI_TRANSFER_OPEN(); HAL_SPI_TRANSFER(CMD_CONFIG_MODE); /* config mode cmd */ HAL_SPI_TRANSFER(0x09); // oder 0x0A HAL_SPI_TRANSFER(0x00); /* whole analog frontend on */ HAL_SPI_TRANSFER(0x10); /* enable rx-antenna (0x10) and set gain (0x10-0x13) */ HAL_SPI_TRANSFER(0x6F); // (MODULE_TX_RS | MODULE_TX | MODULE_RX_RS | MODULE_RX | MODULE_LOOPBACK); HAL_SPI_TRANSFER(0x11); /* Preamble length... */ HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER(0x00); HAL_SPI_TRANSFER_CLOSE(); /* wait for ints */ PRINTF("uwb: waiting for tx-interrupt ... "); /* encoding time depends on frame length - so make it length-dependend */ for (i=0;i<ram_tx_buffer[1];i++) { if (HAL_CHECK_IRQ1()) break; delay_us(20); } if (i < ram_tx_buffer[1]) PRINTF("ok\r\n"); else { PRINTF("FAILED\r\n"); failed++; } /* wait for ints */ PRINTF("uwb: waiting for rx-interrupt ... "); for (i=0;i<50;i++) { if (HAL_CHECK_IRQ0()) break; delay_us(5); } if (i < 50) PRINTF("ok\r\n"); else { PRINTF("FAILED\r\n"); failed++; } /* read frame */ // PRINTF("uwb: starting frame download ... "); HAL_SS_LOW(); HAL_SPI_TRANSFER(CMD_READ_RAM_RX); HAL_SPI_TRANSFER(0x00); i = HAL_SPI_TRANSFER(0x00); if (i>0) { hal_spi_dma_transfer(NULL, ram_rx_buffer, i); while (hal_spi_dma_busy()) {;} } HAL_SS_HIGH(); // PRINTF("done\r\n"); /* do reset to release IRQs */ HAL_ASSERT_RST(); delay_us(2); HAL_DEASSERT_RST(); delay_us(2); if ((i == ram_tx_buffer[1]) && (memcmp(&ram_tx_buffer[2],ram_rx_buffer,i) == 0)) PRINTF("uwb: ... PASSED\r\n"); else { if (i != ram_tx_buffer[1]) PRINTF("uwb: ... length is %u, expected %u - FAILED\r\n", i, ram_tx_buffer[1]); else PRINTF("uwb: ... buffers differ - FAILED\r\n"); failed++; } return failed; }
/** \brief Transfer a frame from the radio transceiver to a RAM buffer * * This version is optimized for use with contiki RF230BB driver. * The callback routine and CRC are left out for speed in reading the rx buffer. * Any delays here can lead to overwrites by the next packet! * * If the frame length is out of the defined bounds, the length, lqi and crc * are set to zero. * * \param rx_frame Pointer to the data structure where the frame is stored. */ void hal_frame_read(hal_rx_frame_t *rx_frame) { #if defined(__AVR_ATmega128RFA1__) uint8_t frame_length,*rx_data,*rx_buffer; /* Get length from the TXT_RX_LENGTH register, not including LQI * Bypassing the length check can result in overrun if buffer is < 256 bytes. */ frame_length = TST_RX_LENGTH; if ( 0 || ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH))) { rx_frame->length = frame_length; /* Start of buffer in I/O space, pointer to RAM buffer */ rx_buffer=(uint8_t *)0x180; rx_data = (rx_frame->data); do{ *rx_data++ = _SFR_MEM8(rx_buffer++); } while (--frame_length > 0); /*Read LQI value for this frame.*/ rx_frame->lqi = *rx_buffer; #else /* defined(__AVR_ATmega128RFA1__) */ uint8_t *rx_data; /*Send frame read (long mode) command.*/ HAL_SPI_TRANSFER_OPEN(); HAL_SPI_TRANSFER(0x20); /*Read frame length. This includes the checksum. */ uint8_t frame_length = HAL_SPI_TRANSFER(0); /*Check for correct frame length. Bypassing this test can result in a buffer overrun! */ if ( 0 || ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH))) { rx_data = (rx_frame->data); rx_frame->length = frame_length; /*Transfer frame buffer to RAM buffer */ HAL_SPI_TRANSFER_WRITE(0); HAL_SPI_TRANSFER_WAIT(); do{ *rx_data++ = HAL_SPI_TRANSFER_READ(); HAL_SPI_TRANSFER_WRITE(0); /* CRC was checked in hardware, but redoing the checksum here ensures the rx buffer * is not being overwritten by the next packet. Since that lengthy computation makes * such overwrites more likely, we skip it and hope for the best. * Without the check a full buffer is read in 320us at 2x spi clocking. * The 802.15.4 standard requires 640us after a greater than 18 byte frame. * With a low interrupt latency overwrites should never occur. */ // crc = _crc_ccitt_update(crc, tempData); HAL_SPI_TRANSFER_WAIT(); } while (--frame_length > 0); /*Read LQI value for this frame.*/ rx_frame->lqi = HAL_SPI_TRANSFER_READ(); #endif /* defined(__AVR_ATmega128RFA1__) */ /* If crc was calculated set crc field in hal_rx_frame_t accordingly. * Else show the crc has passed the hardware check. */ rx_frame->crc = true; } else { /* Length test failed */ rx_frame->length = 0; rx_frame->lqi = 0; rx_frame->crc = false; } HAL_SPI_TRANSFER_CLOSE(); } /*----------------------------------------------------------------------------*/ /** \brief This function will download a frame to the radio transceiver's frame * buffer. * * \param write_buffer Pointer to data that is to be written to frame buffer. * \param length Length of data. The maximum length is 127 bytes. */ void hal_frame_write(uint8_t *write_buffer, uint8_t length) { #if defined(__AVR_ATmega128RFA1__) uint8_t *tx_buffer; tx_buffer=(uint8_t *)0x180; //start of fifo in i/o space /* Write frame length, including the two byte checksum */ /* The top bit of the length field shall be set to 0 for IEEE 802.15.4 compliant frames */ /* It should already be clear, so bypassing the masking is sanity check of the uip stack */ // length &= 0x7f; _SFR_MEM8(tx_buffer++) = length; /* Download to the Frame Buffer. * When the FCS is autogenerated there is no need to transfer the last two bytes * since they will be overwritten. */ #if !RF230_CONF_CHECKSUM length -= 2; #endif do _SFR_MEM8(tx_buffer++)= *write_buffer++; while (--length); #else /* defined(__AVR_ATmega128RFA1__) */ /* Optionally truncate length to maximum frame length. * Not doing this is a fast way to know when the application needs fixing! */ // length &= 0x7f; HAL_SPI_TRANSFER_OPEN(); /* Send Frame Transmit (long mode) command and frame length */ HAL_SPI_TRANSFER(0x60); HAL_SPI_TRANSFER(length); /* Download to the Frame Buffer. * When the FCS is autogenerated there is no need to transfer the last two bytes * since they will be overwritten. */ #if !RF230_CONF_CHECKSUM length -= 2; #endif do HAL_SPI_TRANSFER(*write_buffer++); while (--length); HAL_SPI_TRANSFER_CLOSE(); #endif /* defined(__AVR_ATmega128RFA1__) */ }
/** \brief Transfer a frame from the radio transceiver to a RAM buffer * * This version is optimized for use with contiki RF230BB driver. * The callback routine and CRC are left out for speed in reading the rx buffer. * Any delays here can lead to overwrites by the next packet! * * If the frame length is out of the defined bounds, the length, lqi and crc * are set to zero. * * \param rx_frame Pointer to the data structure where the frame is stored. */ void hal_frame_read(hal_rx_frame_t *rx_frame) { #if defined(__AVR_ATmega128RFA1__) uint8_t frame_length,*rx_data,*rx_buffer; /* Get length from the TXT_RX_LENGTH register, not including LQI * Bypassing the length check can result in overrun if buffer is < 256 bytes. */ frame_length = TST_RX_LENGTH; if ((frame_length < HAL_MIN_FRAME_LENGTH) || (frame_length > HAL_MAX_FRAME_LENGTH)) { /* Length test failed */ rx_frame->length = 0; rx_frame->lqi = 0; rx_frame->crc = false; return; } rx_frame->length = frame_length; /* Start of buffer in I/O space, pointer to RAM buffer */ rx_buffer=(uint8_t *)0x180; rx_data = (rx_frame->data); do{ *rx_data++ = _SFR_MEM8(rx_buffer++); } while (--frame_length > 0); /*Read LQI value for this frame.*/ rx_frame->lqi = *rx_buffer; /* If crc was calculated set crc field in hal_rx_frame_t accordingly. * Else show the crc has passed the hardware check. */ rx_frame->crc = true; #else /* defined(__AVR_ATmega128RFA1__) */ uint8_t frame_length, *rx_data; /*Send frame read (long mode) command.*/ HAL_SPI_TRANSFER_OPEN(); HAL_SPI_TRANSFER(0x20); /*Read frame length. This includes the checksum. */ frame_length = HAL_SPI_TRANSFER(0); /*Check for correct frame length. Bypassing this test can result in a buffer overrun! */ if ((frame_length < HAL_MIN_FRAME_LENGTH) || (frame_length > HAL_MAX_FRAME_LENGTH)) { /* Length test failed */ rx_frame->length = 0; rx_frame->lqi = 0; rx_frame->crc = false; } else { rx_data = (rx_frame->data); rx_frame->length = frame_length; /*Transfer frame buffer to RAM buffer */ HAL_SPI_TRANSFER_WRITE(0); HAL_SPI_TRANSFER_WAIT(); do{ *rx_data++ = HAL_SPI_TRANSFER_READ(); HAL_SPI_TRANSFER_WRITE(0); /* CRC was checked in hardware, but redoing the checksum here ensures the rx buffer * is not being overwritten by the next packet. Since that lengthy computation makes * such overwrites more likely, we skip it and hope for the best. * Without the check a full buffer is read in 320us at 2x spi clocking. * The 802.15.4 standard requires 640us after a greater than 18 byte frame. * With a low interrupt latency overwrites should never occur. */ // crc = _crc_ccitt_update(crc, tempData); HAL_SPI_TRANSFER_WAIT(); } while (--frame_length > 0); /*Read LQI value for this frame.*/ rx_frame->lqi = HAL_SPI_TRANSFER_READ(); /* If crc was calculated set crc field in hal_rx_frame_t accordingly. * Else show the crc has passed the hardware check. */ rx_frame->crc = true; } HAL_SPI_TRANSFER_CLOSE(); #endif /* defined(__AVR_ATmega128RFA1__) */ }