static uint32_t frame_send() { uint32_t err_code; m_current_tx_frame_length = compute_current_frame_length(m_tx_packet_length, m_accumulated_tx_packet_length); if (m_current_tx_frame_length == SER_PHY_SPI_5W_MTU_SIZE) { m_current_tx_frame_length -= 1; //extra space for guard byte must be taken into account for MTU } m_tx_frame_buffer[0] = 0; //guard byte copy_buff(&(m_tx_frame_buffer[1]), &(m_p_tx_buffer[m_accumulated_tx_packet_length]), m_current_tx_frame_length); err_code = spi_slave_buffers_set(m_tx_frame_buffer, m_rx_frame_buffer, m_current_tx_frame_length + 1, m_current_tx_frame_length + 1); return err_code; }
static void ser_phy_switch_state(ser_phy_event_source_t evt_src) { uint32_t err_code = NRF_SUCCESS; static bool m_waitForReadyFlag = false; //local scheduling flag to defer RDY events switch (m_spi_master_state) { case SER_PHY_STATE_IDLE: if (evt_src == SER_PHY_EVT_GPIO_REQ) { m_waitForReadyFlag = false; if (m_slave_ready_flag) { m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; err_code = header_send(0); } else { m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY; } } else if (evt_src == SER_PHY_EVT_TX_API_CALL) { spi_master_raw_assert(mp_tx_buffer != NULL); //api event with tx_buffer == NULL has no sense m_waitForReadyFlag = false; if (m_slave_ready_flag) { m_spi_master_state = SER_PHY_STATE_TX_HEADER; err_code = header_send(m_tx_buf_len); } else { m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY; } } break; case SER_PHY_STATE_TX_WAIT_FOR_RDY: if (evt_src == SER_PHY_EVT_GPIO_RDY) { m_spi_master_state = SER_PHY_STATE_TX_HEADER; err_code = header_send(m_tx_buf_len); } break; case SER_PHY_STATE_RX_WAIT_FOR_RDY: if (evt_src == SER_PHY_EVT_GPIO_RDY) { m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; err_code = header_send(0); } break; case SER_PHY_STATE_TX_HEADER: if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) { m_tx_packet_length = m_tx_buf_len; m_accumulated_tx_packet_length = 0; if (m_slave_ready_flag) { m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD; err_code = frame_send(); } else { m_waitForReadyFlag = true; } } else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag) { m_waitForReadyFlag = false; m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD; err_code = frame_send(); } break; case SER_PHY_STATE_TX_PAYLOAD: if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) { if (m_accumulated_tx_packet_length < m_tx_packet_length) { if (m_slave_ready_flag) { err_code = frame_send(); } else { m_waitForReadyFlag = true; } } else { spi_master_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length); //Release TX buffer buffer_release(&mp_tx_buffer, &m_tx_buf_len); callback_packet_sent(); if ( m_slave_request_flag) { if (m_slave_ready_flag) { m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; err_code = header_send(0); } else { m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY; } } else { m_spi_master_state = SER_PHY_STATE_IDLE; //m_Tx_buffer is NULL - have to wait for API event } } } else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag ) { m_waitForReadyFlag = false; err_code = frame_send(); } break; case SER_PHY_STATE_TX_ZERO_HEADER: if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) { if (m_slave_ready_flag) { m_spi_master_state = SER_PHY_STATE_RX_HEADER; err_code = header_get(); } else { m_waitForReadyFlag = true; } } else if ( (evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag) { m_waitForReadyFlag = false; m_spi_master_state = SER_PHY_STATE_RX_HEADER; err_code = header_get(); } break; case SER_PHY_STATE_RX_HEADER: if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) { m_spi_master_state = SER_PHY_STATE_MEMORY_REQUEST; m_rx_buf_len = uint16_decode(&(m_len_buffer[1])); //skip guard when receiving m_rx_packet_length = m_rx_buf_len; callback_mem_request(); } break; case SER_PHY_STATE_MEMORY_REQUEST: if (evt_src == SER_PHY_EVT_RX_API_CALL) { m_accumulated_rx_packet_length = 0; if (m_slave_ready_flag) { m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD; err_code = frame_get(); } else { m_waitForReadyFlag = true; } } else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag) { m_waitForReadyFlag = false; m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD; err_code = frame_get(); } break; case SER_PHY_STATE_RX_PAYLOAD: if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) { if (mp_rx_buffer) { copy_buff(&(mp_rx_buffer[m_accumulated_rx_packet_length]), &(m_recv_buffer[1]), m_current_rx_packet_length - 1); //skip guard byte when receiving } m_accumulated_rx_packet_length += (m_current_rx_packet_length - 1); if (m_accumulated_rx_packet_length < m_rx_packet_length) { if (m_slave_ready_flag) { err_code = frame_get(); } else { m_waitForReadyFlag = true; } } else { spi_master_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length); if (mp_rx_buffer == NULL) { callback_packet_dropped(); } else { callback_packet_received(); } //Release RX buffer buffer_release(&mp_rx_buffer, &m_rx_buf_len); if ((mp_tx_buffer != NULL)) //mp_tx_buffer !=NULL, this means that API_EVT was scheduled { if (m_slave_ready_flag ) { err_code = header_send(m_tx_buf_len); m_spi_master_state = SER_PHY_STATE_TX_HEADER; } else { m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY; } } else if (m_slave_request_flag) { if (m_slave_ready_flag) { m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; err_code = header_send(0); } else { m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY; } } else { m_spi_master_state = SER_PHY_STATE_IDLE; } } } else if ( evt_src == SER_PHY_EVT_GPIO_RDY && m_waitForReadyFlag) { m_waitForReadyFlag = false; err_code = frame_get(); } break; default: break; } if (err_code != NRF_SUCCESS) { (void)err_code; } }