bool serial_handler_event_send(serial_evt_t* evt)
{
    if (fifo_is_full(&tx_fifo))
    {
        return false;
    }

    enable_pin_listener(false);
    NVIC_DisableIRQ(SPI1_TWI1_IRQn); /* critical section */

    serial_data_t raw_data;
    raw_data.status_byte = 0;
    memcpy(raw_data.buffer, evt, evt->length + 1);
    fifo_push(&tx_fifo, &raw_data);

    if (fifo_is_full(&rx_fifo))
    {
        enable_pin_listener(true);
        serial_state = SERIAL_STATE_WAIT_FOR_QUEUE;
    }
    else if (serial_state == SERIAL_STATE_IDLE)
    {
        do_transmit();
    }

    NVIC_EnableIRQ(SPI1_TWI1_IRQn); /* critical section complete */
    return true;
}
/**
* @brief SPI event handler, from SPI driver
*/
void spi_event_handler(spi_slave_evt_t evt)
{
    switch (evt.evt_type)
    {
        case SPI_SLAVE_BUFFERS_SET_DONE:
            if (has_pending_tx)
            {
                NRF_GPIO->OUTCLR = (1 << PIN_RDYN);
            }
            has_pending_tx = false;
            break;

        case SPI_SLAVE_XFER_DONE:
            NRF_GPIO->OUTSET = (1 << PIN_RDYN);
            nrf_gpio_pin_set(1);
            nrf_gpio_pin_clear(1);
            /* handle incoming */
            if (rx_buffer.buffer[SERIAL_LENGTH_POS] > 0)
            {
                if (fifo_push(&rx_fifo, &rx_buffer) == NRF_SUCCESS)
                {

                    /* notify ACI handler */
                    async_event_t async_evt;
                    async_evt.callback.generic = mesh_aci_command_check;
                    async_evt.type = EVENT_TYPE_GENERIC;
                    event_handler_push(&async_evt);
                }
                else
                {
                    APP_ERROR_CHECK(NRF_ERROR_NO_MEM);
                }
            }

            if (fifo_is_empty(&tx_fifo))
            {
                serial_state = SERIAL_STATE_IDLE;
                prepare_rx();
                enable_pin_listener(true);
            }
            else if (fifo_is_full(&rx_fifo))
            {
                prepare_rx();
                serial_state = SERIAL_STATE_WAIT_FOR_QUEUE;
            }
            else
            {
                do_transmit();
            }

            break;

        default:
            /* no implementation necessary */
            break;
    }
}
示例#3
0
文件: fifo.c 项目: vyacht/stm32
int fifo_put(fifo_t * fifo, uint8_t val)
{
    int ret;
    ret = !fifo_is_full(fifo);
    if (ret) {
        fifo->data[fifo->in & fifo->mask] = val;
        smp_wmb();
        fifo->in++;
    }
    return ret;
}
示例#4
0
文件: fifo.c 项目: jsr38/psu-firmware
/**
 * Add element to fifo. If fifo is full, return FALSE.
 * @param fifo
 * @param value
 * @return
 */
scpi_bool_t fifo_add(scpi_fifo_t * fifo, int16_t value) {
    /* FIFO full? */
    if (fifo_is_full(fifo)) {
        return FALSE;
    }

    fifo->data[fifo->wr] = value;
    fifo->wr = (fifo->wr + 1) % (fifo->size);

    return TRUE;
}
示例#5
0
文件: fifo.c 项目: Blackclaws/tinyusb
bool fifo_write(fifo_t* f, uint8_t data)
{
  if ( fifo_is_full(f) && f->overwritable == false)
      return false;

  mutex_lock(f);

  f->buf[f->wr_ptr] = data;
  f->wr_ptr = (f->wr_ptr + 1) % f->size;

  if (fifo_is_full(f))
  {
    f->rd_ptr = f->wr_ptr; // keep the full state (rd == wr && len = size)
  }else
  {
    f->len++;
  }

  mutex_unlock(f);

  return true;
}
bool serial_handler_event_send(serial_evt_t* evt)
{
    if (fifo_is_full(&m_tx_fifo))
    {
        return false;
    }

    serial_data_t raw_data;
    raw_data.status_byte = 0;
    memcpy(raw_data.buffer, evt, evt->length + 1);
    fifo_push(&m_tx_fifo, &raw_data);

    if (m_serial_state == SERIAL_STATE_IDLE)
    {
        schedule_transmit();
    }

    return true;
}
示例#7
0
static void ICACHE_FLASH_ATTR
add_to_sent_queue(at_linkConType *l, uint8_t *data, uint16_t length) {

	if (!fifo_is_full(msg_queue)) {

		my_send_queue_item_t *i = (my_send_queue_item_t *) os_zalloc(sizeof(my_send_queue_item_t));

		uint16_t j = 0;
		i->data = (uint8_t *) os_zalloc(length);
		i->l = l;
		i->length = length;

		for (j = 0; j < length; ++j)
			*(i->data + j) = *(data + j);

		fifo_push(msg_queue, i);

	}

}
static void char_rx(uint8_t c)
{
    static serial_data_t rx_buf = {0};
    static uint8_t* pp = rx_buf.buffer;

    *(pp++) = c;

    uint32_t len = (uint32_t)(pp - rx_buf.buffer);
    if (len >= sizeof(rx_buf) || (len > 1 && len >= rx_buf.buffer[0] + 1)) /* end of command */
    {
        if (fifo_push(&m_rx_fifo, &rx_buf) != NRF_SUCCESS)
        {
            /* respond inline, queue was full */
            serial_evt_t fail_evt;
            fail_evt.length = 3;
            fail_evt.opcode = SERIAL_EVT_OPCODE_CMD_RSP;
            fail_evt.params.cmd_rsp.command_opcode = ((serial_cmd_t*) rx_buf.buffer)->opcode;
            fail_evt.params.cmd_rsp.status = ACI_STATUS_ERROR_BUSY;
            serial_handler_event_send(&fail_evt);
        }
        else
        {
#ifdef BOOTLOADER
            NVIC_SetPendingIRQ(SWI2_IRQn);
#else
            async_event_t async_evt;
            async_evt.type = EVENT_TYPE_GENERIC;
            async_evt.callback.generic.cb = mesh_aci_command_check_cb;
            async_evt.callback.generic.p_context = NULL;
            event_handler_push(&async_evt);
#endif
        }

        if (fifo_is_full(&m_rx_fifo))
        {
            m_serial_state = SERIAL_STATE_WAIT_FOR_QUEUE;
            NRF_UART0->TASKS_STOPRX = 1;
        }
        pp = rx_buf.buffer;
    }
}
/**
* @brief IRQ handler for treating incoming SPI message. The master will not
*   start sending before we lower the RDYN pin.
*/
void GPIOTE_IRQHandler(void)
{
    NRF_GPIO->OUTSET = (1 << 2);
    if (NRF_GPIOTE->EVENTS_IN[SERIAL_REQN_GPIOTE_CH] && serial_state == SERIAL_STATE_IDLE)
    {
        
        NRF_GPIO->OUTSET = (1 << 3);
        if (fifo_is_full(&rx_fifo))
        {
            /* wait until the application pops an event off the rx queue */
            serial_state = SERIAL_STATE_WAIT_FOR_QUEUE;
        }
        else
        {
            do_transmit();
        }
        NRF_GPIO->OUTCLR = (1 << 3);
    }
    NRF_GPIOTE->EVENTS_IN[SERIAL_REQN_GPIOTE_CH] = 0;
    NRF_GPIO->OUTCLR = (1 << 2);
}