http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_slave.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_slave.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_slave.c deleted file mode 100644 index e091691..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_slave.c +++ /dev/null @@ -1,618 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - */ - -/**@file - * - * @defgroup ser_phy_spi_5W_phy_driver_slave ser_phy_nrf51_spi_5W_slave.c - * @{ - * @ingroup ser_phy_spi_5W_phy_driver_slave - * - * @brief SPI_5W_RAW PHY slave driver. - */ - - -#include <stddef.h> -#include <string.h> - - -#include "boards.h" -#include "nrf_drv_spis.h" -#include "ser_phy.h" -#include "ser_config.h" -#include "nrf_gpio.h" -#include "nrf_delay.h" -#include "nrf_gpiote.h" -#include "nrf_soc.h" -#include "app_error.h" -#include "app_util.h" -#include "ser_phy_config_conn_nrf51.h" -#include "ser_phy_debug_conn.h" -#include "app_error.h" - -#define _static static - -#define SER_PHY_SPI_5W_MTU_SIZE SER_PHY_SPI_MTU_SIZE - -#define SER_PHY_SPI_DEF_CHARACTER 0xFF //SPI default character. Character clocked out in case of an ignored transaction -#define SER_PHY_SPI_ORC_CHARACTER 0xFF //SPI over-read character. Character clocked out after an over-read of the transmit buffer - -static nrf_drv_spis_t m_spis = NRF_DRV_SPIS_INSTANCE(SER_PHY_SPI_SLAVE_INSTANCE); - -#define _SPI_5W_ - -//SPI raw peripheral device configuration data -typedef struct -{ - int32_t pin_req; //SPI /REQ pin. -1 for not using - int32_t pin_rdy; //SPI /RDY pin. -1 for not using - int32_t ppi_rdy_ch; //SPI /RDY ppi ready channel - int32_t gpiote_rdy_ch; //SPI /RDY pin ready channel -} spi_slave_raw_trasp_cfg_t; - -/**@brief States of the SPI transaction state machine. */ -typedef enum -{ - SPI_RAW_STATE_UNKNOWN, - SPI_RAW_STATE_SETUP_HEADER, - SPI_RAW_STATE_RX_HEADER, - SPI_RAW_STATE_MEM_REQUESTED, - SPI_RAW_STATE_RX_PAYLOAD, - SPI_RAW_STATE_TX_HEADER, - SPI_RAW_STATE_TX_PAYLOAD, -} trans_state_t; - -_static spi_slave_raw_trasp_cfg_t m_spi_slave_raw_config; - -_static uint16_t m_accumulated_rx_packet_length; -_static uint16_t m_rx_packet_length; -_static uint16_t m_current_rx_frame_length; - -_static uint16_t m_accumulated_tx_packet_length; -_static uint16_t m_tx_packet_length; -_static uint16_t m_current_tx_frame_length; - -_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE + 1]; //+1 for '0' guard in SPI_5W -_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE + 1]; //+1 for '0' guard in SPI_5W - -_static uint8_t m_tx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE]; -_static uint8_t m_rx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE]; -_static uint8_t m_zero_buff[SER_PHY_SPI_5W_MTU_SIZE] = { 0 }; //ROM'able declaration - all guard bytes - -_static uint8_t * volatile m_p_rx_buffer = NULL; -_static const uint8_t * volatile m_p_tx_buffer = NULL; - -_static bool m_trash_payload_flag; -_static bool m_buffer_reqested_flag; - -_static trans_state_t m_trans_state = SPI_RAW_STATE_UNKNOWN; -_static ser_phy_events_handler_t m_ser_phy_callback = NULL; - -static void spi_slave_raw_assert(bool cond) -{ - APP_ERROR_CHECK_BOOL(cond); -} - -static void callback_ser_phy_event(ser_phy_evt_t event) -{ - if (m_ser_phy_callback) - { - m_ser_phy_callback(event); - } - return; -} - -static void callback_memory_request(uint16_t size) -{ - ser_phy_evt_t event; - - event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; - event.evt_params.rx_buf_request.num_of_bytes = size; - callback_ser_phy_event(event); - return; - -} - -static void callback_packet_received(uint8_t * pBuffer, uint16_t size) -{ - ser_phy_evt_t event; - - event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; - event.evt_params.rx_pkt_received.num_of_bytes = size; - event.evt_params.rx_pkt_received.p_buffer = pBuffer; - callback_ser_phy_event(event); - return; -} - -static void callback_packet_dropped() -{ - ser_phy_evt_t event; - - event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; - callback_ser_phy_event(event); - return; -} - -static void callback_packet_transmitted(void) -{ - ser_phy_evt_t event; - - event.evt_type = SER_PHY_EVT_TX_PKT_SENT; - callback_ser_phy_event(event); - return; -} - -static void copy_buff(uint8_t * const p_dest, uint8_t const * const p_src, uint16_t len) -{ - uint16_t index; - - for (index = 0; index < len; index++) - { - p_dest[index] = p_src[index]; - } - return; -} - -/* Function computes current packet length */ -static uint16_t compute_current_frame_length(const uint16_t packet_length, - const uint16_t accumulated_packet_length) -{ - uint16_t current_packet_length = packet_length - accumulated_packet_length; - - if (current_packet_length > SER_PHY_SPI_5W_MTU_SIZE) - { - current_packet_length = SER_PHY_SPI_5W_MTU_SIZE; - } - - return current_packet_length; -} - -static uint32_t header_get() -{ - uint32_t err_code; - - err_code = nrf_drv_spis_buffers_set(&m_spis, - (uint8_t *) m_zero_buff, - SER_PHY_HEADER_SIZE, - m_header_rx_buffer, - SER_PHY_HEADER_SIZE); - return err_code; -} - -static uint32_t frame_get() -{ - uint32_t err_code; - - m_current_rx_frame_length = compute_current_frame_length(m_rx_packet_length, - m_accumulated_rx_packet_length); - - if (!m_trash_payload_flag) - { - err_code = - nrf_drv_spis_buffers_set(&m_spis, - (uint8_t *) m_zero_buff, - m_current_rx_frame_length, - &(m_p_rx_buffer[m_accumulated_rx_packet_length]), - m_current_rx_frame_length); - } - else - { - err_code = nrf_drv_spis_buffers_set(&m_spis, - (uint8_t *) m_zero_buff, - m_current_rx_frame_length, - m_rx_frame_buffer, - m_current_rx_frame_length); - } - return err_code; -} - -static uint32_t header_send(uint16_t len) -{ - uint32_t err_code; - - m_header_tx_buffer[0] = (uint8_t) 0; //this is guard byte - (void)uint16_encode(len, &(m_header_tx_buffer[1])); - err_code = nrf_drv_spis_buffers_set(&m_spis, - m_header_tx_buffer, - SER_PHY_HEADER_SIZE + 1, - m_header_rx_buffer, - SER_PHY_HEADER_SIZE + 1); - return err_code; -} - -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 = nrf_drv_spis_buffers_set(&m_spis, - m_tx_frame_buffer, - m_current_tx_frame_length + 1, - m_rx_frame_buffer, - m_current_tx_frame_length + 1); - - return err_code; -} - -static void set_ready_line(void) -{ -#ifndef _SPI_5W_ - //toggle - this should go high - but toggle is unsafe - uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.gpiote_rdy_ch); - *(uint32_t *)rdy_task = 1; -#endif - return; -} - -static void set_request_line(void) -{ - //active low logic - set is 0 - nrf_gpio_pin_clear(m_spi_slave_raw_config.pin_req); - DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0); - return; -} - -static void clear_request_line(void) -{ - //active low logic - clear is 1 - nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); - DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(0); - return; -} - -/** - * \brief Slave driver main state machine - * For UML graph, please refer to SDK documentation -*/ -static void spi_slave_event_handle(nrf_drv_spis_event_t event) -{ - static uint32_t err_code = NRF_SUCCESS; - static uint16_t packetLength; - - switch (m_trans_state) - { - case SPI_RAW_STATE_SETUP_HEADER: - m_trans_state = SPI_RAW_STATE_RX_HEADER; - err_code = header_get(); - break; - - case SPI_RAW_STATE_RX_HEADER: - - if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); - set_ready_line(); - } - - if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); - spi_slave_raw_assert(event.rx_amount == SER_PHY_HEADER_SIZE); - packetLength = uint16_decode(m_header_rx_buffer); - - if (packetLength != 0 ) - { - m_trans_state = SPI_RAW_STATE_MEM_REQUESTED; - m_buffer_reqested_flag = true; - m_rx_packet_length = packetLength; - callback_memory_request(packetLength); - } - else - { - if (m_p_tx_buffer) - { - clear_request_line(); - m_trans_state = SPI_RAW_STATE_TX_HEADER; - err_code = header_send(m_tx_packet_length); - } - else - { - //there is nothing to send - zero response facilitates pooling - but perhaps, it should be assert - err_code = header_send(0); - } - } - } - - break; - - case SPI_RAW_STATE_MEM_REQUESTED: - - if (event.evt_type == NRF_DRV_SPIS_EVT_TYPE_MAX) //This is API dummy event - { - m_buffer_reqested_flag = false; - m_trans_state = SPI_RAW_STATE_RX_PAYLOAD; - m_accumulated_rx_packet_length = 0; - err_code = frame_get(); - } - break; - - - case SPI_RAW_STATE_RX_PAYLOAD: - - if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); - set_ready_line(); - } - - if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); - spi_slave_raw_assert(event.rx_amount == m_current_rx_frame_length); - m_accumulated_rx_packet_length += m_current_rx_frame_length; - - if (m_accumulated_rx_packet_length < m_rx_packet_length ) - { - err_code = frame_get(); - } - else - { - spi_slave_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length); - m_trans_state = SPI_RAW_STATE_RX_HEADER; - err_code = header_get(); - - if (!m_trash_payload_flag) - { - callback_packet_received(m_p_rx_buffer, m_accumulated_rx_packet_length); - } - else - { - callback_packet_dropped(); - } - } - } - break; - - case SPI_RAW_STATE_TX_HEADER: - - if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); - set_ready_line(); - } - - if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); - spi_slave_raw_assert(event.tx_amount == SER_PHY_HEADER_SIZE + 1); - m_trans_state = SPI_RAW_STATE_TX_PAYLOAD; - m_accumulated_tx_packet_length = 0; - err_code = frame_send(); - } - - break; - - case SPI_RAW_STATE_TX_PAYLOAD: - - if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); - set_ready_line(); - } - - if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); - spi_slave_raw_assert(event.tx_amount == m_current_tx_frame_length + 1); - m_accumulated_tx_packet_length += m_current_tx_frame_length; - - if ( m_accumulated_tx_packet_length < m_tx_packet_length ) - { - err_code = frame_send(); - } - else - { - spi_slave_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length); - //clear pointer before callback - m_p_tx_buffer = NULL; - callback_packet_transmitted(); - //spi slave TX transfer is possible only when RX is ready, so return to waiting for a header - m_trans_state = SPI_RAW_STATE_RX_HEADER; - err_code = header_get(); - } - } - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - APP_ERROR_CHECK(err_code); -} - -#ifndef _SPI_5W_ -static void spi_slave_gpiote_init(void) -{ - if (!nrf_drv_gpiote_is_init()) - { - (void)nrf_drv_gpiote_init(); - } - nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true); - (void)nrf_drv_gpiote_out_init(m_spi_slave_raw_config.gpiote_rdy_ch, &config); - return; -} - -static void spi_slave_ppi_init(void) -{ - uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.gpiote_rdy_ch); - //Configure PPI channel to clear /RDY line - NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].EEP = (uint32_t)(&NRF_SPIS1->EVENTS_END); - NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].TEP = rdy_task; - - //this works only for channels 0..15 - but soft device is using 8-15 anyway - NRF_PPI->CHEN |= (1 << m_spi_slave_raw_config.ppi_rdy_ch); - return; -} -#endif - -static void spi_slave_gpio_init(void) -{ - nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req); - nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); -#ifndef _SPI_5W_ - nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy); - nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy); -#endif - return; -} - -/* ser_phy API function */ -void ser_phy_interrupts_enable(void) -{ - NVIC_EnableIRQ(m_spis.irq); -} - -/* ser_phy API function */ -void ser_phy_interrupts_disable(void) -{ - NVIC_DisableIRQ(m_spis.irq); -} - -/* ser_phy API function */ -uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) -{ - uint32_t status = NRF_SUCCESS; - nrf_drv_spis_event_t event; - - ser_phy_interrupts_disable(); - - if (m_buffer_reqested_flag && (m_trans_state == SPI_RAW_STATE_MEM_REQUESTED)) - { - m_p_rx_buffer = p_buffer; - - if (m_p_rx_buffer) - { - m_trash_payload_flag = false; - } - else - { - m_trash_payload_flag = true; - } - - event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition with dummy event - event.rx_amount = 0; - event.tx_amount = 0; - spi_slave_event_handle(event); - } - else - { - status = NRF_ERROR_BUSY; - } - ser_phy_interrupts_enable(); - - return status; -} - -/* ser_phy API function */ -uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) -{ - uint32_t status = NRF_SUCCESS; - - if ( p_buffer == NULL || num_of_bytes == 0) - { - return NRF_ERROR_NULL; - } - - ser_phy_interrupts_disable(); - - if ( m_p_tx_buffer == NULL) - { - m_tx_packet_length = num_of_bytes; - m_p_tx_buffer = p_buffer; - set_request_line(); - } - else - { - status = NRF_ERROR_BUSY; - } - ser_phy_interrupts_enable(); - - return status; -} - -/* ser_phy API function */ -uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) -{ - uint32_t err_code; - nrf_drv_spis_config_t spi_slave_config; - nrf_drv_spis_event_t event; - - if (m_trans_state != SPI_RAW_STATE_UNKNOWN) - { - return NRF_ERROR_INVALID_STATE; - } - - if (events_handler == NULL) - { - return NRF_ERROR_NULL; - } - - //one ppi channel and one gpiote channel are used to drive RDY line - m_spi_slave_raw_config.pin_req = SER_PHY_SPI_SLAVE_REQ_PIN; - m_spi_slave_raw_config.pin_rdy = SER_PHY_SPI_SLAVE_RDY_PIN; - m_spi_slave_raw_config.ppi_rdy_ch = SER_PHY_SPI_PPI_RDY_CH; - m_spi_slave_raw_config.gpiote_rdy_ch = SER_PHY_SPI_GPIOTE_RDY_CH; - - spi_slave_gpio_init(); -#ifndef _SPI_5W_ - spi_slave_gpiote_init(); - spi_slave_ppi_init(); -#endif - - spi_slave_config.miso_pin = SER_CON_SPIS_MISO_PIN; - spi_slave_config.mosi_pin = SER_CON_SPIS_MOSI_PIN; - spi_slave_config.sck_pin = SER_CON_SPIS_SCK_PIN; - spi_slave_config.csn_pin = SER_CON_SPIS_CSN_PIN; - spi_slave_config.mode = NRF_DRV_SPIS_MODE_0; - spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST; - spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER; - spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER; - spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP; - spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOW; - - //keep /CS high when init - nrf_gpio_cfg_input(spi_slave_config.csn_pin, NRF_GPIO_PIN_PULLUP); - - err_code = nrf_drv_spis_init(&m_spis, &spi_slave_config, spi_slave_event_handle); - APP_ERROR_CHECK(err_code); - - if (err_code == NRF_SUCCESS) - { - m_ser_phy_callback = events_handler; - - m_trans_state = SPI_RAW_STATE_SETUP_HEADER; - event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition for dummy event - event.rx_amount = 0; - event.tx_amount = 0; - spi_slave_event_handle(event); - - } - - return err_code; -} - -/* ser_phy API function */ -void ser_phy_close(void) -{ - nrf_drv_spis_uninit(&m_spis); - m_ser_phy_callback = NULL; - m_trans_state = SPI_RAW_STATE_UNKNOWN; -}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_slave.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_slave.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_slave.c deleted file mode 100644 index 21eaff7..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_slave.c +++ /dev/null @@ -1,580 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - */ - -/**@file - * - * @defgroup ser_phy_spi_phy_driver_slave ser_phy_nrf51_spi_slave.c - * @{ - * @ingroup ser_phy_spi_phy_driver_slave - * - * @brief SPI_RAW PHY slave driver. - */ - -#include <stddef.h> -#include <string.h> - -#include "app_error.h" -#include "app_util.h" -#include "boards.h" -#include "nrf_gpio.h" -#include "nrf_drv_gpiote.h" -#include "nrf_soc.h" -#include "nrf_drv_spis.h" -#include "ser_config.h" -#include "ser_phy.h" -#include "ser_phy_config_conn_nrf51.h" -#include "ser_phy_debug_conn.h" - -#define SER_PHY_SPI_DEF_CHARACTER 0xFF //SPI default character. Character clocked out in case of an ignored transaction -#define SER_PHY_SPI_ORC_CHARACTER 0xFF //SPI over-read character. Character clocked out after an over-read of the transmit buffer - -static nrf_drv_spis_t m_spis = NRF_DRV_SPIS_INSTANCE(SER_PHY_SPI_SLAVE_INSTANCE); - -//SPI raw peripheral device configuration data -typedef struct -{ - int32_t pin_req; //SPI /REQ pin. -1 for not using - int32_t pin_rdy; //SPI /RDY pin. -1 for not using - int32_t ppi_rdy_ch; //SPI /RDY ppi ready channel - int32_t gpiote_rdy_ch; //SPI /RDY pin ready channel -} spi_slave_raw_trasp_cfg_t; - -/**@brief States of the SPI transaction state machine. */ -typedef enum -{ - SPI_RAW_STATE_UNKNOWN, - SPI_RAW_STATE_SETUP_HEADER, - SPI_RAW_STATE_RX_HEADER, - SPI_RAW_STATE_MEM_REQUESTED, - SPI_RAW_STATE_RX_PAYLOAD, - SPI_RAW_STATE_TX_HEADER, - SPI_RAW_STATE_TX_PAYLOAD, -} trans_state_t; - -#define _static static - -static spi_slave_raw_trasp_cfg_t m_spi_slave_raw_config; - -_static uint16_t m_accumulated_rx_packet_length; -_static uint16_t m_rx_packet_length; -_static uint16_t m_current_rx_frame_length; - -_static uint16_t m_accumulated_tx_packet_length; -_static uint16_t m_tx_packet_length; -_static uint16_t m_current_tx_frame_length; - -_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE]; -_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE]; - -_static uint8_t m_frame_buffer[SER_PHY_SPI_MTU_SIZE]; //trash storage -_static uint8_t m_zero_buffer[SER_PHY_SPI_MTU_SIZE] = { 0 }; //ROM'able declaration - -_static uint8_t * volatile m_p_rx_buffer = NULL; -_static const uint8_t * volatile m_p_tx_buffer = NULL; - -_static bool m_trash_payload_flag; -_static bool m_buffer_reqested_flag; - -_static trans_state_t m_trans_state = SPI_RAW_STATE_UNKNOWN; -_static ser_phy_events_handler_t m_ser_phy_callback = NULL; - -static void spi_slave_raw_assert(bool cond) -{ - APP_ERROR_CHECK_BOOL(cond); -} - -static void callback_ser_phy_event(ser_phy_evt_t event) -{ - if (m_ser_phy_callback) - { - m_ser_phy_callback(event); - } -} - -static void callback_memory_request(uint16_t size) -{ - ser_phy_evt_t event; - - DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(0); - - event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; - event.evt_params.rx_buf_request.num_of_bytes = size; - callback_ser_phy_event(event); -} - -static void callback_packet_received(uint8_t * pBuffer, uint16_t size) -{ - ser_phy_evt_t event; - - DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(0); - - event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; - event.evt_params.rx_pkt_received.num_of_bytes = size; - event.evt_params.rx_pkt_received.p_buffer = pBuffer; - callback_ser_phy_event(event); -} - -static void callback_packet_dropped() -{ - ser_phy_evt_t event; - - DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(0); - - event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; - callback_ser_phy_event(event); -} - -static void callback_packet_transmitted(void) -{ - ser_phy_evt_t event; - - DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(0); - - event.evt_type = SER_PHY_EVT_TX_PKT_SENT; - callback_ser_phy_event(event); -} - -/* Function computes current packet length */ -static uint16_t compute_current_frame_length(const uint16_t packet_length, - const uint16_t accumulated_packet_length) -{ - uint16_t current_packet_length = packet_length - accumulated_packet_length; - - if (current_packet_length > SER_PHY_SPI_MTU_SIZE) - { - current_packet_length = SER_PHY_SPI_MTU_SIZE; - } - - return current_packet_length; -} - -static uint32_t header_get() -{ - uint32_t err_code; - - err_code = nrf_drv_spis_buffers_set(&m_spis, - (uint8_t *) m_zero_buffer, - SER_PHY_HEADER_SIZE, - m_header_rx_buffer, - SER_PHY_HEADER_SIZE); - return err_code; -} - -static uint32_t frame_get() -{ - uint32_t err_code; - - m_current_rx_frame_length = compute_current_frame_length(m_rx_packet_length, - m_accumulated_rx_packet_length); - - if (!m_trash_payload_flag) - { - err_code = - nrf_drv_spis_buffers_set(&m_spis, - (uint8_t *) m_zero_buffer, - m_current_rx_frame_length, - &(m_p_rx_buffer[m_accumulated_rx_packet_length]), - m_current_rx_frame_length); - } - else - { - err_code = nrf_drv_spis_buffers_set(&m_spis, - (uint8_t *) m_zero_buffer, - m_current_rx_frame_length, - m_frame_buffer, - m_current_rx_frame_length); - } - return err_code; -} - -static uint32_t header_send(uint16_t len) -{ - uint32_t err_code; - - (void) uint16_encode(len, m_header_tx_buffer); - err_code = - nrf_drv_spis_buffers_set(&m_spis, - m_header_tx_buffer, - sizeof (m_header_tx_buffer), - m_header_rx_buffer, - sizeof (m_header_tx_buffer)); - return err_code; -} - -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); - err_code = - nrf_drv_spis_buffers_set(&m_spis, - (uint8_t *) &(m_p_tx_buffer[m_accumulated_tx_packet_length]), - m_current_tx_frame_length, - m_frame_buffer, - m_current_tx_frame_length); - return err_code; -} - -static void set_ready_line(void) -{ - //toggle - this should go high - but toggle is unsafe - uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.pin_rdy); - *(uint32_t *)rdy_task = 1; - return; -} - -static void set_request_line(void) -{ - //active low logic - set is 0 - nrf_gpio_pin_clear(m_spi_slave_raw_config.pin_req); - DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0); -} - -static void clear_request_line(void) -{ - //active low logic - clear is 1 - nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); - DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0); -} - -/** - * \brief Slave driver main state machine - * For UML graph, please refer to SDK documentation -*/ -static void spi_slave_event_handle(nrf_drv_spis_event_t event) -{ - uint32_t err_code = NRF_SUCCESS; - static uint16_t packetLength; - - switch (m_trans_state) - { - case SPI_RAW_STATE_SETUP_HEADER: - m_trans_state = SPI_RAW_STATE_RX_HEADER; - err_code = header_get(); - break; - - case SPI_RAW_STATE_RX_HEADER: - - if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); - set_ready_line(); - } - - if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); - spi_slave_raw_assert(event.rx_amount == SER_PHY_HEADER_SIZE); - packetLength = uint16_decode(m_header_rx_buffer); - - if (packetLength != 0 ) - { - m_trans_state = SPI_RAW_STATE_MEM_REQUESTED; - m_buffer_reqested_flag = true; - m_rx_packet_length = packetLength; - callback_memory_request(packetLength); - } - else - { - if (m_p_tx_buffer) - { - clear_request_line(); - m_trans_state = SPI_RAW_STATE_TX_HEADER; - err_code = header_send(m_tx_packet_length); - } - else - { - //there is nothing to send - zero response facilitates pooling - but perhaps, it should be assert - err_code = header_send(0); - } - } - } - - break; - - case SPI_RAW_STATE_MEM_REQUESTED: - - if (event.evt_type == NRF_DRV_SPIS_EVT_TYPE_MAX) //This is API dummy event - { - m_buffer_reqested_flag = false; - m_trans_state = SPI_RAW_STATE_RX_PAYLOAD; - m_accumulated_rx_packet_length = 0; - err_code = frame_get(); - } - break; - - case SPI_RAW_STATE_RX_PAYLOAD: - - if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); - set_ready_line(); - } - - if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); - spi_slave_raw_assert(event.rx_amount == m_current_rx_frame_length); - m_accumulated_rx_packet_length += m_current_rx_frame_length; - - if (m_accumulated_rx_packet_length < m_rx_packet_length ) - { - err_code = frame_get(); - } - else - { - spi_slave_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length); - m_trans_state = SPI_RAW_STATE_RX_HEADER; - err_code = header_get(); - - if (!m_trash_payload_flag) - { - callback_packet_received(m_p_rx_buffer, m_accumulated_rx_packet_length); - } - else - { - callback_packet_dropped(); - } - } - } - break; - - case SPI_RAW_STATE_TX_HEADER: - - if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); - set_ready_line(); - } - - if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); - spi_slave_raw_assert(event.tx_amount == SER_PHY_HEADER_SIZE); - m_trans_state = SPI_RAW_STATE_TX_PAYLOAD; - m_accumulated_tx_packet_length = 0; - err_code = frame_send(); - } - - break; - - case SPI_RAW_STATE_TX_PAYLOAD: - - if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); - set_ready_line(); - } - - if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) - { - DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); - spi_slave_raw_assert(event.tx_amount == m_current_tx_frame_length); - m_accumulated_tx_packet_length += m_current_tx_frame_length; - - if ( m_accumulated_tx_packet_length < m_tx_packet_length ) - { - err_code = frame_send(); - } - else - { - spi_slave_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length); - //clear pointer before callback - m_p_tx_buffer = NULL; - callback_packet_transmitted(); - //spi slave TX transfer is possible only when RX is ready, so return to waiting for a header - m_trans_state = SPI_RAW_STATE_RX_HEADER; - err_code = header_get(); - } - } - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - APP_ERROR_CHECK(err_code); -} - -static void spi_slave_gpiote_init(void) -{ - if (!nrf_drv_gpiote_is_init()) - { - (void)nrf_drv_gpiote_init(); - } - nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true); - (void) nrf_drv_gpiote_out_init(m_spi_slave_raw_config.pin_rdy, &config); - (void) nrf_drv_gpiote_out_task_enable(m_spi_slave_raw_config.pin_rdy); - return; -} - -static void spi_slave_ppi_init(void) -{ - uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.pin_rdy); - //Configure PPI channel to clear /RDY line - NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].EEP = (uint32_t)(&NRF_SPIS1->EVENTS_END); - NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].TEP = rdy_task; - - //this works only for channels 0..15 - but soft device is using 8-15 anyway - NRF_PPI->CHEN |= (1 << m_spi_slave_raw_config.ppi_rdy_ch); - return; -} - -static void spi_slave_gpio_init(void) -{ - nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req); - nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); - nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy); - nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy); -} - -/* ser_phy API function */ -void ser_phy_interrupts_enable(void) -{ - (void)sd_nvic_EnableIRQ(m_spis.irq); -} - -/* ser_phy API function */ -void ser_phy_interrupts_disable(void) -{ - (void)sd_nvic_DisableIRQ(m_spis.irq); -} - -/* ser_phy API function */ -uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) -{ - uint32_t status = NRF_SUCCESS; - nrf_drv_spis_event_t event; - - ser_phy_interrupts_disable(); - - if (m_buffer_reqested_flag && (m_trans_state == SPI_RAW_STATE_MEM_REQUESTED)) - { - m_p_rx_buffer = p_buffer; - - if (m_p_rx_buffer) - { - m_trash_payload_flag = false; - } - else - { - m_trash_payload_flag = true; - } - event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition with dummy event - event.rx_amount = 0; - event.tx_amount = 0; - spi_slave_event_handle(event); - } - else - { - status = NRF_ERROR_BUSY; - } - ser_phy_interrupts_enable(); - - return status; -} - -/* ser_phy API function */ -uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) -{ - uint32_t status = NRF_SUCCESS; - - if ( p_buffer == NULL || num_of_bytes == 0) - { - return NRF_ERROR_NULL; - } - - ser_phy_interrupts_disable(); - - if ( m_p_tx_buffer == NULL) - { - m_tx_packet_length = num_of_bytes; - m_p_tx_buffer = p_buffer; - set_request_line(); - } - else - { - status = NRF_ERROR_BUSY; - } - ser_phy_interrupts_enable(); - - return status; -} - -/* ser_phy API function */ -uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) -{ - uint32_t err_code; - nrf_drv_spis_config_t spi_slave_config; - nrf_drv_spis_event_t event; - - if (m_trans_state != SPI_RAW_STATE_UNKNOWN) - { - return NRF_ERROR_INVALID_STATE; - } - - if (events_handler == NULL) - { - return NRF_ERROR_NULL; - } - - //one ppi channel and one gpiote channel are used to drive RDY line - m_spi_slave_raw_config.pin_req = SER_PHY_SPI_SLAVE_REQ_PIN; - m_spi_slave_raw_config.pin_rdy = SER_PHY_SPI_SLAVE_RDY_PIN; - m_spi_slave_raw_config.ppi_rdy_ch = SER_PHY_SPI_PPI_RDY_CH; - m_spi_slave_raw_config.gpiote_rdy_ch = SER_PHY_SPI_GPIOTE_RDY_CH; - - spi_slave_gpio_init(); - spi_slave_gpiote_init(); - spi_slave_ppi_init(); - - spi_slave_config.miso_pin = SER_PHY_SPI_SLAVE_MISO_PIN; - spi_slave_config.mosi_pin = SER_PHY_SPI_SLAVE_MOSI_PIN; - spi_slave_config.sck_pin = SER_PHY_SPI_SLAVE_SCK_PIN; - spi_slave_config.csn_pin = SER_PHY_SPI_SLAVE_SS_PIN; - spi_slave_config.mode = NRF_DRV_SPIS_MODE_0; - spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST; - spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER; - spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER; - spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOW; - spi_slave_config.miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE; - //use /CS pullup because state of the line might be undefined when master redefines PIO lines - spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP; - - //keep /CS high when init - nrf_gpio_cfg_input(spi_slave_config.csn_pin, NRF_GPIO_PIN_PULLUP); - - err_code = nrf_drv_spis_init(&m_spis, &spi_slave_config, spi_slave_event_handle); - APP_ERROR_CHECK(err_code); - - if (err_code == NRF_SUCCESS) - { - m_ser_phy_callback = events_handler; - - m_trans_state = SPI_RAW_STATE_SETUP_HEADER; - event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition for dummy event - event.rx_amount = 0; - event.tx_amount = 0; - spi_slave_event_handle(event); - - } - return err_code; -} - -/* ser_phy API function */ -void ser_phy_close(void) -{ - nrf_drv_spis_uninit(&m_spis); - m_ser_phy_callback = NULL; - m_trans_state = SPI_RAW_STATE_UNKNOWN; -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart.c deleted file mode 100644 index 083d2dd..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart.c +++ /dev/null @@ -1,440 +0,0 @@ - -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ser_phy.h" -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - -#include "nordic_common.h" -#include "nrf.h" -#include "nrf_error.h" -#include "nrf_gpio.h" -#include "app_util.h" -#include "app_uart.h" -#include "app_error.h" - -#ifdef SER_CONNECTIVITY -#include "ser_phy_config_conn_nrf51.h" -#else -#include "ser_phy_config_app_nrf51.h" -#endif /* SER_CONNECTIVITY */ - -#include "boards.h" - -#ifdef NRF51 -#define SER_UART_IRQ UART0_IRQn -#elif defined NRF52 -#define SER_UART_IRQ UARTE0_UART0_IRQn -#endif /* NRF51 */ - -static uint8_t * mp_tx_stream; /**< Pointer to Tx data */ -static uint16_t m_tx_stream_length; /**< Length of Tx data including SER_PHY - * header */ -static uint16_t m_tx_stream_index; /**< Byte index in Tx data */ -static uint8_t m_tx_length_buf[SER_PHY_HEADER_SIZE]; /**< Buffer for header of Tx packet */ - -static uint8_t * mp_rx_stream; /**< Pointer to Rx buffer */ -static uint16_t m_rx_stream_length; /**< Length of Rx data including SER_PHY - * header*/ -static uint16_t m_rx_stream_index; /**< Byte index in Rx data */ -static uint8_t m_rx_length_buf[SER_PHY_HEADER_SIZE]; /**< Buffer for header of Rx packet */ -static uint8_t m_rx_drop_buf[1]; /**< 1-byte buffer used to trash incoming - * data */ -static uint8_t m_rx_byte; /**< Rx byte passed from low-level driver */ - -static ser_phy_events_handler_t m_ser_phy_event_handler; /**< Event handler for upper layer */ -static ser_phy_evt_t m_ser_phy_rx_event; /**< Rx event for upper layer - * notification */ -static ser_phy_evt_t m_ser_phy_tx_event; /**< Tx event for upper layer - * notification */ - -static bool m_other_side_active = false; /* Flag indicating that the other side is running */ - -/** - *@breif UART configuration structure, values are defined in SER_PHY config files: - * ser_phy_config_conn_nrf51.h for connectivity and ser_phy_config_app_nrf51.h for application. - */ -static const app_uart_comm_params_t comm_params = -{ - .rx_pin_no = SER_PHY_UART_RX, - .tx_pin_no = SER_PHY_UART_TX, - .rts_pin_no = SER_PHY_UART_RTS, - .cts_pin_no = SER_PHY_UART_CTS, - //Below values are defined in ser_config.h common for application and connectivity - .flow_control = SER_PHY_UART_FLOW_CTRL, - .use_parity = SER_PHY_UART_PARITY, - .baud_rate = SER_PHY_UART_BAUDRATE -}; - -/** FUNCTION DECLARATIONS */ - -static __INLINE void callback_ser_phy_event(ser_phy_evt_t event); -static __INLINE void callback_packet_received(void); -static __INLINE void callback_packet_sent(void); -static __INLINE void callback_mem_request(void); -static __INLINE void callback_hw_error(uint32_t error_src); - -static void ser_phy_uart_tx(void); -static void ser_phy_uart_rx(uint8_t rx_byte); -static void ser_phy_uart_evt_callback(app_uart_evt_t * uart_evt); - - -/** STATIC FUNCTION DEFINITIONS */ - -/** - *@brief Callback for calling ser phy event handler to notify higher layer with appropriate event. - * Handler is called only wen it was previously registered. - */ -static __INLINE void callback_ser_phy_event(ser_phy_evt_t event) -{ - if (m_ser_phy_event_handler) - { - m_ser_phy_event_handler(event); - } - return; -} - -/** - *@brief Callback for notifying upper layer that either a packet was succesfully received or it was - * dropped. - */ -static __INLINE void callback_packet_received(void) -{ - if (mp_rx_stream == m_rx_drop_buf) - { - m_ser_phy_rx_event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; - } - else - { - m_ser_phy_rx_event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; - m_ser_phy_rx_event.evt_params.rx_pkt_received.num_of_bytes = - m_rx_stream_index - SER_PHY_HEADER_SIZE; - m_ser_phy_rx_event.evt_params.rx_pkt_received.p_buffer = - mp_rx_stream; - } - - mp_rx_stream = NULL; - m_rx_stream_length = 0; - m_rx_stream_index = 0; - - callback_ser_phy_event(m_ser_phy_rx_event); -} - -/** - *@brief Callback for notifying upper layer that a packet was succesfully transmitted - */ -static __INLINE void callback_packet_sent(void) -{ - mp_tx_stream = NULL; - m_tx_stream_length = 0; - m_tx_stream_index = 0; - - m_ser_phy_tx_event.evt_type = SER_PHY_EVT_TX_PKT_SENT; - - callback_ser_phy_event(m_ser_phy_tx_event); -} - -/** - *@brief Callback for requesting from upper layer memory for an incomming packet. - */ -static __INLINE void callback_mem_request(void) -{ - m_rx_stream_length = uint16_decode(m_rx_length_buf) + SER_PHY_HEADER_SIZE; - m_ser_phy_rx_event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; - m_ser_phy_rx_event.evt_params.rx_buf_request.num_of_bytes = - m_rx_stream_length - SER_PHY_HEADER_SIZE; - - callback_ser_phy_event(m_ser_phy_rx_event); -} - -/** - *@brief Callback for notifying upper layer of a HW error that occured. - */ -static __INLINE void callback_hw_error(uint32_t error_src) -{ - mp_rx_stream = NULL; - m_rx_stream_length = 0; - m_rx_stream_index = 0; - m_ser_phy_rx_event.evt_type = SER_PHY_EVT_HW_ERROR; - - //Pass error source to upper layer - m_ser_phy_rx_event.evt_params.hw_error.error_code = error_src; - callback_ser_phy_event(m_ser_phy_rx_event); -} - -/** - *@brief Function for handling Tx procedure. - */ -static void ser_phy_uart_tx(void) -{ - if (mp_tx_stream != NULL) - { - bool tx_done_flag = false; /**< Local flag for indicating that TX is completed */ - uint32_t err_code = NRF_SUCCESS; /**< Error code for storing result of app_uart_put */ - - //Blocking TXRDY interrupt is done to avoid interrupting when this procedure is - //triggered from main context - NRF_UART0->INTENCLR = (UART_INTENSET_TXDRDY_Set << UART_INTENSET_TXDRDY_Pos); - - //Notify upper layer if whole packet has been transmitted - if (m_tx_stream_index == m_tx_stream_length) - { - callback_packet_sent(); - tx_done_flag = true; - } - //First transmit 2 bytes of packet length - else if (m_tx_stream_index < SER_PHY_HEADER_SIZE) - { - err_code = app_uart_put(m_tx_length_buf[m_tx_stream_index]); - } - //Then transmit payload - else if (m_tx_stream_index < m_tx_stream_length) - { - err_code = app_uart_put(mp_tx_stream[m_tx_stream_index - SER_PHY_HEADER_SIZE]); - } - - //Increment index only if byte was sent without errors - if ((err_code == NRF_SUCCESS) && !tx_done_flag) - { - m_tx_stream_index++; - } - - //Unblock TXRDY interrupts - NRF_UART0->INTENSET = (UART_INTENSET_TXDRDY_Set << UART_INTENSET_TXDRDY_Pos); - } - -} - -/** - *@brief Function for handling Rx procedure. - */ -static void ser_phy_uart_rx(uint8_t rx_byte) -{ - - if (mp_rx_stream == NULL ) - { - //Receive length value and request rx buffer from higher layer - if (m_rx_stream_index < SER_PHY_HEADER_SIZE) - { - m_rx_length_buf[m_rx_stream_index++] = rx_byte; - - if (m_rx_stream_index == SER_PHY_HEADER_SIZE) - { - //Block RXRDY interrupts at this point to not handle incoming bytes until upper - //layer provides memory for payload - NRF_UART0->INTENCLR = (UART_INTENCLR_RXDRDY_Clear << UART_INTENCLR_RXDRDY_Pos); - - //Request rx buffer from upper layer - callback_mem_request(); - } - } - } - else if (m_rx_stream_index < m_rx_stream_length) - { - //Receive or drop payload - if (mp_rx_stream == m_rx_drop_buf) - { - //Drop incoming data to the one-element drop buffer - *mp_rx_stream = rx_byte; - m_rx_stream_index++; - } - else - { - mp_rx_stream[m_rx_stream_index - SER_PHY_HEADER_SIZE] = rx_byte; - m_rx_stream_index++; - } - } - - //Process RX packet, notify higher layer - if (m_rx_stream_index == m_rx_stream_length) - { - callback_packet_received(); - } -} - -/** - *@brief Callback for processing events from low-level UART driver. - */ -static void ser_phy_uart_evt_callback(app_uart_evt_t * uart_evt) -{ - if (uart_evt == NULL) - { - return; - } - - switch (uart_evt->evt_type) - { - case APP_UART_COMMUNICATION_ERROR: - - //Process error only if this is parity or overrun error. - //Break and framing error is always present when app side is not active - if (uart_evt->data.error_communication & - (UART_ERRORSRC_PARITY_Msk | UART_ERRORSRC_OVERRUN_Msk)) - { - callback_hw_error(uart_evt->data.error_communication); - } - break; - - case APP_UART_TX_EMPTY: - ser_phy_uart_tx(); - break; - - case APP_UART_DATA: - - //After first reception disable pulldown - it was only needed before start - //of the other side - if (!m_other_side_active) - { - nrf_gpio_cfg_input(comm_params.rx_pin_no, NRF_GPIO_PIN_NOPULL); - m_other_side_active = true; - } - - m_rx_byte = uart_evt->data.value; - ser_phy_uart_rx(m_rx_byte); - break; - - default: - APP_ERROR_CHECK(NRF_ERROR_INTERNAL); - break; - } -} - -/** API FUNCTIONS */ - -uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) -{ - uint32_t err_code = NRF_SUCCESS; - - if (events_handler == NULL) - { - return NRF_ERROR_NULL; - } - - //Check if function was not called before - if (m_ser_phy_event_handler != NULL) - { - return NRF_ERROR_INVALID_STATE; - } - - //Configure UART and register handler - //uart_evt_handler is used to handle events produced by low-level uart driver - APP_UART_INIT(&comm_params, ser_phy_uart_evt_callback, UART_IRQ_PRIORITY, err_code); - -// //Pull down Rx pin until another side gets up to avoid receiving false bytes due to glitches -// //on Rx line -// nrf_gpio_cfg_input(comm_params.rx_pin_no, NRF_GPIO_PIN_PULLDOWN); - - m_ser_phy_event_handler = events_handler; - - //If intialization did not go alright return error - if (err_code != NRF_SUCCESS) - { - return NRF_ERROR_INVALID_PARAM; - } - - return err_code; -} - - - -uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) -{ - if (p_buffer == NULL) - { - return NRF_ERROR_NULL; - } - else if (num_of_bytes == 0) - { - return NRF_ERROR_INVALID_PARAM; - } - - //Check if there is no ongoing transmission at the moment - if ((mp_tx_stream == NULL) && (m_tx_stream_length == 0) && (m_tx_stream_index == 0)) - { - (void) uint16_encode(num_of_bytes, m_tx_length_buf); - mp_tx_stream = (uint8_t *)p_buffer; - m_tx_stream_length = num_of_bytes + SER_PHY_HEADER_SIZE; - - //Call tx procedure to start transmission of a packet - ser_phy_uart_tx(); - } - else - { - return NRF_ERROR_BUSY; - } - - return NRF_SUCCESS; -} - -uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) -{ - - if (m_ser_phy_rx_event.evt_type != SER_PHY_EVT_RX_BUF_REQUEST) - { - return NRF_ERROR_INVALID_STATE; - } - - if (p_buffer != NULL) - { - mp_rx_stream = p_buffer; - } - else - { - mp_rx_stream = m_rx_drop_buf; - } - - //Unblock RXRDY interrupts as higher layer has responded (with a valid or NULL pointer) - NRF_UART0->INTENSET = (UART_INTENSET_RXDRDY_Set << UART_INTENSET_RXDRDY_Pos); - - return NRF_SUCCESS; -} - -void ser_phy_close(void) -{ - m_ser_phy_event_handler = NULL; - (void)app_uart_close(); -} - -void ser_phy_interrupts_enable(void) -{ - NVIC_EnableIRQ(SER_UART_IRQ); -} - -void ser_phy_interrupts_disable(void) -{ - NVIC_DisableIRQ(SER_UART_IRQ); -} - http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_app.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_app.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_app.c deleted file mode 100644 index 7963d5f..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_app.c +++ /dev/null @@ -1,754 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by STMicroelectronics that - * is used in combination with a processor manufactured by Nordic Semiconductor - * or in a processor manufactured by STMicroelectronics. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include <stdint.h> -#include <stdlib.h> - -#include "nordic_common.h" -#include "boards.h" -#include "nrf.h" -#include "nrf_error.h" -#include "nrf_gpio.h" -#include "nrf_delay.h" -#include "nrf_gpiote.h" -#include "app_gpiote.h" -#include "app_util.h" -#include "app_util_platform.h" - -#include "ser_phy.h" -#include "ser_phy_config_app_nrf51.h" - -#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */ - -/** @brief States for the app_uart state machine. */ -typedef enum -{ - UART_IDLE, /**< Indicating that the current status for either RX or TX is idle. When both RX and TX is idle the UART will be disabled in order to save power. */ - UART_RX, /**< Used to indicate that a packet is currently being received on RX. */ - UART_RX_PENDING, /**< Used to indicate that byte is ready at RXD register but no buffer was available when the byte was received. The byte will be pulled when a buffer is set. */ - UART_TX_COMPLETE, /**< Used on TX to indicate that final byte has been put on TXD register. Next TXDRDY interrupt will indicate that last byte has been transmitted. */ - UART_TX_SEND, /**< Used to indicate that a packet is currently being transmitted on TX. */ - UART_TX_LAST_BYTE_WAIT, /**< Used to indicate that the last byte on a TX packet is currently waiting to be transmitted when CTS goes low. Note that flow control is off when tranmitting final byte. */ - UART_STALL, /**< Indicates that TX is stalled because final byte is being received on the UART. */ -} uart_states_t; - -static volatile uint32_t m_pin_cts_mask; /**< CTS pin mask for UART module. */ - -static volatile uint8_t * mp_tx_stream; /**< Pointer to array of data packet to be transmitted. */ -static volatile uint16_t m_tx_stream_length; /**< Total length of data packet to be transmitted. */ -static volatile uint16_t m_tx_stream_index; /**< Index in data packet for next byte to be transmitted. */ -static uint8_t m_tx_length_buf[SER_PHY_HEADER_SIZE]; /**< Buffer needed in transmission of packet length */ - -static uint8_t * mp_rx_stream; /**< Pointer to current receive buffer. */ -static volatile uint16_t m_rx_stream_length; /**< Length of receive buffer. */ -static volatile uint16_t m_rx_stream_index; /**< Index in receive buffer where the next byte will be placed. */ -static volatile bool m_rx_stream_header; /**< Indication of whether header data (true) or payload data (false) is currently being received. */ -static uint8_t m_rx_length_buf[SER_PHY_HEADER_SIZE]; /**< Buffer needed in reception of packet length */ -static uint8_t m_rx_drop_buf[1]; /**< Additional buffer, needed by packet dropping functionality. */ - -static volatile uart_states_t m_rx_state = UART_IDLE; /**< State of the RX state machine. */ -static volatile uart_states_t m_tx_state = UART_IDLE; /**< State of the TX state machine. */ -static volatile bool m_tx_pending = false; /**< If TX state is UART_STALL and a byte is ready for tranmission the pending flag is set to true. */ -static volatile bool m_cts_high_disconnect = false; /**< If CTS was sampled low when last byte was transmitted this flag is set to true to indicate that a switch from low->high on CTS should be interpreted as transmission has completed and UART is to be disabled to save power. */ - -static volatile ser_phy_events_handler_t m_ser_phy_event_handler; -static volatile ser_phy_evt_t m_ser_phy_event_rx; -static volatile ser_phy_evt_t m_ser_phy_event_tx; - - -static void uart_peripheral_disconnect_flow(void) -{ - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->CONFIG &= ~(UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); -} - - -static void uart_peripheral_connect_flow(void) -{ - NRF_UART0->PSELCTS = SER_PHY_UART_CTS; - NRF_UART0->PSELRTS = SER_PHY_UART_RTS; - NRF_UART0->CONFIG |= (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); -} - - -static void uart_peripheral_enable(void) -{ - if (!(NRF_UART0->ENABLE & (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos))) - { - NRF_UART0->PSELCTS = SER_PHY_UART_CTS; - NRF_UART0->PSELRTS = SER_PHY_UART_RTS; - NRF_UART0->CONFIG |= (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - NRF_UART0->TASKS_STARTRX = 1; - NRF_UART0->TASKS_STARTTX = 1; - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); - } -} - - -static void uart_peripheral_disable(void) -{ - if ((m_tx_state == UART_IDLE || m_tx_state == UART_STALL) && - (m_rx_state == UART_IDLE)) - { - NRF_UART0->TASKS_STOPTX = 1; - NRF_UART0->TASKS_STOPRX = 1; - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos); - - nrf_gpio_cfg_input(SER_PHY_UART_RTS, NRF_GPIO_PIN_NOPULL); - - nrf_gpiote_event_configure(0, SER_PHY_UART_CTS, NRF_GPIOTE_POLARITY_TOGGLE); - - if (!nrf_gpio_pin_read(SER_PHY_UART_CTS)) - { - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - uart_peripheral_enable(); - } - } -} - - -static void uart_tx_start(void) -{ - if (mp_tx_stream != NULL) - { - //If RX is already ongoing then no wakeup signal is required. - if (m_rx_state == UART_IDLE) - { - nrf_gpiote_event_disable(0); - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - uart_peripheral_connect_flow(); - uart_peripheral_enable(); - } - } -} - - -static void uart_tx_send(void) -{ - //First send 2 bytes of header then payload - if (m_tx_stream_index < SER_PHY_HEADER_SIZE) - { - NRF_UART0->TXD = m_tx_length_buf[m_tx_stream_index++]; - } - else if (m_tx_stream_index < m_tx_stream_length) - { - NRF_UART0->TXD = mp_tx_stream[m_tx_stream_index++ - SER_PHY_HEADER_SIZE]; - } -} - - -static void uart_tx_last_byte(void) -{ - uart_peripheral_disconnect_flow(); - m_tx_state = UART_TX_LAST_BYTE_WAIT; - - //Configure event in case CTS is going low during this function execution - nrf_gpiote_event_configure(0, SER_PHY_UART_CTS, NRF_GPIOTE_POLARITY_TOGGLE); - - if (!nrf_gpio_pin_read(SER_PHY_UART_CTS)) //All pins are low --> last byte can be transmitted. - { - //Re-check state as it might have changed due to preemption of current interrupt. - nrf_gpiote_event_disable(0); - - if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - m_tx_state = UART_TX_COMPLETE; - uart_tx_send(); - } - } -} - - -static void tx_complete_event_send(void) -{ - mp_tx_stream = NULL; - m_tx_stream_length = 0; - m_tx_stream_index = 0; - - m_ser_phy_event_tx.evt_type = SER_PHY_EVT_TX_PKT_SENT; - m_ser_phy_event_handler(m_ser_phy_event_tx); -} - - -static void uart_txdrdy_handle(void) -{ - NRF_UART0->EVENTS_TXDRDY = 0; - - if (m_tx_state == UART_TX_SEND || m_tx_state == UART_IDLE) - { - if (m_tx_stream_index < (m_tx_stream_length - 1)) - { - m_tx_state = UART_TX_SEND; - uart_tx_send(); - //Keep same state. - } - else if (m_tx_stream_index == m_tx_stream_length) - { - m_tx_state = UART_IDLE; - tx_complete_event_send(); - } - else - { - uart_tx_last_byte(); - } - } - else if (m_tx_state == UART_TX_COMPLETE) - { - m_tx_state = UART_IDLE; - - if (m_rx_state == UART_IDLE) - { - nrf_delay_us(15); - nrf_gpiote_event_configure(0, SER_PHY_UART_CTS, NRF_GPIOTE_POLARITY_TOGGLE); - - if (nrf_gpio_pin_read(SER_PHY_UART_CTS)) - { - uart_peripheral_disable(); - } - else - { - uart_peripheral_connect_flow(); - m_cts_high_disconnect = true; - nrf_gpiote_event_configure(0, SER_PHY_UART_CTS, NRF_GPIOTE_POLARITY_TOGGLE); - - if (nrf_gpio_pin_read(SER_PHY_UART_CTS)) - { - //If second sample show CTS high it either - //1) happened BEFORE gpiote enable and uart should be disabled. - //(m_cts_high_disconnect == true). - //2) happened AFTER gpiote enable and an interrupt low->high has occured then - //uart should NOT be disabled as the ISR has disabled the UART. - //(m_cts_high_disconnect == false). - if (m_cts_high_disconnect == true) - { - m_cts_high_disconnect = false; - uart_peripheral_disable(); - } - } - } - } - else - { - uart_peripheral_connect_flow(); - } - - tx_complete_event_send(); - } - else if (m_tx_state == UART_STALL) - { - if (m_tx_stream_index == m_tx_stream_length) - { - tx_complete_event_send(); - } - else - { - m_tx_pending = true; - } - } - else - { - //Do nothing. - } -} - - -static __INLINE void on_cts_high(void) -{ - if (m_cts_high_disconnect == true) - { - m_cts_high_disconnect = false; - - if (m_rx_state == UART_IDLE && m_tx_state == UART_IDLE) - { - if (m_tx_stream_index == m_tx_stream_length) - { - uart_peripheral_disable(); - } - } - } -} - - -static __INLINE void on_cts_low(void) -{ - m_cts_high_disconnect = false; - nrf_gpiote_event_disable(0); - - if (m_tx_state == UART_STALL) - { - m_tx_pending = true; - } - else if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - m_tx_state = UART_TX_COMPLETE; - uart_tx_send(); - } - else if (m_rx_state == UART_IDLE && m_tx_state == UART_IDLE) - { - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - uart_peripheral_enable(); - } -} - - -static void uart_rxdrdy_handle(void) -{ - if (m_rx_state == UART_IDLE) - { - m_rx_state = UART_RX; - } - - //Set proper size and buff at the beginning of receiving header - if ((m_rx_stream_header == true) && !m_rx_stream_index) - { - m_rx_stream_length = SER_PHY_HEADER_SIZE; - mp_rx_stream = m_rx_length_buf; - } - - if (mp_rx_stream != NULL) - { - bool tx_dual_end = false; - - NRF_UART0->EVENTS_RXDRDY = 0; - - //Second last byte received. - //Disconnect CTS before pulling the byte and receiving the final byte. - if ((m_rx_stream_header == false) && ((m_rx_stream_index) == (m_rx_stream_length - 2))) - { - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - - //Last byte is waiting for tansmission. Thus dual end TX case. - // - if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - m_tx_state = UART_STALL; - nrf_gpiote_event_disable(0); - - //Checking pending state. - //- If pending is true then CTS have become low after we stalled the UART and final byte should be transmitted here. - //- If pending is false we should check if final byte was tranmitted and if not, the do the transmission her. - if ((m_tx_pending == true) || (m_tx_stream_index == (m_tx_stream_length - 1))) - { - //tx_dual_end = true; - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - uart_tx_send(); - } - } - - if (!tx_dual_end) - { - NRF_GPIO->OUTCLR = 1 << SER_PHY_UART_RTS; - } - m_tx_state = UART_STALL; - - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->CONFIG &= ~(UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - } - - if (m_rx_stream_index < (m_rx_stream_length - 1)) - { - if (mp_rx_stream != m_rx_drop_buf) - { - mp_rx_stream[m_rx_stream_index++] = NRF_UART0->RXD; - } - else - { - mp_rx_stream[0] = NRF_UART0->RXD; - m_rx_stream_index++; - } - - if (m_tx_stream_index == (m_tx_stream_length - 1)) - { - //Toggle CTS line to indicate ack. - //If CTS is connected to UART this code will have no effect. - //But on edge case on bi-directional last byte transfer this avoids lock-up. - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_delay_us(8); - NRF_GPIO->OUTCLR = 1 << SER_PHY_UART_RTS; - } - } - else - { - if (m_rx_stream_header == false) - { - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - - if (mp_rx_stream != m_rx_drop_buf) - { - mp_rx_stream[m_rx_stream_index++] = NRF_UART0->RXD; - } - else - { - mp_rx_stream[0] = NRF_UART0->RXD; - m_rx_stream_index++; - } - m_rx_state = UART_IDLE; - - //Last byte of payload received - notify that next transmission will be header - m_rx_stream_header = true; - - //Prepare event - if (mp_rx_stream != m_rx_drop_buf) - { - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; - m_ser_phy_event_rx.evt_params.rx_pkt_received.num_of_bytes = m_rx_stream_index; - m_ser_phy_event_rx.evt_params.rx_pkt_received.p_buffer = mp_rx_stream; - } - else - { - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; - } - - m_rx_stream_length = 0; - m_rx_stream_index = 0; - } - else - { - mp_rx_stream[m_rx_stream_index++] = NRF_UART0->RXD; - - //Last byte of header received - notify that next transmission will be payload - m_rx_stream_header = false; - - mp_rx_stream = NULL; - - //Clear index before receiving payload - m_rx_stream_index = 0; - - //Prepare event - m_rx_stream_length = uint16_decode(m_rx_length_buf); - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; - m_ser_phy_event_rx.evt_params.rx_buf_request.num_of_bytes = m_rx_stream_length; - } - - //Notify upwards - m_ser_phy_event_handler(m_ser_phy_event_rx); - - //UART TX was stalled while receiving final byte. Restart tx. - if (m_tx_state == UART_STALL) - { - if (m_tx_stream_length == m_tx_stream_index) - { - m_tx_state = UART_IDLE; - } - else if (m_tx_stream_index == (m_tx_stream_length - 1)) - { - m_tx_state = UART_TX_LAST_BYTE_WAIT; - } - else - { - m_tx_state = UART_TX_SEND; - } - - //Critical region for avoiding timing issues in 'simultaneous RX end and TX start' - CRITICAL_REGION_ENTER(); - if (m_tx_pending == true) - { - m_tx_pending = false; - uart_tx_start(); - - if (m_tx_state == UART_TX_SEND) - { - uart_tx_send(); - } - else if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - uart_tx_last_byte(); - } - } - CRITICAL_REGION_EXIT(); - - if (m_tx_state == UART_IDLE) - { - uart_peripheral_disable(); - } - } - } - } - else - { - m_rx_state = UART_RX_PENDING; - } -} - - -static __INLINE void uart_error_handle(void) -{ - uint32_t error_source; - - //Clear UART ERROR event flag. - NRF_UART0->EVENTS_ERROR = 0; - - //Clear error source. - error_source = NRF_UART0->ERRORSRC; - NRF_UART0->ERRORSRC = error_source; - - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_HW_ERROR; - m_ser_phy_event_rx.evt_params.hw_error.error_code = error_source; - - m_ser_phy_event_handler(m_ser_phy_event_rx); -} - - -/**@brief app_gpiote_fast_detect event handler. - * - */ -static void gpiote_evt_handler(void) -{ - if ( m_pin_cts_mask) - { - if ( nrf_gpio_pin_read(SER_PHY_UART_CTS) ) - { - on_cts_high(); - } - else - { - on_cts_low(); - } - } -} - -/**@brief Function for handling the UART Interrupt. - * - * @details UART interrupt handler to process TX Ready when TXD is available, RX Ready when a byte - * is received, or in case of error when receiving a byte. - */ -void UART0_IRQHandler(void) -{ - //Handle Reception. - if (NRF_UART0->EVENTS_RXDRDY != 0 && (NRF_UART0->INTENSET & UART_INTENSET_RXDRDY_Msk)) - { - uart_rxdrdy_handle(); - } - - //Handle transmission. - if (NRF_UART0->EVENTS_TXDRDY != 0 && (NRF_UART0->INTENSET & UART_INTENSET_TXDRDY_Msk)) - { - uart_txdrdy_handle(); - } - - //Handle errors. - if (NRF_UART0->EVENTS_ERROR != 0 && (NRF_UART0->INTENSET & UART_INTENSET_ERROR_Msk)) - { - uart_error_handle(); - } -} - - -uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) -{ - if (events_handler == NULL) - { - return NRF_ERROR_NULL; - } - - //Check if function was not called before - if (m_ser_phy_event_handler != NULL) - { - return NRF_ERROR_INVALID_STATE; - } - - //GPIO Setup - nrf_gpio_cfg_input(SER_PHY_UART_RTS, NRF_GPIO_PIN_NOPULL); - - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_TX; - nrf_gpio_cfg_output(SER_PHY_UART_TX); - - //Setup the gpiote to handle pin events on cts-pin. - //For the UART we want to detect both low->high and high->low transitions in order to - //know when to activate/de-activate the TX/RX in the UART. - //Configure pin. - m_pin_cts_mask = (1 << SER_PHY_UART_CTS); - nrf_gpio_cfg_sense_input(SER_PHY_UART_CTS, - NRF_GPIO_PIN_PULLUP, - NRF_GPIO_PIN_SENSE_LOW); - - nrf_gpio_cfg_sense_input(SER_PHY_UART_RX, - NRF_GPIO_PIN_PULLUP, - NRF_GPIO_PIN_NOSENSE); - - (void)app_gpiote_input_event_handler_register(0, - SER_PHY_UART_CTS, - GPIOTE_CONFIG_POLARITY_Toggle, - gpiote_evt_handler); - (void)app_gpiote_enable_interrupts(); - - NVIC_ClearPendingIRQ(PendSV_IRQn); - - m_rx_state = UART_IDLE; - m_tx_state = UART_IDLE; - - //Set header flag - m_rx_stream_header = true; - - //UART setup - NRF_UART0->PSELRXD = SER_PHY_UART_RX; - NRF_UART0->PSELTXD = SER_PHY_UART_TX; - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->BAUDRATE = SER_PHY_UART_BAUDRATE; - NRF_UART0->CONFIG = (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos); - - //Enable UART interrupt - NRF_UART0->INTENCLR = 0xFFFFFFFF; - NRF_UART0->INTENSET = (UART_INTENSET_TXDRDY_Set << UART_INTENSET_TXDRDY_Pos) | - (UART_INTENSET_RXDRDY_Set << UART_INTENSET_RXDRDY_Pos) | - (UART_INTENSET_ERROR_Set << UART_INTENSET_ERROR_Pos); - - NVIC_ClearPendingIRQ(UART0_IRQn); - NVIC_SetPriority(UART0_IRQn, APP_IRQ_PRIORITY_MID); - NVIC_EnableIRQ(UART0_IRQn); - - m_ser_phy_event_handler = events_handler; - - return NRF_SUCCESS; -} - - -void ser_phy_close(void) -{ - //Disable UART interrupt. - NRF_UART0->INTENCLR = 0xFFFFFFFF; - - //Unregister callback. - m_ser_phy_event_handler = NULL; - - //Will not check err_code here as we will still continue with closure of UART despite errors. - //Note that any error will still be reported back in the system. - nrf_gpiote_event_disable(0); - - uart_peripheral_disable(); - - //Clear internal UART states - m_rx_state = UART_IDLE; - m_tx_state = UART_IDLE; - - mp_tx_stream = NULL; - m_tx_stream_length = 0; - m_tx_stream_index = 0; - - mp_rx_stream = NULL; - m_rx_stream_length = 0; - m_rx_stream_index = 0; -} - - -uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) -{ - if (p_buffer == NULL) - { - return NRF_ERROR_NULL; - } - - if (num_of_bytes == 0) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (mp_tx_stream != NULL) - { - return NRF_ERROR_BUSY; - } - - m_tx_pending = true; - - (void) uint16_encode(num_of_bytes, m_tx_length_buf); - mp_tx_stream = (uint8_t *)p_buffer; - m_tx_stream_length = num_of_bytes + SER_PHY_HEADER_SIZE; - - //Critical region for avoiding timing issues in 'simultaneous RX end and TX start' - CRITICAL_REGION_ENTER(); - if ((!m_rx_stream_length) || (m_rx_stream_index < (m_rx_stream_length - 2))) - { - if (m_tx_state != UART_STALL) - { - if (m_tx_pending == true) - { - m_tx_pending = false; - uart_tx_start(); - //As no tx can be ongoing, then it is safe to call tx_send here. - uart_tx_send(); - } - } - } - CRITICAL_REGION_EXIT(); - - return NRF_SUCCESS; -} - - -uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) -{ - if (m_ser_phy_event_rx.evt_type != SER_PHY_EVT_RX_BUF_REQUEST) - { - return NRF_ERROR_INVALID_STATE; - } - - if (p_buffer != NULL) - { - mp_rx_stream = p_buffer; - } - else - { - mp_rx_stream = m_rx_drop_buf; - } - - return NRF_SUCCESS; -} - - -void ser_phy_interrupts_enable(void) -{ - NVIC_EnableIRQ(UART0_IRQn); - NVIC_EnableIRQ(GPIOTE_IRQn); -} - - -void ser_phy_interrupts_disable(void) -{ - NVIC_DisableIRQ(UART0_IRQn); - NVIC_DisableIRQ(GPIOTE_IRQn); -}