/** * @brief Timer handling services * * This Function performs timer handling services. * It calls functions which are responsible * 1) to put the expired timer into the expired timer queue, and * 2) to service expired timers and call the respective callback. */ void timer_service(void) { ENTER_CRITICAL_REGION(); internal_timer_handler(); LEAVE_CRITICAL_REGION(); /* * Process expired timers. * Call the callback functions of the expired timers in the order of their * expiry. */ { timer_expiry_cb_t callback; void *callback_param; uint8_t next_expired_timer; /* Expired timer if any will be processed here */ while (NO_TIMER != expired_timer_queue_head) { ENTER_CRITICAL_REGION(); next_expired_timer = timer_array[expired_timer_queue_head].next_timer_in_queue; /* Callback is stored */ callback = (timer_expiry_cb_t)timer_array[expired_timer_queue_head].timer_cb; /* Callback parameter is stored */ callback_param = timer_array[expired_timer_queue_head].param_cb; /* * The expired timer's structure elements are updated and the timer * is taken out of expired timer queue */ timer_array[expired_timer_queue_head].next_timer_in_queue = NO_TIMER; timer_array[expired_timer_queue_head].timer_cb = NULL; timer_array[expired_timer_queue_head].param_cb = NULL; /* * The expired timer queue head is updated with the next timer in the * expired timer queue. */ expired_timer_queue_head = next_expired_timer; if (NO_TIMER == expired_timer_queue_head) { expired_timer_queue_tail = NO_TIMER; } LEAVE_CRITICAL_REGION(); if (NULL != callback) { /* Callback function is called */ callback(callback_param); } } } }
/** * @brief Timer handling services * * This Function performs timer handling services. * It calls functions which are responsible * 1) to put the expired timer into the expired timer queue, and * 2) to service expired timers and call the respective callback. */ void timer_service(void) { /*Check if any timer has expired. */ ENTER_CRITICAL_REGION(); internal_timer_handler(); LEAVE_CRITICAL_REGION(); /* * Process expired timers. * Call the callback functions of the expired timers in the order of their * expiry. */ timer_expiry_cb_t callback; void *callback_param; uint8_t next_expired_timer; /* Expired timer if any will be processed here */ while (NO_TIMER != expired_timer_queue_head) { /*Saving the current interrupt status & disabling the global interrupt */ ENTER_CRITICAL_REGION(); next_expired_timer = timer_array[expired_timer_queue_head].next_timer_in_queue; /*Callback is stored */ callback = (timer_expiry_cb_t)timer_array[expired_timer_queue_head].timer_cb; /*Callback parameter is stored */ callback_param = timer_array[expired_timer_queue_head].param_cb; /* * The expired timer's structure elements are updated and the timer * is taken out of expired timer queue */ timer_array[expired_timer_queue_head].next_timer_in_queue = NO_TIMER; timer_array[expired_timer_queue_head].timer_cb = NULL; timer_array[expired_timer_queue_head].param_cb = NULL; /* * Expired timer queue head is updated to point to next timer in the * expired timer queue */ expired_timer_queue_head = next_expired_timer; if (NO_TIMER == expired_timer_queue_head) { expired_timer_queue_tail = NO_TIMER; } /*Restoring the interrupt status which was stored & enabling the global interrupt */ LEAVE_CRITICAL_REGION(); if (NULL != callback) { /*Callback function is called */ callback(callback_param); } } }
/** * @brief Initialize the system clock * * This function sets the system clock by enabling the internal RC oscillator * with the proper prescaler (if available). * Ensure that CKDIV8 fuse does not affect the system clock prescaler. * */ static void mcu_clock_init(void) { /* * This is only allowed if the AVR 8-bit MCU already has a clock prescaler. * For older devices this function does not make sense. * Therefore the existence of register CLKPR is checked. */ //#ifdef CLKPR /* Is clock prescaler existing? */ #if (F_CPU == (8000000UL)) #ifdef __ICCAVR__ ENTER_CRITICAL_REGION(); CLKPR = 0x80; CLKPR = 0x00; LEAVE_CRITICAL_REGION(); #else clock_prescale_set(clock_div_1); #endif /* __ICCAVR__ */ #endif /* (F_CPU == (8000000UL) */ #if (F_CPU == (4000000UL)) #ifdef __ICCAVR__ ENTER_CRITICAL_REGION(); CLKPR = 0x80; CLKPR = 0x01; LEAVE_CRITICAL_REGION(); #else clock_prescale_set(clock_div_2); #endif /* __ICCAVR__ */ #endif /* (F_CPU == (4000000UL) */ #if (F_CPU == (2000000UL)) #ifdef __ICCAVR__ ENTER_CRITICAL_REGION(); CLKPR = 0x80; CLKPR = 0x02; LEAVE_CRITICAL_REGION(); #else clock_prescale_set(clock_div_4); #endif /* __ICCAVR__ */ #endif /* (F_CPU == (2000000UL) */ #if (F_CPU == (1000000UL)) #ifdef __ICCAVR__ ENTER_CRITICAL_REGION(); CLKPR = 0x80; CLKPR = 0x03; LEAVE_CRITICAL_REGION(); #else clock_prescale_set(clock_div_8); #endif /* __ICCAVR__ */ #endif /* (F_CPU == (1000000UL) */ //#endif /* CLKPR */ }
ADI_ETHER_BUFFER *EtherRecv ( ADI_ETHER_HANDLE const hDevice ) { ADI_ETHER_BUFFER *pack = NULL; int nSelectedDev = 0; if ( hDevice == g_hDev[0] ) { nSelectedDev = 0; } else if( hDevice == g_hDev[1] ) { nSelectedDev = 1; } else { DEBUG_STATEMENT ( " EtherRecv: Can not find the hDev \n\n" ); return NULL; } //一次返回一个 ENTER_CRITICAL_REGION(); DeQueue ( &user_net_config_info[nSelectedDev].rx_completed_q, ( QElem * ) &pack ) ; EXIT_CRITICAL_REGION(); return pack; }
/** * @brief Stops a high priority timer * * This function stops a high priority timer. * * @param timer_id Timer identifier * * @return * - @ref PAL_TMR_NOT_RUNNING if the timer id does not match with the high priority * timer register, or * - @ref MAC_SUCCESS otherwise. */ retval_t pal_stop_high_priority_timer(uint8_t timer_id) { retval_t timer_stop_status = PAL_TMR_NOT_RUNNING; /*Saving the current interrupt status & disabling the global interrupt */ ENTER_CRITICAL_REGION(); if (timer_id == high_priority_timer_id) { /* Turn off timer2/channel1 Outpur compare interrupt */ HIGH_PRIORITY_TIMER_DISABLE_INT = DISABLE_ALL_TIMER_INTERRUPTS; /*Clear pending output compare matches */ HIGH_PRIORITY_TIMER_ENABLE_INT &= ~AVR32_TC_IER0_CPAS_MASK; timer_array[high_priority_timer_id].next_timer_in_queue = NO_TIMER; timer_array[high_priority_timer_id].timer_cb = NULL; high_priority_timer_id = NO_TIMER; timer_stop_status = MAC_SUCCESS; } /*Restoring the interrupt status which was stored & enabling the global interrupt */ LEAVE_CRITICAL_REGION(); return timer_stop_status; }
void rf230_frame_write_P(uint8_t length, PROGMEM_BYTE_ARRAY_T wr_buffer) { ENTER_CRITICAL_REGION(); RF230_SS_LOW(); /*SEND FRAME WRITE COMMAND AND FRAME LENGTH.*/ RF230_SPI_DATA_REG = RF230_TRX_CMD_FW; RF230_WAIT_FOR_SPI_TX_COMPLETE(); uint8_t dummy_read = RF230_SPI_DATA_REG; RF230_SPI_DATA_REG = length; RF230_WAIT_FOR_SPI_TX_COMPLETE(); dummy_read = RF230_SPI_DATA_REG; /*Download to the Frame Buffer. */ do { RF230_SPI_DATA_REG = PROGMEM_READ_BYTE(wr_buffer); wr_buffer++; --length; RF230_WAIT_FOR_SPI_TX_COMPLETE(); dummy_read = RF230_SPI_DATA_REG; } while (length != 0); RF230_SS_HIGH(); LEAVE_CRITICAL_REGION(); }
uint8_t rf230_register_read(uint8_t address) { /*Add the register read command to the register address. */ address |= RF230_TRX_CMD_RR; ENTER_CRITICAL_REGION(); RF230_SS_LOW(); /*Send Register address and read register content.*/ RF230_SPI_DATA_REG = address; RF230_WAIT_FOR_SPI_TX_COMPLETE(); address = RF230_SPI_DATA_REG; uint8_t register_value = 0; RF230_SPI_DATA_REG = register_value; RF230_WAIT_FOR_SPI_TX_COMPLETE(); register_value = RF230_SPI_DATA_REG; RF230_SS_HIGH(); LEAVE_CRITICAL_REGION(); return register_value; }
bool zigbee_init(uint64_t ieee_address) { /* Set local variables to initial value. */ ENTER_CRITICAL_REGION(); bool init_status = false; ndi = NULL; nji = NULL; nli = NULL; LEAVE_CRITICAL_REGION(); /* Reset internal variables. */ zigbee_nib_init(); zigbee_neighbor_table_init(); if(true != ieee802_15_4_init(ieee_address)) { } else { /* Initialize all necessary callbacks from the IEEE 802.15.4 MAC. */ ieee802_15_4_set_mcps_data_indication(mac_data_indication_callback); ieee802_15_4_set_mlme_associate_indication(mac_associate_indication_callback); ieee802_15_4_set_mlme_disassociate_indication(mac_disassociate_indication_callback); ieee802_15_4_set_mlme_orphan_indication(mac_orphan_indication_callback); ieee802_15_4_set_mlme_comm_status_indication(mac_comm_status_indication_callback); ZIGBEE_NWK_SET_STATE(NWK_IDLE); init_status = true; } // END: if(ieee802_15_4_init(ieee_address)) ... return init_status; }
/** * @brief Reads current value from a transceiver register * * This function reads the current value from a transceiver register. * * @param addr Specifies the address of the trx register from which * the data shall be read * * @return Value of the register read */ uint8_t pal_trx_reg_read(uint8_t addr) { uint8_t register_value; ENTER_CRITICAL_REGION(); /* Prepare the command byte */ addr |= READ_ACCESS_COMMAND; /* Start SPI transaction by pulling SEL low */ SS_LOW(); /* Send the write command byte */ SPI_WRITE(addr); /* * Done to clear the RDRF bit in the SPI status register, which will be set * as a result of reception of some data from the transceiver as a result * of SPI write operation done above. */ SPI_READ(register_value); /* Do dummy write for initiating SPI read */ SPI_WRITE(SPI_DUMMY_VALUE); /* Read the byte received */ SPI_READ(register_value); /* Stop the SPI transaction by setting SEL high */ SS_HIGH(); LEAVE_CRITICAL_REGION(); return register_value; }
/** * @brief Cleanup TAL * * @param trx_id Transceiver identifier */ static void cleanup_tal(trx_id_t trx_id) { /* Clear all running TAL timers. */ ENTER_CRITICAL_REGION(); stop_tal_timer(trx_id); LEAVE_CRITICAL_REGION(); /* Clear TAL Incoming Frame queue and free used buffers. */ while (tal_incoming_frame_queue[trx_id].size > 0) { buffer_t *frame = qmm_queue_remove( &tal_incoming_frame_queue[trx_id], NULL); if (NULL != frame) { bmm_buffer_free(frame); } } /* Get new TAL Rx buffer if necessary */ if (tal_rx_buffer[trx_id] == NULL) { tal_rx_buffer[trx_id] = bmm_buffer_alloc(LARGE_BUFFER_SIZE); } /* Handle buffer shortage */ if (tal_rx_buffer[trx_id] == NULL) { tal_buf_shortage[trx_id] = true; } else { tal_buf_shortage[trx_id] = false; } }
/*========================= IMPLEMENTATION =========================*/ int mbox_init(void) { // Init error flag bool init_error = false; // If allready initialized, deinitialize first if (mbox_initalized == true) { mbox_deinit(); } // Init mail box buffer pointer mbox_mail_buffer = NULL; // mbox_mail_numb_get() and mbox_mail_numb_create() needs interrupts enabled ENTER_CRITICAL_REGION(); sei(); // If "name number file" does not exist, create it if (mbox_mail_numb_get() == EOF) { if (mbox_mail_numb_create() == EOF) { init_error = true; } } // Restore interrupt state LEAVE_CRITICAL_REGION(); // Indicate successful initialization mbox_initalized = init_error ? false : true; // Return EOF on error return init_error ? EOF : 0; }
// Posts the given function pointer and data on the queue. // Returns 0 on success, returns -1 if there is no space // left in the queue. int tq_post(void (*funct)(void* ), void* data) { int usage; int ret_val = 0; int next_head; ENTER_CRITICAL_REGION(); next_head = tq_head + 1; if (next_head >= TASK_QUEUE_SIZE) next_head -= TASK_QUEUE_SIZE; if (next_head != tq_tail) { task_queue_buf[tq_head].funct = funct; task_queue_buf[tq_head].data = data; } else { ret_val = -1; } tq_head = next_head; //record max usage usage = buf_get_used(tq_head, tq_tail, TASK_QUEUE_SIZE); if (usage > max_task_queue_size) max_task_queue_size = usage; LEAVE_CRITICAL_REGION(); return ret_val; }
/* * This function is called when the USB transfer from the host to the * device is finished */ static void usb0_rx_complete_handler( unsigned int unused, unsigned char status, unsigned int received, unsigned int remaining) { uint8_t tail = usb_0_buffer.rx_buf_tail; uint8_t i = 0; ENTER_CRITICAL_REGION(); while (received--) { /* Count of bytes received through USB 0 channel is incremented. */ usb_0_buffer.rx_count++; usb_0_buffer.rx_buf[tail] = usb_0_rx_temp_buf[i]; i++; if ((USB_RX_BUF_MAX_SIZE - 1) == usb_0_buffer.rx_buf_tail) { /* Revert back to beginning of buffer after reaching end of buffer. */ usb_0_buffer.rx_buf_tail = 0; tail = 0; } else { usb_0_buffer.rx_buf_tail++; tail++; } } LEAVE_CRITICAL_REGION(); }
/*============================ IMPLEMENTATION ================================*/ void chip_init(void) { /* * Disable all modules except the 32-bit RTC to minimise power * consumption */ PR.PRGEN = PR_AES_bm | PR_EBI_bm | PR_EVSYS_bm | PR_DMA_bm; PR.PRPA = PR_ADC_bm | PR_AC_bm; PR.PRPB = PR_DAC_bm | PR_ADC_bm | PR_AC_bm; PR.PRPC = PR_TWI_bm | PR_USART0_bm | PR_USART1_bm | PR_SPI_bm | PR_HIRES_bm | PR_TC0_bm | PR_TC1_bm; PR.PRPD = PR_USART0_bm | PR_USART1_bm | PR_SPI_bm | PR_HIRES_bm | PR_TC0_bm | PR_TC1_bm; PR.PRPE = PR_TWI_bm | PR_USART0_bm | PR_HIRES_bm | PR_TC0_bm | PR_TC1_bm; PR.PRPF = PR_USART0_bm | PR_HIRES_bm | PR_TC0_bm; PORTA.DIR = 0x02; PORTA.OUTCLR = 0x02; /* Configure system clock to use 32 MHz internal RC oscillator */ OSC.CTRL |= OSC_RC32MEN_bm; ENTER_CRITICAL_REGION( ); CCP = 0xD8; CLK.PSCTRL = (uint8_t)CLK_PSADIV_1_gc | (uint8_t)CLK_PSBCDIV_1_1_gc; while ( (OSC.STATUS & OSC_RC32MRDY_bm) == 0 ); CCP = 0xD8; CLK.CTRL = CLK_SCLKSEL_RC32M_gc; LEAVE_CRITICAL_REGION(); /* Configure the interrupt system */ PMIC.CTRL |= PMIC_LOLVLEN_bm; }
/** \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 ) { uint8_t tmp; ENTER_CRITICAL_REGION(); /* Start SPI transaction by pulling SEL low */ hal_set_ss_low(); /* 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 !RF231_CONF_CHECKSUM length -= 2; #endif /* Send the command byte */ spi_readwrite(RF_SPI,HAL_TRX_CMD_FW); /* Length */ spi_readwrite(RF_SPI,length); do { tmp = *write_buffer++; spi_readwrite(RF_SPI, tmp); --length; } while (length > 0); /* Stop the SPI transaction by setting SEL high. */ hal_set_ss_high(); 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. * 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) { uint8_t dummy_rx_data; uint8_t phy_status; uint8_t frame_length; uint8_t *rx_data; ENTER_CRITICAL_REGION(); /* Start SPI transaction by pulling SEL low */ hal_set_ss_low(); /* Send the command byte */ phy_status = spi_readwrite(RF_SPI,HAL_TRX_CMD_FR); frame_length = spi_readwrite(RF_SPI,0); /*Check for correct frame length.*/ if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)){ rx_data = rx_frame->data; rx_frame->length = frame_length; do { *rx_data++ = spi_readwrite(RF_SPI,0); } while (--frame_length > 0); rx_frame->lqi = spi_readwrite(RF_SPI,0); rx_frame->crc = 1; } else { rx_frame->length = 0; rx_frame->lqi = 0; rx_frame->crc = 0; } /* Stop the SPI transaction by setting SEL high. */ hal_set_ss_high(); LEAVE_CRITICAL_REGION(); }
/** * @brief Starts high priority timer * * This function starts a high priority timer for the specified timeout. * * @param timer_id Timer identifier * @param timer_count Timeout in microseconds * @param timer_cb Callback handler invoked upon timer expiry * @param param_cb Argument for the callback handler * * @return * - @ref PAL_TMR_INVALID_ID if the identifier is undefined, * - @ref MAC_INVALID_PARAMETER if the callback function for this timer is NULL, * - @ref PAL_TMR_ALREADY_RUNNING if the timer is already running, or * - @ref MAC_SUCCESS if timer is started successfully. */ retval_t pal_start_high_priority_timer(uint8_t timer_id, uint16_t timer_count, FUNC_PTR timer_cb, void *param_cb) { uint32_t timer_ocr = INTIALIZE_TO_ZERO; if (TOTAL_NUMBER_OF_TIMERS <= timer_id) { return PAL_TMR_INVALID_ID; } if (NULL == timer_cb) { return MAC_INVALID_PARAMETER; } if (NULL != timer_array[timer_id].timer_cb) { /* * Irrespective of the type, the timer is already running if the * callback function of the corresponding timer index in the timer * array is not NULL. */ return PAL_TMR_ALREADY_RUNNING; } /* * A high priority timer can be started, as currently * there is no high priority timer running. */ { /*Saving the current interrupt status & disabling the global interrupt */ ENTER_CRITICAL_REGION(); high_priority_timer_id = timer_id; /* * The corresponding running timer queue's timer index is updated * with the new values. */ timer_array[timer_id].timer_cb = timer_cb; timer_array[timer_id].param_cb = param_cb; timer_array[timer_id].next_timer_in_queue = NO_TIMER; timer_ocr = timer_count; timer_array[timer_id].abs_exp_timer = timer_ocr; /* Program output compare match */ HIGH_PRIORITY_TIMER_COMP = timer_ocr; /*Clear pending output compare matches */ HIGH_PRIORITY_TIMER_DISABLE_INT = DISABLE_ALL_TIMER_INTERRUPTS; /* Enable output compare match interrupt */ HIGH_PRIORITY_TIMER_ENABLE_INT |= AVR32_TC_IER0_CPAS_MASK; /*Restoring the interrupt status which was stored & enabling the global interrupt */ LEAVE_CRITICAL_REGION(); } return MAC_SUCCESS; }
/** * @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 pal_trx_aes_wrrd(uint8_t addr, uint8_t *idata, uint8_t length) { uint8_t dummy_rx_data; uint8_t *odata; PAL_WAIT_500_NS(); ENTER_CRITICAL_REGION(); /* Start SPI transaction by pulling SEL low */ SS_LOW(); /* Send the command byte */ SPI_WRITE(TRX_CMD_SW); /* * Done to clear the RDRF bit in the SPI status register, which will be set * as a result of reception of some data from the transceiver as a result * of SPI write operation done above. */ SPI_READ(dummy_rx_data); /* Write SRAM start address, clear the RDRF bit */ SPI_WRITE(addr); SPI_READ(dummy_rx_data); /* Now transfer data */ odata = idata; /* Write data byte 0 - the obtained value in SPDR is meaningless */ SPI_WRITE(*idata++); SPI_READ(dummy_rx_data); /* * Done to avoid compiler warning about variable being not used after * setting. */ dummy_rx_data = dummy_rx_data; /* Process data bytes 1...length-1: write and read */ do { SPI_WRITE(*idata++); /* Upload the received byte in the user provided location */ SPI_READ(*odata++); } while (--length > 0); /* To get the last data byte, write some dummy byte */ SPI_WRITE(SPI_DUMMY_VALUE); SPI_READ(*odata); /* Stop the SPI transaction by setting SEL high */ SS_HIGH(); LEAVE_CRITICAL_REGION(); }
void qmm_queue_append(queue_t *q, buffer_t *buf) #endif /* ENABLE_QUEUE_CAPACITY */ { #ifdef ENABLE_QUEUE_CAPACITY retval_t status; #endif /* ENABLE_QUEUE_CAPACITY */ ENTER_CRITICAL_REGION(); #ifdef ENABLE_QUEUE_CAPACITY /* Check if queue is full */ if (q->size == q->capacity) { /* Buffer cannot be appended as queue is full */ status = QUEUE_FULL; } else #endif /* ENABLE_QUEUE_CAPACITY */ { /* Check whether queue is empty */ if (q->size == 0) { /* Add the buffer at the head */ q->head = buf; } else { /* Add the buffer at the end */ q->tail->next = buf; } /* Update the list */ q->tail = buf; /* Terminate the list */ buf->next = NULL; /* Update size */ q->size++; #if (DEBUG > 1) if (q->head == NULL) { ASSERT("Corrupted queue: Null pointer has been queued" == 0); } #endif #ifdef ENABLE_QUEUE_CAPACITY status = MAC_SUCCESS; #endif /* ENABLE_QUEUE_CAPACITY */ } LEAVE_CRITICAL_REGION(); #ifdef ENABLE_QUEUE_CAPACITY return (status); #endif }/* qmm_queue_append */
rf230_cb_handler_t rf230_get_callback_handler(void) { rf230_cb_handler_t handler = NULL; ENTER_CRITICAL_REGION(); handler = rf230_callback_handler; LEAVE_CRITICAL_REGION(); return handler; }
/** * @brief Reads frame buffer of the transceiver * * This function reads the frame buffer of the transceiver. * * @param[out] data Pointer to the location to store frame * @param[in] length Number of bytes to be read from the frame buffer. */ void pal_trx_frame_read(uint8_t *data, uint8_t length) { uint8_t dummy_rx_data; ENTER_CRITICAL_REGION(); /* Start SPI transaction by pulling SEL low */ SS_LOW(); /* Send the command byte */ SPI_WRITE(TRX_CMD_FR); /* * Done to clear the RDRF bit in the SPI status register, which will be set * as a result of reception of some data from the transceiver as a result * of SPI write operation done above. */ SPI_READ(dummy_rx_data); /* * Done to avoid compiler warning about variable being not used after * setting. */ dummy_rx_data = dummy_rx_data; #ifdef NODMA_SPI do { /* Do dummy write for initiating SPI read */ SPI_WRITE(SPI_DUMMY_VALUE); /* Upload the received byte in the user provided location */ SPI_READ(*data); data++; } while (--length > 0); #else /* Disable both read and write. */ SPI_USED->SPI_PTCR = SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS; memset(data, 0xFF, length); SPI_USED->SPI_RPR = SPI_USED->SPI_TPR = (uint32_t)data; SPI_USED->SPI_RCR = SPI_USED->SPI_TCR = length; /* Enable read and write. */ SPI_USED->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN; /* Wait for end of read */ while (SPI_USED->SPI_RCR); #endif SS_HIGH(); LEAVE_CRITICAL_REGION(); }
/****************************************************************************** * releases the DMA so that either transmit or receive can use it. *****************************************************************************/ void dma_relinquish() { ENTER_CRITICAL_REGION(); dev->m_dma_protect = 0; dev->m_dma_direction = DMA_NONE; // set destination config to 0 SET_VAL_SHORT((dev->DstStreamBaseAddr+OFFSET_CONFIG),(unsigned short)0x0); // set source config to 0 SET_VAL_SHORT((dev->SrcStreamBaseAddr+OFFSET_CONFIG),(unsigned short)0x0); EXIT_CRTICIAL_REGION(); }
void tal_tx_beacon(frame_info_t *tx_frame) { tal_trx_status_t trx_status; /* Set pointer to actual mpdu to be downloaded to the transceiver. */ uint8_t *tal_beacon_to_tx = tx_frame->mpdu; /* Avoid that the beacon is transmitted while other transmision is *on-going. */ if (tal_state == TAL_TX_AUTO) { Assert( "trying to transmit beacon while ongoing transmission" == 0); return; } /* Send the pre-created beacon frame to the transceiver. */ do { trx_status = set_trx_state(CMD_PLL_ON); #if (_DEBUG_ > 1) if (trx_status != PLL_ON) { Assert("PLL_ON failed for beacon transmission" == 0); } #endif } while (trx_status != PLL_ON); /* \TODO wait for talbeaconTxTime */ ENTER_CRITICAL_REGION(); /* prevent from buffer underrun */ /* Toggle the SLP_TR pin triggering transmission. */ TRX_SLP_TR_HIGH(); PAL_WAIT_65_NS(); TRX_SLP_TR_LOW(); /* * Send the frame to the transceiver. * Note: The PhyHeader is the first byte of the frame to * be sent to the transceiver and this contains the frame * length. * The actual length of the frame to be downloaded * (parameter two of trx_frame_write) * is * 1 octet frame length octet * + n octets frame (i.e. value of frame_tx[0]) * - 2 octets FCS */ trx_frame_write(tal_beacon_to_tx, tal_beacon_to_tx[0] - 1); tal_beacon_transmission = true; LEAVE_CRITICAL_REGION(); }
uint8_t mac_add_gts_info(uint8_t *frame_ptr) { uint8_t table_index; uint8_t update_octets_count = 0; uint8_t direction_mask = 0; mac_gts_spec_t mac_gts_spec; mac_gts_spec.GtsDescCount = 0; mac_gts_spec.Reserved = 0; ENTER_CRITICAL_REGION(); for (table_index = 0; table_index < MAX_GTS_ON_PANC; table_index++) { if (0 < mac_pan_gts_table[table_index].PersistenceCount) { frame_ptr--; *frame_ptr = (mac_pan_gts_table[table_index].GtsDesc. GtsLength << 4) | mac_pan_gts_table[table_index].GtsDesc .GtsStartingSlot; frame_ptr--; *frame_ptr = mac_pan_gts_table[table_index].DevShortAddr >> 8; /* * GTS * *List **/ frame_ptr--; *frame_ptr = mac_pan_gts_table[table_index].DevShortAddr; /* * GTS * *List **/ update_octets_count += 3; direction_mask <<= 1; if (GTS_RX_SLOT & mac_pan_gts_table[table_index].GtsDesc. GtsDirection) { direction_mask |= GTS_RX_SLOT; } mac_gts_spec.GtsDescCount++; --mac_pan_gts_table[table_index].PersistenceCount; } }
/****************************************************************************** * Trasfer num_bytes from source address to the destination address * *****************************************************************************/ void dma_initiate_transfer(unsigned long src_addr, unsigned long des_addr, unsigned long num_bytes,DMA_DIRECTION dir) { unsigned short dma_config_source; unsigned short dma_config_destination; unsigned short d0_x_modify, s0_x_modify; ENTER_CRITICAL_REGION(); if(dir == DMA_DIR_TX) { d0_x_modify = 0; // auto increment, same port. s0_x_modify = DMA_WORD_SIZE; } else { d0_x_modify = DMA_WORD_SIZE; s0_x_modify = 0; // auto inrement, same port. } // configure the source address register SET_VAL_ADDR((dev->SrcStreamBaseAddr+OFFSET_START_ADDR),src_addr); // configure number of bytes to send at the source end SET_VAL_SHORT((dev->SrcStreamBaseAddr+OFFSET_X_COUNT),(unsigned short)num_bytes); // configure modify at the source end SET_VAL_SHORT((dev->SrcStreamBaseAddr+OFFSET_X_MODIFY),(unsigned short)s0_x_modify); // configure destination address register //*pMDMA_D0_START_ADDR = (volatile void*)des_addr; // configure the source address register SET_VAL_ADDR((dev->DstStreamBaseAddr+OFFSET_START_ADDR),des_addr); //configure destination x_count register SET_VAL_SHORT((dev->DstStreamBaseAddr+OFFSET_X_COUNT),(unsigned short)num_bytes); // configure destiantion x_modify register SET_VAL_SHORT((dev->DstStreamBaseAddr+OFFSET_X_MODIFY),(unsigned short)d0_x_modify); // Configure source DMA config register, enable bit set, and transfer // size if 16 bits. // dma_config_source = (WDSIZE_16 | DMAEN); SET_VAL_SHORT((dev->SrcStreamBaseAddr+OFFSET_CONFIG),(unsigned short)dma_config_source); // Configure destination config register, enable DMA, transfer size 16 // bits and enable DMA completion interrupt // dma_config_destination = (DI_EN | WDSIZE_16 | DMAEN | WNR); // DMA transfer starts here. SET_VAL_SHORT((dev->DstStreamBaseAddr+OFFSET_CONFIG),(unsigned short)dma_config_destination); ssync(); EXIT_CRTICIAL_REGION(); }
/* * @brief Internal MAC soft reset function * * This function resets the MAC variables, stops all running timers and * initializes the PIBs. * * @param init_pib Boolean indicates whether PIB attributes shall be * initialized or not. */ static void mac_soft_reset(uint8_t init_pib) { reset_globals(); /* Set trx to PHY_TRX_OFF */ tal_rx_enable(PHY_TRX_OFF); ENTER_CRITICAL_REGION(); mac_timers_stop(); LEAVE_CRITICAL_REGION(); if (init_pib) { do_init_pib(); } }
void zigbee_deinit(void) { if (NWK_UNINITIALIZED == nwk_state) { return; } ieee802_15_4_deinit(); ENTER_CRITICAL_REGION(); ndi = NULL; nji = NULL; nli = NULL; LEAVE_CRITICAL_REGION(); nwk_state = NWK_UNINITIALIZED; }
/** * @brief Writes data into frame buffer of the transceiver * * This function writes data into the frame buffer of the transceiver * * @param[in] data Pointer to data to be written into frame buffer * @param[in] length Number of bytes to be written into frame buffer */ void pal_trx_frame_write(uint8_t *data, uint8_t length) { uint8_t command_data = TRX_CMD_FW ; ENTER_CRITICAL_REGION(); /* Start SPI transaction by pulling SEL low */ SS_LOW(); #ifdef NODMA_SPI /* Send the command byte */ SPI_WRITE(command_data); do { /* Upload the user data to transceiver data register */ SPI_WRITE(*data); data++; } while (--length > 0); #else /* DMA transfer for SAM3S */ /* Disable both read and write. */ SPI_USED->SPI_PTCR = SPI_PTCR_TXTDIS; /* Setup dma transfer including trx command byte */ SPI_USED->SPI_TPR = (uint32_t)&command_data; SPI_USED->SPI_TCR = (uint16_t)1; SPI_USED->SPI_TNPR = (uint32_t)data; SPI_USED->SPI_TNCR = (uint16_t)length; /* start transfer */ SPI_USED->SPI_PTCR = SPI_PTCR_TXTEN; /* Wait while transfer isnt finished */ while (!(SPI_USED->SPI_SR & SPI_SR_TXEMPTY) || !(SPI_USED->SPI_SR & SPI_SR_TXBUFE)); SPI_USED->SPI_PTCR = SPI_PTCR_TXTDIS; #endif /* Wait for end of write; send counter should not matter. */ /* Stop the SPI transaction by setting SEL high. */ SS_HIGH(); LEAVE_CRITICAL_REGION(); }
/** * @brief Writes data into SRAM of the transceiver * * This function writes data into the SRAM of the transceiver * * @param addr Start address in the SRAM for the write operation * @param data Pointer to the data to be written into SRAM * @param length Number of bytes to be written into SRAM */ void pal_trx_sram_write(uint8_t addr, uint8_t *data, uint8_t length) { ENTER_CRITICAL_REGION(); /* Start SPI transaction by pulling SEL low */ SS_LOW(); /* Send the command byte */ SPI_WRITE(TRX_CMD_SW); /* Send the address from which the write operation should start */ SPI_WRITE(addr); #ifdef NODMA_SPI do { /* Upload the user data to transceiver data register */ SPI_WRITE(*data); data++; } while (--length > 0); #else /* DMA transfer for SAM3S */ /* Disable both read and write. */ SPI_USED->SPI_PTCR = SPI_PTCR_TXTDIS; /* Setup dma transfer including trx command byte */ SPI_USED->SPI_TPR = (uint32_t)data; SPI_USED->SPI_TCR = (uint16_t)length; /* start transfer */ SPI_USED->SPI_PTCR = SPI_PTCR_TXTEN; /* Wait while transfer isnt finished */ while (!(SPI_USED->SPI_SR & SPI_SR_TXEMPTY) || !(SPI_USED->SPI_SR & SPI_SR_TXBUFE)); SPI_USED->SPI_PTCR = SPI_PTCR_TXTDIS; #endif /* Stop the SPI transaction by setting SEL high */ SS_HIGH(); LEAVE_CRITICAL_REGION(); }
/////////////CALL_BACK void External_PPS_Trigger_Callback ( ADI_GPIO_PIN_INTERRUPT const ePinInt, uint32_t const Data, void* pCBParam) { TimeInternal tmStart = {0,0}; ENTER_CRITICAL_REGION(); // SetFlexiblePPSOutput( (ADI_ETHER_HANDLE) pCBParam, PULSE_SINGLE,tmStart, 0x5F5E0ff, 0x2FAF07f); //reset the system time ResetSysTime( (ADI_ETHER_HANDLE) pCBParam ); EXIT_CRITICAL_REGION(); }