Esempio n. 1
0
/*
    Configures all the tx mechanisms in preparation for TX.
        This includes channel, whitening init, length fields, etc.
        Assumes that the payload is already laid out in RAM buffer.
*/
uint32_t ble_radio_tx(ble_t * ble_p){
    //TODO - check channel range
    //TODO - check payload length

    nrf_tx_buffer[0]        = ble_p->pdu_type & PDU_TYPE_MASK;
    if (ble_p->hw_addr_type == HW_ADDR_TYPE_RANDOM)
            nrf_tx_buffer[0] |= 0x40;

    nrf_tx_buffer[1]        = ble_p->payload_length;

    _wait_radio_disabled();

    NRF_RADIO->PACKETPTR    =   (uint32_t )&nrf_tx_buffer;

    _ble_radio_pre_init(ble_p);

    gpio_set(GPIO_LED1,0);
    NRF_RADIO->TASKS_TXEN       =   1;
    event_wait_timeout(&radio_end_evt, 10);  //todo, check for timeout and bomb. TODO- really need to make this tickless
    if ((ble_p->scannable) ) {
        // set up the receive
        ble_radio_start_rx(ble_p);


    }
    return 0;
}
Esempio n. 2
0
/*
 *  gracefully waits for radio to enter disabled state, which is the starting point for
 *      any radio activity when swtiching between rx and tx mode
 */
