/** Initialize the AVR clock speed. */ void halSetupClock(void) { // Set clock speed based on F_CPU flag if (F_CPU == 4000000UL) { AVR_ENTER_CRITICAL_REGION(); CLKPR = 1 << CLKPCE; // Set the change-enable flag CLKPR = 1; // Set for divide-by-two, or 4MHz AVR_LEAVE_CRITICAL_REGION(); } if (F_CPU == 2000000UL) { AVR_ENTER_CRITICAL_REGION(); CLKPR = 1 << CLKPCE; // Set the change-enable flag CLKPR = 2; // Set for divide-by-four, or 2MHz AVR_LEAVE_CRITICAL_REGION(); } if (F_CPU == 1000000UL) { AVR_ENTER_CRITICAL_REGION(); CLKPR = 1 << CLKPCE; // Set the change-enable flag CLKPR = 3; // Set for divide-by-eight, or 1MHz 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 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 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( ); }
/** Initialize the AVR clock speed. */ void halSetupClock(void) { // Set clock speed based on Xtal and F_CPU define // It programs the ClockPrescaleRegister to divide Fosc to the value given in the F_CPU define // It assumes that Fosc is running at 16Mhz, either by external Xtal osc. //NOTE on sharing clocks between RF212 and MCU: /* Since the AVR can not switch the clock source programmatically we are stuck with the clock source as programmed * via the fuse bits and can not switch in the RF212's clock output after starting up on the RC osc. Dynamic switching * of the MCU's clock source would be necessary since the radio chip disables the clock during reset and sleep cuasing a * deadlock in the CPU. * * Using the internal ~8mhz RC oscillator would be ok fine, except that the UART bases the baud rate on the CPU clock * and it might not be precise enough for the serial debug output. * * Using an external Xtal on the MCU and feeding the clock to the radio seems like a good choice, except that the radio * requires a 16Mhz clock and a VCC of no more than 3.6V. The (20mhz) MCU is not guaranteed to run at 16Mhz below 4.5V. * and therefore this solution is not guaranteed to work in all situations, although it seems to work on the proto board. * * So, to guarantee proper operation of the MCU AND serial port one will have to use an 8Mhz Xtal on the MCU and * a 16Mhz Xtal on the radio or use the internal 8Mhz RC osc and then calibrate it with the help of the 32Khz timer xtal. * * For a final product where the serial port is not used, the xtal on the MCU can be omitted and the internal 8Mhz Osc can * be used. * */ AVR_ENTER_CRITICAL_REGION(); CLKPR = 1 << CLKPCE; // Set the change-enable flag CLKPR = ((F_OSC/F_CPU)-1); // Set for divide-by-n, 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 radio_register_read(u8 address) { //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(); RADIO_DEVSEL_L(); //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; RADIO_DEVSEL_H(); //End the transaction by pulling the Slave Select High. AVR_LEAVE_CRITICAL_REGION(); return register_value; }
/*! \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 radio_register_write(u8 address, u8 value) { //Add the Register Write command to the address. address = HAL_TRX_CMD_RW | (HAL_TRX_CMD_RADDRM & address); AVR_ENTER_CRITICAL_REGION(); RADIO_DEVSEL_L(); //Start the SPI transaction by pulling the Slave Select low. /*Send Register address and write register content.*/ SPDR = address; while ((SPSR & (1 << SPIF)) == 0) {;} SPDR; // Dummy read of SPDR SPDR = value; while ((SPSR & (1 << SPIF)) == 0) {;} SPDR; // Dummy read of SPDR RADIO_DEVSEL_H(); //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 ((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; } }
/*! \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 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 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; }
u16 macGetTime(void) { u16 localtime; AVR_ENTER_CRITICAL_REGION(); localtime = tickTimer; AVR_LEAVE_CRITICAL_REGION(); return localtime; }
/*! \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 reset the interrupt flags and interrupt event handlers * (Callbacks) to their default value. * * \ingroup hal_avr_api */ void hal_reset_flags( void ){ AVR_ENTER_CRITICAL_REGION( ); //Reset Flags. hal_bat_low_flag = 0; hal_trx_ur_flag = 0; hal_trx_end_flag = 0; hal_rx_start_flag = 0; hal_unknown_isr_flag = 0; hal_pll_unlock_flag = 0; hal_pll_lock_flag = 0; //Reset Associated Event Handlers. rx_start_callback = NULL; trx_end_callback = NULL; 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. * * \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 This is the implementation of the 15.4 MAC Reset Request * primitive. * \param setDefaultPIB True if the default PIB values should be set. * \return Integer denoting success or failure. * \retval 0 Failure. * \retval 1 Success. * * Sets all PIB values to default. */ void sicslowmac_resetRequest (bool setDefaultPIB) { if(setDefaultPIB){ /* initialize all of the MAC PIB variables to their default values */ macCoordShortAddress = 0xffff; macDSN = rand() % 256; macSrcPANId = SOURCE_PAN_ID; macDstPANId = DEST_PAN_ID; macShortAddress = 0xffff; /* Setup the address of this device by reading a stored address from eeprom. */ /** \todo This might be read from the serial eeprom onboard Raven. */ AVR_ENTER_CRITICAL_REGION(); eeprom_read_block ((void *)&macLongAddr, EEPROMMACADDRESS, 8); byte_reverse((uint8_t *) &macLongAddr, 8); 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; }
/*! \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 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(); }
/** Sets a general purpose timer. Can be called by application. The callback will not be called from the timer ISR, so it is thread-safe. param: time Number of milliseconds to wait before calling the callback function. This parameter can be 0-65535 param: callback Pointer to a function to call back after the specified time. The callback function must take no arguments and return nothing. returns: Handle to timer. Can be used to call macTimerKill(). NOTE: Timers are oneshot only - no repeat or reload function you must call MacSetAlarm repeadedtly for a timed loop */ u8 macSetAlarm(u16 time, void(*callback)(void)) { u8 i; u16 ticks; if (!time) { // Don't delay, just call it callback(); return 0; } // Store the timer details in the array ticks = max(time, 1); // At least one tick // Protect this section from an ISR that will add an alarm AVR_ENTER_CRITICAL_REGION(); // search for free event structure for (i=0;i<TIMER_EVENTS_MAX;i++) if (!timerEvents[i].time) // free, use this one break; if (i >= TIMER_EVENTS_MAX) // Out of timers to use, just quit return 0; timerEvents[i].time = ticks; timerEvents[i].callback = callback; // don't return zero as a timer ID timerEvents[i].timerID = getUniqueTimer_ID(); AVR_LEAVE_CRITICAL_REGION(); return timerEvents[i].timerID; }
/*! \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 radio_frame_write(u8 *write_buffer, u8 length) { 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(); RADIO_DEVSEL_L(); //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); RADIO_DEVSEL_H(); //Terminate SPI transaction. AVR_LEAVE_CRITICAL_REGION(); }
/* * Write a register of the transceiver over SPI */ void spi_regWrite(uint8_t addr, uint8_t data) { AVR_ENTER_CRITICAL_REGION( ); /* Prepare the command byte */ addr |= 0xC0; /* Start SPI transaction by pulling SEL low */ SPI &= ~(1 << SEL1); /* Send the Read command byte */ SPDR = addr; while (!(SPSR & (1 << SPIF))); _delay_us(100); /* Write the byte in the transceiver data register */ SPDR = data; while (!(SPSR & (1 << SPIF))); _delay_us(100); /* Stop the SPI transaction by setting SEL high */ SPI |= (1 << SEL1); AVR_LEAVE_CRITICAL_REGION( ); }
/*------Done in a subroutine to keep main routine stack usage small--------*/ void initialize(void) { //calibrate_rc_osc_32k(); //CO: Had to comment this out #ifdef RAVEN_LCD_INTERFACE /* First rs232 port for Raven 3290 port */ rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); /* Set input handler for 3290 port */ rs232_set_input(0,raven_lcd_serial_input); #endif /* Second rs232 port for debugging */ rs232_init(RS232_PORT_1, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); /* Redirect stdout to second port */ rs232_redirect_stdout(RS232_PORT_1); clock_init(); printf_P(PSTR("\n*******Booting %s*******\n"),CONTIKI_VERSION_STRING); /* Initialize process subsystem */ process_init(); #ifdef RF230BB { /* Start radio and radio receive process */ rf230_init(); sicslowpan_init(sicslowmac_init(&rf230_driver)); // ctimer_init(); // sicslowpan_init(lpp_init(&rf230_driver)); // rime_init(sicslowmac_driver.init(&rf230_driver)); // rime_init(lpp_init(&rf230_driver)); /* Set addresses BEFORE starting tcpip process */ rimeaddr_t addr; memset(&addr, 0, sizeof(rimeaddr_t)); AVR_ENTER_CRITICAL_REGION(); eeprom_read_block ((void *)&addr.u8, &mac_address, 8); AVR_LEAVE_CRITICAL_REGION(); memcpy(&uip_lladdr.addr, &addr.u8, 8); rf230_set_pan_addr(IEEE802154_PANID, 0, (uint8_t *)&addr.u8); rf230_set_channel(24); rimeaddr_set_node_addr(&addr); PRINTF("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); // uip_ip6addr(&ipprefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); // uip_netif_addr_add(&ipprefix, UIP_DEFAULT_PREFIX_LEN, 0, AUTOCONF); // uip_nd6_prefix_add(&ipprefix, UIP_DEFAULT_PREFIX_LEN, 0); // PRINTF("Prefix %x::/%u\n",ipprefix.u16[0],UIP_DEFAULT_PREFIX_LEN); #if UIP_CONF_ROUTER rime_init(rime_udp_init(NULL)); uip_router_register(&rimeroute); #endif PRINTF("Driver: %s, Channel: %u\n", sicslowmac_driver.name, rf230_get_channel()); } #endif /*RF230BB*/ /* Register initial processes */ procinit_init(); /* Autostart processes */ autostart_start(autostart_processes); //Give ourselves a prefix // init_net(); /*---If using coffee file system create initial web content if necessary---*/ #if COFFEE_FILES int fa = cfs_open( "/index.html", CFS_READ); if (fa<0) { //Make some default web content printf_P(PSTR("No index.html file found, creating upload.html!\n")); printf_P(PSTR("Formatting FLASH file system for coffee...")); cfs_coffee_format(); printf_P(PSTR("Done!\n")); fa = cfs_open( "/index.html", CFS_WRITE); int r = cfs_write(fa, &"It works!", 9); if (r<0) printf_P(PSTR("Can''t create /index.html!\n")); cfs_close(fa); // fa = cfs_open("upload.html"), CFW_WRITE); // <html><body><form action="upload.html" enctype="multipart/form-data" method="post"><input name="userfile" type="file" size="50" /><input value="Upload" type="submit" /></form></body></html> } #endif /*--------------------------Announce the configuration---------------------*/ #if WEBSERVER char buf[80]; unsigned int size; eeprom_read_block (buf,server_name, sizeof(server_name)); buf[sizeof(server_name)]=0; printf_P(PSTR("%s"),buf); eeprom_read_block (buf,domain_name, sizeof(domain_name)); buf[sizeof(domain_name)]=0; size=httpd_fs_get_size(); #ifndef COFFEE_FILES printf_P(PSTR(".%s online with fixed %u byte web content\n"),buf,size); #elif COFFEE_FILES==1 printf_P(PSTR(".%s online with static %u byte EEPROM file system\n"),buf,size); #elif COFFEE_FILES==2 printf_P(PSTR(".%s online with dynamic %u KB EEPROM file system\n"),buf,size>>10); #elif COFFEE_FILES==3 printf_P(PSTR(".%s online with static %u byte program memory file system\n"),buf,size); #elif COFFEE_FILES==4 printf_P(PSTR(".%s online with dynamic %u KB program memory file system\n"),buf,size>>10); #endif #else printf_P(PSTR("Online\n")); #endif /* WEBSERVER */ }
/** General-purpose function to write data to eeprom @param offset The offset in EEPROM of the start of the data block @param length The length in bytes of the data block @param src Pointer to the area in memory which contains the data block */ void halPutEeprom(u8 *addr, u8 length, u8 *src) { AVR_ENTER_CRITICAL_REGION(); eeprom_write_block (src, addr, length); AVR_LEAVE_CRITICAL_REGION(); }
/** General-purpose function to read data out of eeprom @param offset The offset in EEPROM of the start of the data block @param length The length in bytes of the data block @param dest Pointer to the area in memory to place the data block */ void halGetEeprom(u8 *addr, u8 length, u8 *dest) { AVR_ENTER_CRITICAL_REGION(); eeprom_read_block (dest, addr, length); AVR_LEAVE_CRITICAL_REGION(); }
/*! \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; }
void set_flag_stop(bool flag) { AVR_ENTER_CRITICAL_REGION(); bStop = flag; AVR_LEAVE_CRITICAL_REGION(); }