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; } }
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; }
/** * 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; }
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; }
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); }