static inline uint32_t _wait_radio_disabled(void) {
    if (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {       // Only yield the thread if we need to
        NRF_RADIO->TASKS_DISABLE = 1;       // Just to be safe, hit the stop button
        event_wait_timeout(&radio_disabled_evt,10);
        return 0;
    }
    event_unsignal(&radio_disabled_evt); // Unsignal the event in case we had a race
    return 0;
}
Esempio n. 3
0
void ble_radio_start_rx(ble_t * ble_p){
    uint32_t d0, d1;
    _wait_radio_disabled();
    nrf_evt_timeout(&radio_end_evt,50);
    NRF_RADIO->PACKETPTR    =   (uint32_t)&nrf_rx_buffer;
    NRF_RADIO->TASKS_RXEN   =   1;
    uint32_t i = event_wait_timeout(&radio_end_evt,4000);

    if (NRF_RADIO->STATE == RADIO_STATE_STATE_Rx ) { //we didn't get anything
        NRF_RADIO->TASKS_DISABLE = 1;   // shut down radio
    } else {
        for (int i = 0 ; i < (nrf_rx_buffer[1]+2) ; i++) {
            printf("%02X ",nrf_rx_buffer[i]);
        }
        printf("\n");
    }
    return 0;

}
Esempio n. 4
0
/*
    ble_radio_scan_continuous - used for continuous scanning.
        return val = zero if packet received
        return val < 0 if due to timeout

    Uses double buffered rx buffers, returns with ble_p->payload pointing
    to the buffer, null if due to timeout.

    Will return, but radio immediately goes back into receive loop.
*/
uint32_t ble_radio_scan_continuous(ble_t * ble_p, lk_time_t timeout){
    uint32_t retval;
    if ((ble_p->state != BLE_SCANNING)) {
        printf("Initing scan mode\n");
        _wait_radio_disabled();
        _ble_radio_scan_init(ble_p);
        _ble_radio_pre_init(ble_p);
        NRF_RADIO->TASKS_RXEN = 1;
    }
    retval = event_wait_timeout(&radio_end_evt, timeout);
    if (retval != 0) {
        ble_p->payload = NULL;
        ble_p->payload_length = 0;
        _ble_radio_increment_rx_buffer();
        return -1;
    } else {
        _ble_get_current_rx_buffer(ble_p);
        _ble_radio_increment_rx_buffer();
        return 0;
    }
}
Esempio n. 5
0
File: eth.c Progetto: 0xBADCA7/lk
static int eth_rx_worker(void *arg)
{
    for (;;) {
#if 0
        status_t event_err = event_wait_timeout(&eth.rx_event, 1000);
        if (event_err == ERR_TIMED_OUT) {
            /* periodically poll the phys status register */
            /* XXX specific to DP83848 */
            uint32_t val;

            /* Read PHY_MISR */
            /* seems to take about 30 usecs */
            HAL_ETH_ReadPHYRegister(&eth.EthHandle, PHY_MISR, &val);

            /* Check whether the link interrupt has occurred or not */
            if (val & PHY_LINK_INTERRUPT) {
                /* Read PHY_SR*/
                HAL_ETH_ReadPHYRegister(&eth.EthHandle, PHY_SR, &val);

                /* Check whether the link is up or down*/
                if (val & PHY_LINK_STATUS) {
                    printf("eth: link up\n");
                    //netif_set_link_up(link_arg->netif);
                } else {
                    printf("eth: link down\n");
                    //netif_set_link_down(link_arg->netif);
                }
            }
        } else {
#else
        status_t event_err = event_wait(&eth.rx_event);
        if (event_err >= NO_ERROR) {
#endif
            // XXX probably race with the event here
            while (HAL_ETH_GetReceivedFrame_IT(&eth.EthHandle) == HAL_OK) {
                LTRACEF("got packet len %u, buffer %p, seg count %u\n", eth.EthHandle.RxFrameInfos.length,
                        (void *)eth.EthHandle.RxFrameInfos.buffer,
                        eth.EthHandle.RxFrameInfos.SegCount);

#if WITH_LIB_MINIP
                /* allocate a pktbuf header, point it at our rx buffer, and pass up the stack */
                pktbuf_t *p = pktbuf_alloc_empty();
                if (p) {
                    pktbuf_add_buffer(p, (void *)eth.EthHandle.RxFrameInfos.buffer, eth.EthHandle.RxFrameInfos.length,
                                      0, 0, NULL, NULL);
                    p->dlen = eth.EthHandle.RxFrameInfos.length;

                    minip_rx_driver_callback(p);

                    pktbuf_free(p, true);
                }
#endif

                /* Release descriptors to DMA */
                /* Point to first descriptor */
                __IO ETH_DMADescTypeDef *dmarxdesc;

                dmarxdesc = eth.EthHandle.RxFrameInfos.FSRxDesc;
                /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
                for (uint i=0; i< eth.EthHandle.RxFrameInfos.SegCount; i++) {
                    dmarxdesc->Status |= ETH_DMARXDESC_OWN;
                    dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
                }

                /* Clear Segment_Count */
                eth.EthHandle.RxFrameInfos.SegCount =0;

                /* When Rx Buffer unavailable flag is set: clear it and resume reception */
                if ((eth.EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET) {
                    /* Clear RBUS ETHERNET DMA flag */
                    eth.EthHandle.Instance->DMASR = ETH_DMASR_RBUS;
                    /* Resume DMA reception */
                    eth.EthHandle.Instance->DMARPDR = 0;
                }
            }
        }
    }

    return 0;
}

#if WITH_LIB_MINIP

status_t stm32_eth_send_minip_pkt(pktbuf_t *p)
{
    LTRACEF("p %p, dlen %zu, eof %u\n", p, p->dlen, p->flags & PKTBUF_FLAG_EOF);

    DEBUG_ASSERT(p && p->dlen);

    if (!(p->flags & PKTBUF_FLAG_EOF)) {
        /* can't handle multi part packets yet */
        PANIC_UNIMPLEMENTED;

        return ERR_NOT_IMPLEMENTED;
    }

    status_t err = eth_send(p->data, p->dlen);

    pktbuf_free(p, true);

    return err;
}
Esempio n. 6
0
/**
 * @brief  Same as event_wait_timeout(), but without a timeout.
 */
status_t event_wait(event_t *e)
{
	return event_wait_timeout(e, INFINITE_TIME);
}