bool aci_queue_peek_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data) { ble_assert(NULL != aci_q); ble_assert(NULL != p_data); if (aci_queue_is_empty_from_isr(aci_q)) { return false; } memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head % ACI_QUEUE_SIZE]), sizeof(hal_aci_data_t)); return true; }
/* Interrupt service routine called when the RDYN line goes low. Runs the SPI transfer. */ static void m_aci_isr(void) { hal_aci_data_t data_to_send; hal_aci_data_t received_data; // see guide from http://redbearlab.com/blend-low-power-settings/ #if defined(__AVR_ATmega32U4__) PRR0 = 0x00; // Power Reduction Register: open timer PRR1 = 0x00; #endif // Receive from queue if (!aci_queue_dequeue_from_isr(&aci_tx_q, &data_to_send)) { /* queue was empty, nothing to send */ data_to_send.status_byte = 0; data_to_send.buffer[0] = 0; } // Receive and/or transmit data m_aci_spi_transfer(&data_to_send, &received_data); if (!aci_queue_is_full_from_isr(&aci_rx_q) && !aci_queue_is_empty_from_isr(&aci_tx_q)) { m_aci_reqn_enable(); } // Check if we received data if (received_data.buffer[0] > 0) { if (!aci_queue_enqueue_from_isr(&aci_rx_q, &received_data)) { /* Receive Buffer full. Should never happen. Spin in a while loop. */ while(1); } // Disable ready line interrupt until we have room to store incoming messages if (aci_queue_is_full_from_isr(&aci_rx_q)) { detachInterrupt(a_pins_local_ptr->interrupt_number); } } return; }
/* Interrupt service routine called when the RDYN line goes low. Runs the SPI transfer. */ static void m_aci_isr(void) { hal_aci_data_t data_to_send; hal_aci_data_t received_data; // Receive from queue if (!aci_queue_dequeue_from_isr(&aci_tx_q, &data_to_send)) { /* queue was empty, nothing to send */ data_to_send.status_byte = 0; data_to_send.buffer[0] = 0; } // Receive and/or transmit data m_aci_spi_transfer(&data_to_send, &received_data); if (!aci_queue_is_full_from_isr(&aci_rx_q) && !aci_queue_is_empty_from_isr(&aci_tx_q)) { m_aci_reqn_enable(); } // Check if we received data if (received_data.buffer[0] > 0) { if (!aci_queue_enqueue_from_isr(&aci_rx_q, &received_data)) { /* Receive Buffer full. Should never happen. Spin in a while loop. */ while(1); } // Disable ready line interrupt until we have room to store incoming messages if (aci_queue_is_full_from_isr(&aci_rx_q)) { detachInterrupt(a_pins_local_ptr->interrupt_number); } } return; }