/*! \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 }
void drvr_reset_fsm() { hal_set_slptr_low(); delay_us(TIME_NOCLK_TO_WAKE); hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF); delay_us(TIME_CMD_FORCE_TRX_OFF); }
void drvr_at86_reset() { hal_set_rst_low(); hal_set_slptr_low(); delay_us(TIME_RESET); hal_set_rst_high(); }
U8 drvr_tx(const buffer_t *buf) { U8 state = drvr_get_trx_state(); if ((state == BUSY_TX) || (state == BUSY_TX_ARET)) { return RADIO_WRONG_STATE; } // TODO: check why we need to transition to the off state before we go to tx_aret_on drvr_set_trx_state(TRX_OFF); drvr_set_trx_state(TX_ARET_ON); // TODO: try and start the frame transmission by writing TX_START command instead of toggling // sleep pin...i just feel like it's kind of weird... // write frame to buffer hal_frame_write(buf->dptr, buf->len); // TEST - check data in buffer //{ // U8 tmp[30]; // // hal_sram_read(0, buf->len, tmp); // debug_dump_buf(tmp, buf->len); //} // TEST //Do frame transmission. Toggle the SLP_TR pin to initiate the frame transmission. hal_set_slptr_high(); hal_set_slptr_low(); // TODO: if we're in extended operating mode, check for ACK or NO_ACK return codes... return RADIO_SUCCESS; }
/** \brief This function will reset the state machine (to TRX_OFF) from any of * its states, except for the SLEEP state. */ void radio_reset_state_machine(void) { hal_set_slptr_low(); delay_us(TIME_NOCLK_TO_WAKE); hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF); delay_us(TIME_CMD_FORCE_TRX_OFF); }
/** * @brief Initializes the transceiver * * This function is called to initialize the transceiver. * * @return MAC_SUCCESS if the transceiver state is changed to TRX_OFF and the * current device part number and version number are correct; * FAILURE otherwise */ static uint8_t trx_init(void) { uint8_t trx_status; uint8_t poll_counter = 0; hal_set_rst_high(); hal_set_slptr_low(); /* Wait typical time of timer TR1. */ delay_us(P_ON_TO_CLKM_AVAILABLE_TYP_US); /* Apply reset pulse */ hal_set_rst_low(); delay_us(RST_PULSE_WIDTH_US); hal_set_rst_high(); /* Verify that TRX_OFF can be written */ do { /* Wait not more than max. value of TR1. */ if (poll_counter == P_ON_TO_CLKM_ATTEMPTS) { return(-1/* FAILURE*/); } /* Wait a short time interval. */ delay_us(TRX_POLL_WAIT_TIME_US); poll_counter++; /* Check if AT86RF231 is connected; omit manufacturer id check */ } while ((hal_register_read(RG_VERSION_NUM) != AT86RF231_VERSION_NUM) || (hal_register_read(RG_PART_NUM) != AT86RF231_PART_NUM)); /* Verify that TRX_OFF can be written */ hal_register_write(RG_TRX_STATE, CMD_TRX_OFF); /* Verify that the trx has reached TRX_OFF. */ poll_counter = 0; do { /* Wait a short time interval. */ delay_us(TRX_POLL_WAIT_TIME_US); trx_status = (uint8_t)hal_subregister_read(SR_TRX_STATUS); /* Wait not more than max. value of TR2. */ if (poll_counter == SLEEP_TO_TRX_OFF_ATTEMPTS) { return(-1/* FAILURE*/); } poll_counter++; } while (trx_status != TRX_OFF); tal_trx_status = TRX_OFF; 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 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(); }
void hal_init(void) { int i; uint32_t volatile dummy; RCC->AHBENR |= RCC_AHBENR_GPIOAEN; RCC->APB2ENR |= (RCC_APB2ENR_SPI1EN); RCC->APB1ENR |= (RCC_APB1ENR_SPI2EN); /* Configure I/O */ #if (RF230_BUS == 1) /* SPI: MISO; MOSI and CLK */ gpio_conf_af(GPIOA, 5, GPIO_OUTPUT_TYPE_PPULL, GPIO_OSPEED_40MHZ, GPIO_RESISTORS_PULLDN); gpio_conf_af(GPIOA, 6, GPIO_OUTPUT_TYPE_PPULL, GPIO_OSPEED_40MHZ, GPIO_RESISTORS_PULLDN); gpio_conf_af(GPIOA, 7, GPIO_OUTPUT_TYPE_PPULL, GPIO_OSPEED_40MHZ, GPIO_RESISTORS_PULLDN); gpio_map_af(GPIOA, 5, GPIO_AF_SPI1); gpio_map_af(GPIOA, 6, GPIO_AF_SPI1); gpio_map_af(GPIOA, 7, GPIO_AF_SPI1); /* Manual CS */ gpio_conf_output(GPIOA, 4, GPIO_OUTPUT_TYPE_PPULL, GPIO_OSPEED_40MHZ); gpio_set_resistors(GPIOA, 4, GPIO_RESISTORS_PULLUP); /* Reset */ gpio_conf_output(GPIOA, 8, GPIO_OUTPUT_TYPE_PPULL, GPIO_OSPEED_40MHZ); /* Sleep */ gpio_conf_output(GPIOA, 10, GPIO_OUTPUT_TYPE_PPULL, GPIO_OSPEED_40MHZ); #if 0 /* printf("Initiating GPIO for radio\r\n"); */ /* CS */ GPIO_CONF_OUTPUT_PORT(A, 4, PUSH_PULL, 50); /* CLOCK */ GPIO_CONF_OUTPUT_PORT(A, 5, ALT_PUSH_PULL, 50); /* MISO */ GPIO_CONF_OUTPUT_PORT(A, 6, ALT_PUSH_PULL, 50); /* MOSI */ GPIO_CONF_OUTPUT_PORT(A, 7, ALT_PUSH_PULL, 50); /* Reset */ GPIO_CONF_OUTPUT_PORT(A, 8, PUSH_PULL, 50); /* Sleep */ GPIO_CONF_OUTPUT_PORT(A, 10, PUSH_PULL, 50); /* Set up interrupt pin from radio */ /* PA11 -> EXTI11, PA -> set EXTICR to 0 */ AFIO->EXTICR[2] &= 0x0FfF; /* Enable clock to peripheral IOPA */ RCC->APB2ENR |= (RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN); /* Configure IRQ pin as input */ GPIO_CONF_INPUT_PORT(A, 11, FLOATING); /* Unmask interrupt for interrupt line */ EXTI->IMR |= (1 << RADIO_IRQ_PIN); /* Unmask event for interrupt line */ EXTI->EMR |= (1 << RADIO_IRQ_PIN); /* Rising edge trigger */ EXTI->RTSR |= (1 << RADIO_IRQ_PIN); /* Falling edge trigger */ /* EXTI->FTSR |= (1 << RADIO_IRQ_PIN); */ dummy = EXTI->PR; NVIC->ISER[1] |= (1 << (EXTI15_10_IRQChannel & 0x1F)); #endif #else /* CS */ GPIO_CONF_OUTPUT_PORT(B, 12, PUSH_PULL, 50); /* CLOCK */ GPIO_CONF_OUTPUT_PORT(B, 13, ALT_PUSH_PULL, 50); /* MISO */ GPIO_CONF_OUTPUT_PORT(B, 14, ALT_PUSH_PULL, 50); /* MOSI */ GPIO_CONF_OUTPUT_PORT(B, 15, ALT_PUSH_PULL, 50); /* Reset */ GPIO_CONF_OUTPUT_PORT(B, 10, PUSH_PULL, 50); /* Sleep */ GPIO_CONF_OUTPUT_PORT(B, 11, PUSH_PULL, 50); /* Set up interrupt pin from radio */ /* PC11 -> EXTI11, PC -> set EXTICR bits to 2 */ AFIO->EXTICR[2] &= 0xFF0F; AFIO->EXTICR[2] |= 0x0020; /* Enable clock to peripheral IOPC */ RCC->APB2ENR |= (RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPCEN); /* Configure IRQ pin as input */ GPIO_CONF_INPUT_PORT(C, 9, FLOATING); /* Unmask interrupt for line 9 */ EXTI->IMR |= (1 << RADIO_IRQ_PIN); /* Unmask event for line 9 */ EXTI->EMR |= (1 << RADIO_IRQ_PIN); /* Rising edge trigger */ EXTI->RTSR |= (1 << RADIO_IRQ_PIN); /* Falling edge trigger */ /* EXTI->FTSR |= (1 << RADIO_IRQ_PIN); */ dummy = EXTI->PR; NVIC->ISER[0] |= (1 << (EXTI9_5_IRQChannel & 0x1F)); #endif /* Assert reset */ hal_set_rst_low(); /* slptr */ hal_set_slptr_low(); /* Don't do like this...*/ for(i=0; i<100000; i++) ; /* Init SPI */ uspi_init(RF230_SPI_BUS, 000); /* No chip select */ spi_radio_cs(1); /* De-assert reset */ hal_set_rst_high(); }