/** * @brief Handle incoming packets */ static void search_callback(uint8_t* data) { SET_PIN(PIN_RX); uint32_t checksum = (NRF_RADIO->RXCRC & 0x00FFFFFF); /* check if timeslot is about to end */ uint64_t radio_time_left = timeslot_get_remaining_time(); if (radio_time_left > RADIO_SAFETY_TIMING_US) { /* setup next RX */ order_search(); } CLEAR_PIN(PIN_RX); if (data == NULL || !packet_is_data_packet(data)) { return; } async_event_t async_evt; async_evt.type = EVENT_TYPE_PACKET; packet_create_from_data(data, &async_evt.callback.packet); async_evt.callback.packet.rx_crc = checksum; event_handler_push(&async_evt); /** @TODO: add packet chain handling */ }
void transport_control_step(void) { uint64_t next_time; uint64_t time_now = timer_get_timestamp() + global_time; trickle_time_update(time_now); uint32_t error_code = mesh_srv_get_next_processing_time(&next_time); if (error_code != NRF_SUCCESS) { return; } if (next_time < time_now) { async_event_t async_evt; async_evt.callback.generic = trickle_step_callback; async_evt.type = EVENT_TYPE_GENERIC; event_handler_push(&async_evt); } else { if (next_time < global_time + timeslot_get_end_time()) { timer_abort(step_timer_index); step_timer_index = timer_order_cb(next_time - global_time, trickle_step_callback); } } }
void game_init() { // background placeholder jet_type_init(&bg, "background", 0, 0); jet_type_set_grid_sheet(&bg, jet_texture_load_file("bgtest.tga"), 320, 240, 1); jet_type_set_sprite(&bg, 0); jet_spawn(&bg, jet_point_zero()); tiles = jet_texture_load_file("tiles.tga"); // background tiles jet_type_init(&bg_tiles, "background", 0, 0); jet_type_set_grid_sheet(&bg_tiles, tiles, 16, 16, 3); jet_type_set_sprite(&bg_tiles, 11); for(int off = 0; off < 2; ++off) for(int i = 1; i < 8; ++i) for(int j = 1; j < 13; ++j) jet_spawn(&bg_tiles, jet_point_xy(off*176 + i*16,j*16)); // player entity (/entities later) jet_type_init(&dudes, "player", 0, 0); jet_type_set_grid_sheet(&dudes, tiles, 16, 16, 3); jet_type_set_sprite(&dudes, 5); player = jet_spawn(&dudes, jet_point_xy(4*16,8*16)); // bombs! jet_type_init(&bombs, "bomb", sizeof(u8), 0); jet_type_set_grid_sheet(&bombs, tiles, 16, 16, 3); jet_type_set_sprite(&bombs, 2); jet_type_set_update(&bombs, bomb_update); // event handler event_handler_init(&mrbomber_handler, &mrbomber_event); event_handler_push(&mrbomber_handler); }
static bool send_end_evt(void) { if (m_operation_count == 0 || m_curr_op.type == FLASH_OP_TYPE_NONE) { return true; /* no events to send */ } async_event_t end_evt; end_evt.type = EVENT_TYPE_GENERIC; if (m_curr_op.type == FLASH_OP_TYPE_ERASE) { end_evt.callback.generic.cb = erase_operation_ended; end_evt.callback.generic.p_context = (void*) m_op_addr; } else { end_evt.callback.generic.cb = write_operation_ended; end_evt.callback.generic.p_context = (void*) m_op_addr; } if (event_handler_push(&end_evt) != NRF_SUCCESS) { return false; } 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; } }
uint32_t handle_storage_flag_set_async(uint16_t handle, handle_flag_t flag, bool value) { async_event_t evt; evt.type = EVENT_TYPE_SET_FLAG; evt.callback.set_flag.handle = handle; evt.callback.set_flag.flag = flag; evt.callback.set_flag.value = value; return event_handler_push(&evt); }
uint32_t handle_storage_local_packet_push(mesh_packet_t* p_packet) { if (p_packet == NULL) { return NRF_ERROR_NULL; } async_event_t evt; evt.type = EVENT_TYPE_GENERIC; evt.callback.generic.p_context = p_packet; evt.callback.generic.cb = local_packet_push; uint32_t error_code = event_handler_push(&evt); if (error_code == NRF_SUCCESS) { mesh_packet_ref_count_inc(p_packet); } return error_code; }
/** @brief Put a do_transmit call up for asynchronous processing */ static void schedule_transmit(void) { if (!m_suspend && m_serial_state != SERIAL_STATE_TRANSMIT) { m_serial_state = SERIAL_STATE_TRANSMIT; #ifdef BOOTLOADER NVIC_SetPendingIRQ(SWI1_IRQn); #else async_event_t evt; evt.type = EVENT_TYPE_GENERIC; evt.callback.generic.cb = do_transmit; evt.callback.generic.p_context = NULL; if (event_handler_push(&evt) != NRF_SUCCESS) { m_serial_state = SERIAL_STATE_IDLE; } #endif } }
/* radio callback, executed in STACK_LOW */ static void rx_cb(uint8_t* data, bool success, uint32_t crc) { if (success) { async_event_t evt; evt.type = EVENT_TYPE_PACKET; evt.callback.packet.payload = data; evt.callback.packet.crc = crc; evt.callback.packet.timestamp = timer_get_timestamp(); mesh_packet_ref_count_inc((mesh_packet_t*) data); /* event handler has a ref */ if (event_handler_push(&evt) != NRF_SUCCESS) { g_state.queue_saturation = true; mesh_packet_ref_count_dec((mesh_packet_t*) data); /* event handler lost its ref */ } } /* no longer needed in this context */ mesh_packet_ref_count_dec((mesh_packet_t*) data); }
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; } }