/*! \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. * * \param rx_frame Pointer to the data structure where the frame is stored. * * \ingroup hal_avr_api */ void hal_frame_read( hal_rx_frame_t *rx_frame ) { uint8_t frame_length; AVR_ENTER_CRITICAL_REGION( ); HAL_SS_LOW( ); //Send frame read command. frame_length=hal_RF_SPI_Send_Data(HAL_TRX_CMD_FR); // frame_length=hal_RF_SPI_Send_Data(frame_length); //delay_ms(1); /*Check for correct frame length.*/ if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)) { uint16_t crc = 0; uint8_t *rx_data = (rx_frame->data); uint8_t tempData; rx_frame->length = frame_length; //Store frame length. /*Upload frame buffer to data pointer. Calculate CRC.*/ do{ tempData = hal_RF_SPI_Send_Data(frame_length); *rx_data++ = tempData; crc = crc_ccitt_update( crc, tempData ); } while (--frame_length > 0); /*Read LQI value for this frame.*/ rx_frame->lqi = hal_RF_SPI_Send_Data( tempData); HAL_SS_HIGH( ); /*Check calculated crc, and set crc field in hal_rx_frame_t accordingly.*/ if (crc == HAL_CALCULATED_CRC_OK) { rx_frame->crc = true; } else { rx_frame->crc = false; } } else { HAL_SS_HIGH( ); rx_frame->length = 0; rx_frame->lqi = 0; rx_frame->crc = false; } AVR_LEAVE_CRITICAL_REGION( ); }
/*! \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 at86rf23x_registermap.h file for register address definitions. * * \returns The actual value of the read register. * */ u8 hal_register_read(u16 address) { #ifdef SINGLE_CHIP return (*(volatile uint8_t *)(address)); #else //Add the register read command to the register address. // address &= HAL_TRX_CMD_RADDRM; address |= HAL_TRX_CMD_RR; u8 register_value = 0; AVR_ENTER_CRITICAL_REGION(); HAL_SS_LOW(); //Start the SPI transaction by pulling the Slave Select low. /*Send Register address and read register content.*/ SPDR = (u8)address; while ((SPSR & (1 << SPIF)) == 0) {;} register_value = SPDR; SPDR = register_value; while ((SPSR & (1 << SPIF)) == 0) {;} register_value = SPDR; HAL_SS_HIGH(); //End the transaction by pulling the Slave Select High. AVR_LEAVE_CRITICAL_REGION(); return register_value; #endif //return 0; }
/** \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) { length &= HAL_TRX_CMD_RADDRM; /* Truncate length to maximum frame length. */ AVR_ENTER_CRITICAL_REGION(); HAL_SS_LOW(); /* Initiate the SPI transaction. */ /*SEND FRAME WRITE COMMAND AND FRAME LENGTH.*/ SPDR = HAL_TRX_CMD_FW; while ((SPSR & (1 << SPIF)) == 0) {;} uint8_t dummy_read = SPDR; SPDR = length; while ((SPSR & (1 << SPIF)) == 0) {;} dummy_read = SPDR; /* Download to the Frame Buffer. */ do{ SPDR = *write_buffer++; --length; while ((SPSR & (1 << SPIF)) == 0) {;} dummy_read = SPDR; } while (length > 0); HAL_SS_HIGH(); /* Terminate SPI transaction. */ AVR_LEAVE_CRITICAL_REGION(); }
/** * @brief Writes and reads data into/from SRAM of the transceiver * * This function writes data into the SRAM of the transceiver and * simultaneously reads the bytes. * * @param addr Start address in the SRAM for the write operation * @param idata Pointer to the data written/read into/from SRAM * @param length Number of bytes written/read into/from SRAM */ void hal_trx_aes_wrrd(uint8_t addr, uint8_t *idata, uint8_t length) { uint8_t *odata; delay_us(1); AVR_ENTER_CRITICAL_REGION(); /* Start SPI transaction by pulling SEL low */ HAL_SS_LOW(); // Send the command byte hal_RF_SPI_Send_Data(HAL_TRX_CMD_SW);//Send the command byte hal_RF_SPI_Send_Data(addr);//write SRAM start address // now transfer data odata = idata; /* write data byte 0 - the obtained value in SPDR is meaningless */ hal_RF_SPI_Send_Data( *idata++); /* process data bytes 1...length-1: write and read */ while (--length) { *odata++ = hal_RF_SPI_Send_Data( *idata++); } /* to get the last data byte, write some dummy byte */ *odata++ = hal_RF_SPI_Send_Data( SPI_DUMMY_VALUE); /* Stop the SPI transaction by setting SEL high */ HAL_SS_HIGH(); AVR_LEAVE_CRITICAL_REGION(); }
/** \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 at86rf212_registermap.h file for register address definitions. * * \returns The actual value of the read register. */ uint8_t hal_register_read(uint8_t address) { /* Add the register read command to the register address. */ address &= HAL_TRX_CMD_RADDRM; address |= HAL_TRX_CMD_RR; uint8_t register_value = 0; AVR_ENTER_CRITICAL_REGION(); HAL_SS_LOW(); /* Start the SPI transaction by pulling the Slave Select low. */ /*Send Register address and read register content.*/ SPDR = address; while ((SPSR & (1 << SPIF)) == 0) {;} register_value = SPDR; SPDR = register_value; while ((SPSR & (1 << SPIF)) == 0) {;} register_value = SPDR; HAL_SS_HIGH(); /* End the transaction by pulling the Slave Select High. */ AVR_LEAVE_CRITICAL_REGION(); return register_value; }
/*! \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. * * \ingroup hal_avr_api */ void hal_frame_write( uint8_t *write_buffer, uint8_t length ) { uint8_t dummy_read; length &= HAL_TRX_CMD_RADDRM; //Truncate length to maximum frame length. AVR_ENTER_CRITICAL_REGION( ); HAL_SS_LOW( ); //Initiate the SPI transaction. /*SEND FRAME WRITE COMMAND AND FRAME LENGTH.*/ hal_RF_SPI_Send_Data(HAL_TRX_CMD_FW); hal_RF_SPI_Send_Data(length); delay_us(100); //Download to the Frame Buffer. /* do { SPDR = *write_buffer++; --length; while ((SPSR & (1 << SPIF)) == 0) {;} dummy_read = SPDR; //delay_us(100); } while (length > 0);*/ do { dummy_read = hal_RF_SPI_Send_Data( *write_buffer++); } while (--length > 0); HAL_SS_HIGH( ); //Terminate SPI transaction. AVR_LEAVE_CRITICAL_REGION( ); }
/*! \brief Read SRAM * * This function reads from the SRAM of the radio transceiver. * * \param address Address in the TRX's SRAM where the read burst should start * \param length Length of the read burst * \param data Pointer to buffer where data is stored. * */ void hal_sram_read(u8 address, u8 length, u8 *data) { AVR_ENTER_CRITICAL_REGION(); HAL_SS_LOW(); //Initiate the SPI transaction. /*Send SRAM read command.*/ SPDR = HAL_TRX_CMD_SR; while ((SPSR & (1 << SPIF)) == 0) ; SPDR; // Dummy read of SPDR /*Send address where to start reading.*/ SPDR = address; while ((SPSR & (1 << SPIF)) == 0) ; SPDR; // Dummy read of SPDR /*Upload the chosen memory area.*/ do { SPDR = HAL_DUMMY_READ; while ((SPSR & (1 << SPIF)) == 0) {;} *data++ = SPDR; } while (--length > 0); HAL_SS_HIGH(); AVR_LEAVE_CRITICAL_REGION(); }
/*! \brief Write SRAM * * This function writes into the SRAM of the radio transceiver. * * \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(u8 address, u8 length, u8 *data) { AVR_ENTER_CRITICAL_REGION(); HAL_SS_LOW(); /*Send SRAM write command.*/ SPDR = HAL_TRX_CMD_SW; while ((SPSR & (1 << SPIF)) == 0) {;} SPDR; // Dummy read of SPDR /*Send address where to start writing to.*/ SPDR = address; while ((SPSR & (1 << SPIF)) == 0) ; SPDR; // Dummy read of SPDR /*Upload the chosen memory area.*/ do { SPDR = *data++; while ((SPSR & (1 << SPIF)) == 0) ; SPDR; // Dummy read of SPDR } while (--length > 0); HAL_SS_HIGH(); AVR_LEAVE_CRITICAL_REGION(); }
/*! \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(u8 *write_buffer, u8 length) { #ifdef SINGLE_CHIP volatile uint8_t *pDst = (volatile uint8_t *)0x180; AVR_ENTER_CRITICAL_REGION(); //Toggle the SLP_TR pin to initiate the frame transmission. hal_set_slptr_high(); hal_set_slptr_low(); *pDst = length; pDst++; memcpy((void *)pDst, write_buffer, length); AVR_LEAVE_CRITICAL_REGION(); #else length &= HAL_TRX_CMD_RADDRM; //Truncate length to maximum frame length. AVR_ENTER_CRITICAL_REGION(); //Toggle the SLP_TR pin to initiate the frame transmission. hal_set_slptr_high(); hal_set_slptr_low(); HAL_SS_LOW(); //Initiate the SPI transaction. /*SEND FRAME WRITE COMMAND AND FRAME LENGTH.*/ SPDR = HAL_TRX_CMD_FW; while ((SPSR & (1 << SPIF)) == 0) {;} SPDR; // Dummy read of SPDR SPDR = length; while ((SPSR & (1 << SPIF)) == 0) {;} SPDR; // Dummy read of SPDR // Download to the Frame Buffer. do { SPDR = *write_buffer++; --length; while ((SPSR & (1 << SPIF)) == 0) ; SPDR; // Dummy read of SPDR } while (length > 0); HAL_SS_HIGH(); //Terminate SPI transaction. AVR_LEAVE_CRITICAL_REGION(); #endif //SINGLE_CHIP }
/*! \brief Read SRAM * * This function reads from the SRAM of the radio transceiver. * * \param address Address in the TRX's SRAM where the read burst should start * \param length Length of the read burst * \param data Pointer to buffer where data is stored. * * \ingroup hal_avr_api */ void hal_sram_read( uint8_t address, uint8_t length, uint8_t *data ) { // uint8_t dummy_read; AVR_ENTER_CRITICAL_REGION( ); HAL_SS_LOW( ); //Initiate the SPI transaction. //Send SRAM read command. hal_RF_SPI_Send_Data(HAL_TRX_CMD_SR); hal_RF_SPI_Send_Data(address); /*Upload the chosen memory area.*/ do { *data++ = hal_RF_SPI_Send_Data( HAL_DUMMY_READ); } while (--length > 0); HAL_SS_HIGH( ); AVR_LEAVE_CRITICAL_REGION( ); }
/*! \brief Write SRAM * * This function writes into the SRAM of the radio transceiver. * * \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 * * \ingroup hal_avr_api */ void hal_sram_write( uint8_t address, uint8_t length, uint8_t *data ) { // uint8_t dummy_read; AVR_ENTER_CRITICAL_REGION( ); HAL_SS_LOW( ); //Send SRAM write command. hal_RF_SPI_Send_Data(HAL_TRX_CMD_SW); hal_RF_SPI_Send_Data(address); /*Upload the chosen memory area.*/ do { hal_RF_SPI_Send_Data( *data++); } while (--length > 0); HAL_SS_HIGH( ); AVR_LEAVE_CRITICAL_REGION( ); }
/*! \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. * * \ingroup hal_avr_api */ void hal_register_write( uint8_t address, uint8_t value ) { // uint8_t dummy_read; //Add the Register Write command to the address. address = HAL_TRX_CMD_RW | (HAL_TRX_CMD_RADDRM & address); AVR_ENTER_CRITICAL_REGION( ); HAL_SS_LOW( ); //Start the SPI transaction by pulling the Slave Select low. /*Send Register address and write register content.*/ hal_RF_SPI_Send_Data(address); delay_us(100); hal_RF_SPI_Send_Data( value); HAL_SS_HIGH( ); //End the transaction by pulling the Slave Slect High. AVR_LEAVE_CRITICAL_REGION( ); }
/*! \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. * * \ingroup hal_avr_api */ uint8_t hal_register_read( uint8_t address ){ uint8_t register_value = 0; //Add the register read command to the register address. address &= HAL_TRX_CMD_RADDRM; address |= HAL_TRX_CMD_RR; AVR_ENTER_CRITICAL_REGION( ); HAL_SS_LOW( ); //Start the SPI transaction by pulling the Slave Select low. /*Send Register address and read register content.*/ register_value=hal_RF_SPI_Send_Data(address); register_value=hal_RF_SPI_Send_Data(register_value); HAL_SS_HIGH( ); //End the transaction by pulling the Slave Select High. AVR_LEAVE_CRITICAL_REGION( ); return register_value; }
void enter_node_stop(void) { // turn off RF tat_enter_sleep_mode(); hal_set_rst_high(); HAL_SS_HIGH(); // turn off flash //set_spi_flash_state(SPI_FLASH_OFF); GPIO_SetBits(GPIOB, PIN_RST); GPIO_SetBits(GPIOB, PIN_CS); flash_off(); // testing... #ifdef MY_DEBUG hal_clear_net_led(); hal_clear_data_led(); #endif testing(); RTC_WakeUpCmd(ENABLE); }
/*! \brief This function writes a new value to one of the radio transceiver's * registers. * * \see Look at the at86rf23x_registermap.h file for register address definitions. * * \param address Address of register to write. * \param value Value to write. * */ void hal_register_write(u16 address, u8 value) { #ifdef SINGLE_CHIP (*(volatile uint8_t *)(address)) = (value); #else //Add the Register Write command to the address. address = HAL_TRX_CMD_RW | (HAL_TRX_CMD_RADDRM & (u8)address); AVR_ENTER_CRITICAL_REGION(); HAL_SS_LOW(); //Start the SPI transaction by pulling the Slave Select low. /*Send Register address and write register content.*/ SPDR = (u8)address; while ((SPSR & (1 << SPIF)) == 0) {;} SPDR; // Dummy read of SPDR SPDR = value; while ((SPSR & (1 << SPIF)) == 0) {;} SPDR; // Dummy read of SPDR HAL_SS_HIGH(); //End the transaction by pulling the Slave Slect High. AVR_LEAVE_CRITICAL_REGION(); // Set the rx_mode variable based on how we set the radio if (((u8)address & ~HAL_TRX_CMD_RW) == RG_TRX_STATE) { // set rx_mode flag based on mode we're changing to value &= 0x1f; // Mask for TRX_STATE register if (value == RX_ON || value == RX_AACK_ON) rx_mode = true; else rx_mode = false; } #endif }
/** \brief This function writes a new value to one of the radio transceiver's * registers. * * \see Look at the at86rf212_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 command to the address. */ address = HAL_TRX_CMD_RW | (HAL_TRX_CMD_RADDRM & address); AVR_ENTER_CRITICAL_REGION(); HAL_SS_LOW(); /* Start the SPI transaction by pulling the Slave Select low. */ /*Send Register address and write register content.*/ SPDR = address; while ((SPSR & (1 << SPIF)) == 0) {;} uint8_t dummy_read = SPDR; SPDR = value; while ((SPSR & (1 << SPIF)) == 0) {;} dummy_read = SPDR; HAL_SS_HIGH(); /* End the transaction by pulling the Slave Slect High. */ AVR_LEAVE_CRITICAL_REGION(); }
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 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 RF212BB driver * * \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) { uint8_t *rx_data=0; /* check that we have either valid frame pointer or callback pointer */ // if (!rx_frame && !rx_callback) // return; AVR_ENTER_CRITICAL_REGION(); HAL_SS_LOW(); /*Send frame read command.*/ SPDR = HAL_TRX_CMD_FR; while ((SPSR & (1 << SPIF)) == 0) {;} uint8_t frame_length = SPDR; /*Read frame length.*/ SPDR = frame_length; while ((SPSR & (1 << SPIF)) == 0) {;} frame_length = SPDR; /*Check for correct frame length.*/ if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)){ //GH: not needed //uint16_t crc = 0; uint8_t rx_status = 0; //variable for RX_STATUS information // if (rx_frame){ rx_data = (rx_frame->data); rx_frame->length = frame_length; // } else { // rx_callback(frame_length); // } /*Upload frame buffer to data pointer. Calculate CRC.*/ SPDR = frame_length; while ((SPSR & (1 << SPIF)) == 0) {;} do{ uint8_t tempData = SPDR; SPDR = 0; /* dummy write */ // if (rx_frame){ *rx_data++ = tempData; // } else { // rx_callback(tempData); // } //GH: not necessary crc is checked in transceiver //crc = _crc_ccitt_update(crc, tempData); while ((SPSR & (1 << SPIF)) == 0) {;} } while (--frame_length > 0); /*Read LQI value for this frame.*/ // if (rx_frame){ rx_frame->lqi = SPDR; // } else { // rx_callback(SPDR); // } SPDR = 0; /* dummy write */ //read ED while ((SPSR & (1 << SPIF)) == 0) {;} rx_frame->ed = SPDR; SPDR = 0; /* dummy write */ //read RX_STATUS while ((SPSR & (1 << SPIF)) == 0) {;} rx_status = SPDR; SPDR = 0; /* dummy write */ HAL_SS_HIGH(); /*Check calculated crc, and set crc field in hal_rx_frame_t accordingly.*/ // if (rx_frame){ //GH: not necessary crc is checked in transceiver //rx_frame->crc = (crc == HAL_CALCULATED_CRC_OK); rx_frame->crc = (rx_status & 0x80); // } else { // rx_callback(crc != HAL_CALCULATED_CRC_OK); // } } else { HAL_SS_HIGH(); // if (rx_frame){ rx_frame->length = 0; rx_frame->lqi = 0; rx_frame->crc = false; // } } AVR_LEAVE_CRITICAL_REGION(); }
//This #if compile switch is used to provide a "standard" function body for the //doxygen documentation. void hal_input_capture_isr(void) { uint8_t interrupt_source; /*The following code reads the current system time. This is done by first reading the hal_system_time and then adding the 16 LSB directly from the TCNT1 register. */ // uint32_t isr_timestamp = hal_system_time; // isr_timestamp <<= 16; // isr_timestamp |= TCNT1; /*Read Interrupt source.*/ HAL_SS_LOW( ); interrupt_source= hal_RF_SPI_Send_Data(RG_IRQ_STATUS | HAL_TRX_CMD_RR); interrupt_source= hal_RF_SPI_Send_Data(interrupt_source);//The interrupt source is read. // SPDR = interrupt_source; // while ((SPSR & (1 << SPIF)) == 0) {;} // interrupt_source = SPDR; //The interrupt source is read. HAL_SS_HIGH( ); /*Handle the incomming interrupt. Prioritized.*/ if ((interrupt_source & HAL_RX_START_MASK)) { hal_rx_start_flag++; //Increment RX_START flag. if( rx_start_callback != NULL ){ uint8_t frame_length; //Read Frame length and call rx_start callback. HAL_SS_LOW( ); /*SPDR = HAL_TRX_CMD_FR; while ((SPSR & (1 << SPIF)) == 0) {;} uint8_t frame_length = SPDR; SPDR = frame_length; //Any data will do, so frame_length is used. while ((SPSR & (1 << SPIF)) == 0) {;} frame_length = SPDR;*/ frame_length=hal_RF_SPI_Send_Data(HAL_TRX_CMD_FR); frame_length=hal_RF_SPI_Send_Data(frame_length); HAL_SS_HIGH( ); rx_start_callback( 0, frame_length ); } } else if (interrupt_source & HAL_TRX_END_MASK) { hal_trx_end_flag++; //Increment TRX_END flag. if( trx_end_callback != NULL ){ trx_end_callback( 0 ); // trx_end_handler(); } } else if (interrupt_source & HAL_TRX_UR_MASK) { hal_trx_ur_flag++; //Increment TRX_UR flag. } else if (interrupt_source & HAL_PLL_UNLOCK_MASK) { hal_pll_unlock_flag++; //Increment PLL_UNLOCK flag. } else if (interrupt_source & HAL_PLL_LOCK_MASK) { hal_pll_lock_flag++; //Increment PLL_LOCK flag. } else if (interrupt_source & HAL_BAT_LOW_MASK) { //Disable BAT_LOW interrupt to prevent interrupt storm. The interrupt //will continously be signaled when the supply voltage is less than the //user defined voltage threshold. uint8_t trx_isr_mask = hal_register_read( RG_IRQ_MASK ); trx_isr_mask &= ~HAL_BAT_LOW_MASK; hal_register_write( RG_IRQ_MASK, trx_isr_mask ); hal_bat_low_flag++; //Increment BAT_LOW flag. } else { hal_unknown_isr_flag++; //Increment UNKNOWN_ISR flag. } }
/*! \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. * */ uint8_t* hal_frame_read(void) { uint8_t* pFrame = bmm_buffer_alloc(); if(pFrame != NULL) { rx_frame_t *rx_frame = (rx_frame_t*)pFrame; #ifdef SINGLE_CHIP AVR_ENTER_CRITICAL_REGION(); volatile uint8_t *pSrc = (volatile uint8_t *)0x180; uint8_t frame_length = hal_register_read(RG_TST_RX_LENGTH); if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)) { // read length and save frame content -> lqi is NOT included in frame length byte rx_frame->length = frame_length; //memcpy(rx_data, (void *)pSrc, frame_length); memcpy(rx_frame->data, (void *)pSrc, frame_length-1); // save LQI / //rx_frame->lqi = *(pSrc + (frame_length + 1)); rx_frame->lqi = *(pSrc + frame_length); } else { rx_frame->length = 0; rx_frame->lqi = 0; rx_frame->crc = false; bmm_buffer_free(pFrame); // free allcoated buffer pFrame = NULL; // set buffer pointer to NULL, that next app do not use it } AVR_LEAVE_CRITICAL_REGION(); #else uint8_t* rx_data = &rx_frame->data[0]; AVR_ENTER_CRITICAL_REGION(); HAL_SS_LOW(); //Send frame read command. SPDR = HAL_TRX_CMD_FR; while ((SPSR & (1 << SPIF)) == 0) {;} u8 frame_length = SPDR; //Read frame length. SPDR = frame_length; while ((SPSR & (1 << SPIF)) == 0) {;} frame_length = SPDR; //Check for correct frame length. if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)) { rx_frame->length = frame_length; //Store frame length. //Upload frame buffer to data pointer. Calculate CRC. SPDR = frame_length; while ((SPSR & (1 << SPIF)) == 0) ; do { u8 tempData = SPDR; SPDR = 0; // dummy write //*rx_data++ = tempData; *rx_data = tempData; rx_data++; while ((SPSR & (1 << SPIF)) == 0) ; } while (--frame_length > 0); //Read LQI value for this frame. rx_frame->lqi = SPDR; HAL_SS_HIGH(); } else { HAL_SS_HIGH(); if (rx_frame) { rx_frame->length = 0; rx_frame->lqi = 0; rx_frame->crc = false; bmm_buffer_free(pFrame); // free allocated buffer pFrame = NULL; // set buffer pointer to NULL, that next app do not use it } } AVR_LEAVE_CRITICAL_REGION(); #endif // SINGLE_CHIP } return pFrame; }