Martin Gurtner / HKC_MiniCheetah
Committer:
MartinGurtner
Date:
Fri Jan 22 13:10:37 2021 +0000
Revision:
60:8399756e1ba1
.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MartinGurtner 60:8399756e1ba1 1 /*
MartinGurtner 60:8399756e1ba1 2 * Copyright (c) 2015 Nordic Semiconductor ASA
MartinGurtner 60:8399756e1ba1 3 * All rights reserved.
MartinGurtner 60:8399756e1ba1 4 *
MartinGurtner 60:8399756e1ba1 5 * Redistribution and use in source and binary forms, with or without modification,
MartinGurtner 60:8399756e1ba1 6 * are permitted provided that the following conditions are met:
MartinGurtner 60:8399756e1ba1 7 *
MartinGurtner 60:8399756e1ba1 8 * 1. Redistributions of source code must retain the above copyright notice, this list
MartinGurtner 60:8399756e1ba1 9 * of conditions and the following disclaimer.
MartinGurtner 60:8399756e1ba1 10 *
MartinGurtner 60:8399756e1ba1 11 * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
MartinGurtner 60:8399756e1ba1 12 * integrated circuit in a product or a software update for such product, must reproduce
MartinGurtner 60:8399756e1ba1 13 * the above copyright notice, this list of conditions and the following disclaimer in
MartinGurtner 60:8399756e1ba1 14 * the documentation and/or other materials provided with the distribution.
MartinGurtner 60:8399756e1ba1 15 *
MartinGurtner 60:8399756e1ba1 16 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
MartinGurtner 60:8399756e1ba1 17 * used to endorse or promote products derived from this software without specific prior
MartinGurtner 60:8399756e1ba1 18 * written permission.
MartinGurtner 60:8399756e1ba1 19 *
MartinGurtner 60:8399756e1ba1 20 * 4. This software, with or without modification, must only be used with a
MartinGurtner 60:8399756e1ba1 21 * Nordic Semiconductor ASA integrated circuit.
MartinGurtner 60:8399756e1ba1 22 *
MartinGurtner 60:8399756e1ba1 23 * 5. Any software provided in binary or object form under this license must not be reverse
MartinGurtner 60:8399756e1ba1 24 * engineered, decompiled, modified and/or disassembled.
MartinGurtner 60:8399756e1ba1 25 *
MartinGurtner 60:8399756e1ba1 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
MartinGurtner 60:8399756e1ba1 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
MartinGurtner 60:8399756e1ba1 28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
MartinGurtner 60:8399756e1ba1 29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
MartinGurtner 60:8399756e1ba1 30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
MartinGurtner 60:8399756e1ba1 31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
MartinGurtner 60:8399756e1ba1 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
MartinGurtner 60:8399756e1ba1 33 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
MartinGurtner 60:8399756e1ba1 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
MartinGurtner 60:8399756e1ba1 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MartinGurtner 60:8399756e1ba1 36 *
MartinGurtner 60:8399756e1ba1 37 */
MartinGurtner 60:8399756e1ba1 38
MartinGurtner 60:8399756e1ba1 39 #include "sdk_common.h"
MartinGurtner 60:8399756e1ba1 40 #if NRF_MODULE_ENABLED(TWI)
MartinGurtner 60:8399756e1ba1 41 #define ENABLED_TWI_COUNT (TWI0_ENABLED+TWI1_ENABLED)
MartinGurtner 60:8399756e1ba1 42 #if ENABLED_TWI_COUNT
MartinGurtner 60:8399756e1ba1 43 #include "nrf_drv_twi.h"
MartinGurtner 60:8399756e1ba1 44 #include "nrf_drv_common.h"
MartinGurtner 60:8399756e1ba1 45 #include "nrf_gpio.h"
MartinGurtner 60:8399756e1ba1 46 #include "nrf_assert.h"
MartinGurtner 60:8399756e1ba1 47 #include "app_util_platform.h"
MartinGurtner 60:8399756e1ba1 48 #include "nrf_delay.h"
MartinGurtner 60:8399756e1ba1 49
MartinGurtner 60:8399756e1ba1 50 #include <stdio.h>
MartinGurtner 60:8399756e1ba1 51
MartinGurtner 60:8399756e1ba1 52 #define NRF_LOG_MODULE_NAME "TWI"
MartinGurtner 60:8399756e1ba1 53
MartinGurtner 60:8399756e1ba1 54 #if TWI_CONFIG_LOG_ENABLED
MartinGurtner 60:8399756e1ba1 55 #define NRF_LOG_LEVEL TWI_CONFIG_LOG_LEVEL
MartinGurtner 60:8399756e1ba1 56 #define NRF_LOG_INFO_COLOR TWI_CONFIG_INFO_COLOR
MartinGurtner 60:8399756e1ba1 57 #define NRF_LOG_DEBUG_COLOR TWI_CONFIG_DEBUG_COLOR
MartinGurtner 60:8399756e1ba1 58 #define EVT_TO_STR(event) (event == NRF_DRV_TWI_EVT_DONE ? "EVT_DONE" : \
MartinGurtner 60:8399756e1ba1 59 (event == NRF_DRV_TWI_EVT_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \
MartinGurtner 60:8399756e1ba1 60 (event == NRF_DRV_TWI_EVT_DATA_NACK ? "EVT_DATA_NACK" : "UNKNOWN ERROR")))
MartinGurtner 60:8399756e1ba1 61 #define EVT_TO_STR_TWI(event) (event == NRF_TWI_EVENT_STOPPED ? "NRF_TWI_EVENT_STOPPED" : \
MartinGurtner 60:8399756e1ba1 62 (event == NRF_TWI_EVENT_RXDREADY ? "NRF_TWI_EVENT_RXDREADY" : \
MartinGurtner 60:8399756e1ba1 63 (event == NRF_TWI_EVENT_TXDSENT ? "NRF_TWI_EVENT_TXDSENT" : \
MartinGurtner 60:8399756e1ba1 64 (event == NRF_TWI_EVENT_ERROR ? "NRF_TWI_EVENT_ERROR" : \
MartinGurtner 60:8399756e1ba1 65 (event == NRF_TWI_EVENT_BB ? "NRF_TWI_EVENT_BB" : \
MartinGurtner 60:8399756e1ba1 66 (event == NRF_TWI_EVENT_SUSPENDED ? "NRF_TWI_EVENT_SUSPENDED" : "UNKNOWN ERROR"))))))
MartinGurtner 60:8399756e1ba1 67 #define EVT_TO_STR_TWIM(event) (event == NRF_TWIM_EVENT_STOPPED ? "NRF_TWIM_EVENT_STOPPED" : \
MartinGurtner 60:8399756e1ba1 68 (event == NRF_TWIM_EVENT_ERROR ? "NRF_TWIM_EVENT_ERROR" : \
MartinGurtner 60:8399756e1ba1 69 (event == NRF_TWIM_EVENT_SUSPENDED ? "NRF_TWIM_EVENT_SUSPENDED" : \
MartinGurtner 60:8399756e1ba1 70 (event == NRF_TWIM_EVENT_RXSTARTED ? "NRF_TWIM_EVENT_RXSTARTED" : \
MartinGurtner 60:8399756e1ba1 71 (event == NRF_TWIM_EVENT_TXSTARTED ? "NRF_TWIM_EVENT_TXSTARTED" : \
MartinGurtner 60:8399756e1ba1 72 (event == NRF_TWIM_EVENT_LASTRX ? "NRF_TWIM_EVENT_LASTRX" : \
MartinGurtner 60:8399756e1ba1 73 (event == NRF_TWIM_EVENT_LASTTX ? "NRF_TWIM_EVENT_LASTTX" : "UNKNOWN ERROR")))))))
MartinGurtner 60:8399756e1ba1 74 #define TRANSFER_TO_STR(type) (type == NRF_DRV_TWI_XFER_TX ? "XFER_TX" : \
MartinGurtner 60:8399756e1ba1 75 (type == NRF_DRV_TWI_XFER_RX ? "XFER_RX" : \
MartinGurtner 60:8399756e1ba1 76 (type == NRF_DRV_TWI_XFER_TXRX ? "XFER_TXRX" : \
MartinGurtner 60:8399756e1ba1 77 (type == NRF_DRV_TWI_XFER_TXTX ? "XFER_TXTX" : "UNKNOWN TRANSFER TYPE"))))
MartinGurtner 60:8399756e1ba1 78 #else //TWI_CONFIG_LOG_ENABLED
MartinGurtner 60:8399756e1ba1 79 #define EVT_TO_STR(event) ""
MartinGurtner 60:8399756e1ba1 80 #define EVT_TO_STR_TWI(event) ""
MartinGurtner 60:8399756e1ba1 81 #define EVT_TO_STR_TWIM(event) ""
MartinGurtner 60:8399756e1ba1 82 #define TRANSFER_TO_STR(event) ""
MartinGurtner 60:8399756e1ba1 83 #define NRF_LOG_LEVEL 0
MartinGurtner 60:8399756e1ba1 84 #endif //TWI_CONFIG_LOG_ENABLED
MartinGurtner 60:8399756e1ba1 85 #include "nrf_log.h"
MartinGurtner 60:8399756e1ba1 86 #include "nrf_log_ctrl.h"
MartinGurtner 60:8399756e1ba1 87
MartinGurtner 60:8399756e1ba1 88
MartinGurtner 60:8399756e1ba1 89 #define TWI0_IRQ_HANDLER SPI0_TWI0_IRQHandler
MartinGurtner 60:8399756e1ba1 90 #define TWI1_IRQ_HANDLER SPI1_TWI1_IRQHandler
MartinGurtner 60:8399756e1ba1 91
MartinGurtner 60:8399756e1ba1 92 #if (defined(TWIM_IN_USE) && defined(TWI_IN_USE))
MartinGurtner 60:8399756e1ba1 93 // TWIM and TWI combined
MartinGurtner 60:8399756e1ba1 94 #define CODE_FOR_TWIM(code) if (p_instance->use_easy_dma) { code }
MartinGurtner 60:8399756e1ba1 95 #define CODE_FOR_TWI(code) else { code }
MartinGurtner 60:8399756e1ba1 96 #elif (defined(TWIM_IN_USE) && !defined(TWI_IN_USE))
MartinGurtner 60:8399756e1ba1 97 // TWIM only
MartinGurtner 60:8399756e1ba1 98 #define CODE_FOR_TWIM(code) { code }
MartinGurtner 60:8399756e1ba1 99 #define CODE_FOR_TWI(code)
MartinGurtner 60:8399756e1ba1 100 #elif (!defined(TWIM_IN_USE) && defined(TWI_IN_USE))
MartinGurtner 60:8399756e1ba1 101 // TWI only
MartinGurtner 60:8399756e1ba1 102 #define CODE_FOR_TWIM(code)
MartinGurtner 60:8399756e1ba1 103 #define CODE_FOR_TWI(code) { code }
MartinGurtner 60:8399756e1ba1 104 #else
MartinGurtner 60:8399756e1ba1 105 #error "Wrong configuration."
MartinGurtner 60:8399756e1ba1 106 #endif
MartinGurtner 60:8399756e1ba1 107
MartinGurtner 60:8399756e1ba1 108 // All interrupt flags
MartinGurtner 60:8399756e1ba1 109 #define DISABLE_ALL_INT_SHORT 0xFFFFFFFF
MartinGurtner 60:8399756e1ba1 110
MartinGurtner 60:8399756e1ba1 111 #define SCL_PIN_INIT_CONF ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
MartinGurtner 60:8399756e1ba1 112 | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
MartinGurtner 60:8399756e1ba1 113 | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
MartinGurtner 60:8399756e1ba1 114 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
MartinGurtner 60:8399756e1ba1 115 | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos))
MartinGurtner 60:8399756e1ba1 116 #define SDA_PIN_INIT_CONF SCL_PIN_INIT_CONF
MartinGurtner 60:8399756e1ba1 117
MartinGurtner 60:8399756e1ba1 118 #define SDA_PIN_UNINIT_CONF ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
MartinGurtner 60:8399756e1ba1 119 | (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) \
MartinGurtner 60:8399756e1ba1 120 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) \
MartinGurtner 60:8399756e1ba1 121 | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) \
MartinGurtner 60:8399756e1ba1 122 | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos))
MartinGurtner 60:8399756e1ba1 123 #define SCL_PIN_UNINIT_CONF SDA_PIN_UNINIT_CONF
MartinGurtner 60:8399756e1ba1 124
MartinGurtner 60:8399756e1ba1 125 #define SCL_PIN_INIT_CONF_CLR ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
MartinGurtner 60:8399756e1ba1 126 | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
MartinGurtner 60:8399756e1ba1 127 | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
MartinGurtner 60:8399756e1ba1 128 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
MartinGurtner 60:8399756e1ba1 129 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos))
MartinGurtner 60:8399756e1ba1 130 #define SDA_PIN_INIT_CONF_CLR SCL_PIN_INIT_CONF_CLR
MartinGurtner 60:8399756e1ba1 131
MartinGurtner 60:8399756e1ba1 132 #define HW_TIMEOUT 10000
MartinGurtner 60:8399756e1ba1 133
MartinGurtner 60:8399756e1ba1 134 // Control block - driver instance local data.
MartinGurtner 60:8399756e1ba1 135 typedef struct
MartinGurtner 60:8399756e1ba1 136 {
MartinGurtner 60:8399756e1ba1 137 nrf_drv_twi_evt_handler_t handler;
MartinGurtner 60:8399756e1ba1 138 void * p_context;
MartinGurtner 60:8399756e1ba1 139 volatile uint32_t int_mask;
MartinGurtner 60:8399756e1ba1 140 nrf_drv_twi_xfer_desc_t xfer_desc;
MartinGurtner 60:8399756e1ba1 141 uint32_t flags;
MartinGurtner 60:8399756e1ba1 142 uint8_t * p_curr_buf;
MartinGurtner 60:8399756e1ba1 143 uint8_t curr_length;
MartinGurtner 60:8399756e1ba1 144 bool curr_no_stop;
MartinGurtner 60:8399756e1ba1 145 nrf_drv_state_t state;
MartinGurtner 60:8399756e1ba1 146 bool error;
MartinGurtner 60:8399756e1ba1 147 volatile bool busy;
MartinGurtner 60:8399756e1ba1 148 bool repeated;
MartinGurtner 60:8399756e1ba1 149 uint8_t bytes_transferred;
MartinGurtner 60:8399756e1ba1 150 bool hold_bus_uninit;
MartinGurtner 60:8399756e1ba1 151 } twi_control_block_t;
MartinGurtner 60:8399756e1ba1 152
MartinGurtner 60:8399756e1ba1 153 static twi_control_block_t m_cb[ENABLED_TWI_COUNT];
MartinGurtner 60:8399756e1ba1 154
MartinGurtner 60:8399756e1ba1 155 #if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
MartinGurtner 60:8399756e1ba1 156 #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n
MartinGurtner 60:8399756e1ba1 157 #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void)
MartinGurtner 60:8399756e1ba1 158
MartinGurtner 60:8399756e1ba1 159 #if NRF_MODULE_ENABLED(TWI0)
MartinGurtner 60:8399756e1ba1 160 IRQ_HANDLER(0);
MartinGurtner 60:8399756e1ba1 161 #endif
MartinGurtner 60:8399756e1ba1 162 #if NRF_MODULE_ENABLED(TWI1)
MartinGurtner 60:8399756e1ba1 163 IRQ_HANDLER(1);
MartinGurtner 60:8399756e1ba1 164 #endif
MartinGurtner 60:8399756e1ba1 165 static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_TWI_COUNT] = {
MartinGurtner 60:8399756e1ba1 166 #if NRF_MODULE_ENABLED(TWI0)
MartinGurtner 60:8399756e1ba1 167 IRQ_HANDLER_NAME(0),
MartinGurtner 60:8399756e1ba1 168 #endif
MartinGurtner 60:8399756e1ba1 169 #if NRF_MODULE_ENABLED(TWI1)
MartinGurtner 60:8399756e1ba1 170 IRQ_HANDLER_NAME(1),
MartinGurtner 60:8399756e1ba1 171 #endif
MartinGurtner 60:8399756e1ba1 172 };
MartinGurtner 60:8399756e1ba1 173 #else
MartinGurtner 60:8399756e1ba1 174 #define IRQ_HANDLER(n) void SPI##n##_TWI##n##_IRQHandler(void)
MartinGurtner 60:8399756e1ba1 175 #endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
MartinGurtner 60:8399756e1ba1 176
MartinGurtner 60:8399756e1ba1 177 static ret_code_t twi_process_error(uint32_t errorsrc)
MartinGurtner 60:8399756e1ba1 178 {
MartinGurtner 60:8399756e1ba1 179 ret_code_t ret = NRF_ERROR_INTERNAL;
MartinGurtner 60:8399756e1ba1 180
MartinGurtner 60:8399756e1ba1 181 if (errorsrc & NRF_TWI_ERROR_OVERRUN)
MartinGurtner 60:8399756e1ba1 182 {
MartinGurtner 60:8399756e1ba1 183 ret = NRF_ERROR_DRV_TWI_ERR_OVERRUN;
MartinGurtner 60:8399756e1ba1 184 }
MartinGurtner 60:8399756e1ba1 185
MartinGurtner 60:8399756e1ba1 186 if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK)
MartinGurtner 60:8399756e1ba1 187 {
MartinGurtner 60:8399756e1ba1 188 ret = NRF_ERROR_DRV_TWI_ERR_ANACK;
MartinGurtner 60:8399756e1ba1 189 }
MartinGurtner 60:8399756e1ba1 190
MartinGurtner 60:8399756e1ba1 191 if (errorsrc & NRF_TWI_ERROR_DATA_NACK)
MartinGurtner 60:8399756e1ba1 192 {
MartinGurtner 60:8399756e1ba1 193 ret = NRF_ERROR_DRV_TWI_ERR_DNACK;
MartinGurtner 60:8399756e1ba1 194 }
MartinGurtner 60:8399756e1ba1 195
MartinGurtner 60:8399756e1ba1 196 return ret;
MartinGurtner 60:8399756e1ba1 197 }
MartinGurtner 60:8399756e1ba1 198
MartinGurtner 60:8399756e1ba1 199 static void twi_clear_bus(nrf_drv_twi_config_t const * p_config)
MartinGurtner 60:8399756e1ba1 200 {
MartinGurtner 60:8399756e1ba1 201 NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF;
MartinGurtner 60:8399756e1ba1 202 NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF;
MartinGurtner 60:8399756e1ba1 203
MartinGurtner 60:8399756e1ba1 204 nrf_gpio_pin_set(p_config->scl);
MartinGurtner 60:8399756e1ba1 205 nrf_gpio_pin_set(p_config->sda);
MartinGurtner 60:8399756e1ba1 206
MartinGurtner 60:8399756e1ba1 207 NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF_CLR;
MartinGurtner 60:8399756e1ba1 208 NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF_CLR;
MartinGurtner 60:8399756e1ba1 209
MartinGurtner 60:8399756e1ba1 210 nrf_delay_us(4);
MartinGurtner 60:8399756e1ba1 211
MartinGurtner 60:8399756e1ba1 212 for (int i = 0; i < 9; i++)
MartinGurtner 60:8399756e1ba1 213 {
MartinGurtner 60:8399756e1ba1 214 if (nrf_gpio_pin_read(p_config->sda))
MartinGurtner 60:8399756e1ba1 215 {
MartinGurtner 60:8399756e1ba1 216 if (i == 0)
MartinGurtner 60:8399756e1ba1 217 {
MartinGurtner 60:8399756e1ba1 218 return;
MartinGurtner 60:8399756e1ba1 219 }
MartinGurtner 60:8399756e1ba1 220 else
MartinGurtner 60:8399756e1ba1 221 {
MartinGurtner 60:8399756e1ba1 222 break;
MartinGurtner 60:8399756e1ba1 223 }
MartinGurtner 60:8399756e1ba1 224 }
MartinGurtner 60:8399756e1ba1 225 nrf_gpio_pin_clear(p_config->scl);
MartinGurtner 60:8399756e1ba1 226 nrf_delay_us(4);
MartinGurtner 60:8399756e1ba1 227 nrf_gpio_pin_set(p_config->scl);
MartinGurtner 60:8399756e1ba1 228 nrf_delay_us(4);
MartinGurtner 60:8399756e1ba1 229 }
MartinGurtner 60:8399756e1ba1 230 nrf_gpio_pin_clear(p_config->sda);
MartinGurtner 60:8399756e1ba1 231 nrf_delay_us(4);
MartinGurtner 60:8399756e1ba1 232 nrf_gpio_pin_set(p_config->sda);
MartinGurtner 60:8399756e1ba1 233 }
MartinGurtner 60:8399756e1ba1 234
MartinGurtner 60:8399756e1ba1 235 ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * p_instance,
MartinGurtner 60:8399756e1ba1 236 nrf_drv_twi_config_t const * p_config,
MartinGurtner 60:8399756e1ba1 237 nrf_drv_twi_evt_handler_t event_handler,
MartinGurtner 60:8399756e1ba1 238 void * p_context)
MartinGurtner 60:8399756e1ba1 239 {
MartinGurtner 60:8399756e1ba1 240 ASSERT(p_config);
MartinGurtner 60:8399756e1ba1 241 ASSERT(p_config->scl != p_config->sda);
MartinGurtner 60:8399756e1ba1 242 twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
MartinGurtner 60:8399756e1ba1 243 ret_code_t err_code;
MartinGurtner 60:8399756e1ba1 244
MartinGurtner 60:8399756e1ba1 245 if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED)
MartinGurtner 60:8399756e1ba1 246 {
MartinGurtner 60:8399756e1ba1 247 err_code = NRF_ERROR_INVALID_STATE;
MartinGurtner 60:8399756e1ba1 248 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 249 return err_code;
MartinGurtner 60:8399756e1ba1 250 }
MartinGurtner 60:8399756e1ba1 251
MartinGurtner 60:8399756e1ba1 252 #if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
MartinGurtner 60:8399756e1ba1 253 if (nrf_drv_common_per_res_acquire(p_instance->reg.p_twi,
MartinGurtner 60:8399756e1ba1 254 m_irq_handlers[p_instance->drv_inst_idx]) != NRF_SUCCESS)
MartinGurtner 60:8399756e1ba1 255 {
MartinGurtner 60:8399756e1ba1 256 err_code = NRF_ERROR_BUSY;
MartinGurtner 60:8399756e1ba1 257 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 258 return err_code;
MartinGurtner 60:8399756e1ba1 259 }
MartinGurtner 60:8399756e1ba1 260 #endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
MartinGurtner 60:8399756e1ba1 261
MartinGurtner 60:8399756e1ba1 262 p_cb->handler = event_handler;
MartinGurtner 60:8399756e1ba1 263 p_cb->p_context = p_context;
MartinGurtner 60:8399756e1ba1 264 p_cb->int_mask = 0;
MartinGurtner 60:8399756e1ba1 265 p_cb->repeated = false;
MartinGurtner 60:8399756e1ba1 266 p_cb->busy = false;
MartinGurtner 60:8399756e1ba1 267 p_cb->hold_bus_uninit = p_config->hold_bus_uninit;
MartinGurtner 60:8399756e1ba1 268
MartinGurtner 60:8399756e1ba1 269 if(p_config->clear_bus_init)
MartinGurtner 60:8399756e1ba1 270 {
MartinGurtner 60:8399756e1ba1 271 /* Send clocks (max 9) until slave device back from stuck mode */
MartinGurtner 60:8399756e1ba1 272 twi_clear_bus(p_config);
MartinGurtner 60:8399756e1ba1 273 }
MartinGurtner 60:8399756e1ba1 274
MartinGurtner 60:8399756e1ba1 275 /* To secure correct signal levels on the pins used by the TWI
MartinGurtner 60:8399756e1ba1 276 master when the system is in OFF mode, and when the TWI master is
MartinGurtner 60:8399756e1ba1 277 disabled, these pins must be configured in the GPIO peripheral.
MartinGurtner 60:8399756e1ba1 278 */
MartinGurtner 60:8399756e1ba1 279 NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF;
MartinGurtner 60:8399756e1ba1 280 NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF;
MartinGurtner 60:8399756e1ba1 281
MartinGurtner 60:8399756e1ba1 282 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 283 (
MartinGurtner 60:8399756e1ba1 284 NRF_TWIM_Type * p_twim = p_instance->reg.p_twim;
MartinGurtner 60:8399756e1ba1 285 nrf_twim_pins_set(p_twim, p_config->scl, p_config->sda);
MartinGurtner 60:8399756e1ba1 286 nrf_twim_frequency_set(p_twim,
MartinGurtner 60:8399756e1ba1 287 (nrf_twim_frequency_t)p_config->frequency);
MartinGurtner 60:8399756e1ba1 288 )
MartinGurtner 60:8399756e1ba1 289 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 290 (
MartinGurtner 60:8399756e1ba1 291 NRF_TWI_Type * p_twi = p_instance->reg.p_twi;
MartinGurtner 60:8399756e1ba1 292 nrf_twi_pins_set(p_twi, p_config->scl, p_config->sda);
MartinGurtner 60:8399756e1ba1 293 nrf_twi_frequency_set(p_twi,
MartinGurtner 60:8399756e1ba1 294 (nrf_twi_frequency_t)p_config->frequency);
MartinGurtner 60:8399756e1ba1 295 )
MartinGurtner 60:8399756e1ba1 296
MartinGurtner 60:8399756e1ba1 297 if (p_cb->handler)
MartinGurtner 60:8399756e1ba1 298 {
MartinGurtner 60:8399756e1ba1 299 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 300 (
MartinGurtner 60:8399756e1ba1 301 nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twim),
MartinGurtner 60:8399756e1ba1 302 p_config->interrupt_priority);
MartinGurtner 60:8399756e1ba1 303 )
MartinGurtner 60:8399756e1ba1 304 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 305 (
MartinGurtner 60:8399756e1ba1 306 nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twi),
MartinGurtner 60:8399756e1ba1 307 p_config->interrupt_priority);
MartinGurtner 60:8399756e1ba1 308 )
MartinGurtner 60:8399756e1ba1 309 }
MartinGurtner 60:8399756e1ba1 310
MartinGurtner 60:8399756e1ba1 311 p_cb->state = NRF_DRV_STATE_INITIALIZED;
MartinGurtner 60:8399756e1ba1 312
MartinGurtner 60:8399756e1ba1 313 err_code = NRF_SUCCESS;
MartinGurtner 60:8399756e1ba1 314 NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 315 return err_code;
MartinGurtner 60:8399756e1ba1 316 }
MartinGurtner 60:8399756e1ba1 317
MartinGurtner 60:8399756e1ba1 318 void nrf_drv_twi_uninit(nrf_drv_twi_t const * p_instance)
MartinGurtner 60:8399756e1ba1 319 {
MartinGurtner 60:8399756e1ba1 320 twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
MartinGurtner 60:8399756e1ba1 321 ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED);
MartinGurtner 60:8399756e1ba1 322
MartinGurtner 60:8399756e1ba1 323 if (p_cb->handler)
MartinGurtner 60:8399756e1ba1 324 {
MartinGurtner 60:8399756e1ba1 325 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 326 (
MartinGurtner 60:8399756e1ba1 327 nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twim));
MartinGurtner 60:8399756e1ba1 328 )
MartinGurtner 60:8399756e1ba1 329 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 330 (
MartinGurtner 60:8399756e1ba1 331 nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twi));
MartinGurtner 60:8399756e1ba1 332 )
MartinGurtner 60:8399756e1ba1 333 }
MartinGurtner 60:8399756e1ba1 334 nrf_drv_twi_disable(p_instance);
MartinGurtner 60:8399756e1ba1 335
MartinGurtner 60:8399756e1ba1 336 #if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
MartinGurtner 60:8399756e1ba1 337 nrf_drv_common_per_res_release(p_instance->reg.p_twi);
MartinGurtner 60:8399756e1ba1 338 #endif
MartinGurtner 60:8399756e1ba1 339
MartinGurtner 60:8399756e1ba1 340 if (!p_cb->hold_bus_uninit)
MartinGurtner 60:8399756e1ba1 341 {
MartinGurtner 60:8399756e1ba1 342 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 343 (
MartinGurtner 60:8399756e1ba1 344 NRF_GPIO->PIN_CNF[p_instance->reg.p_twim->PSEL.SCL] = SCL_PIN_UNINIT_CONF;
MartinGurtner 60:8399756e1ba1 345 NRF_GPIO->PIN_CNF[p_instance->reg.p_twim->PSEL.SDA] = SDA_PIN_UNINIT_CONF;
MartinGurtner 60:8399756e1ba1 346 )
MartinGurtner 60:8399756e1ba1 347 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 348 (
MartinGurtner 60:8399756e1ba1 349 NRF_GPIO->PIN_CNF[p_instance->reg.p_twi->PSELSCL] = SCL_PIN_UNINIT_CONF;
MartinGurtner 60:8399756e1ba1 350 NRF_GPIO->PIN_CNF[p_instance->reg.p_twi->PSELSDA] = SDA_PIN_UNINIT_CONF;
MartinGurtner 60:8399756e1ba1 351 )
MartinGurtner 60:8399756e1ba1 352 }
MartinGurtner 60:8399756e1ba1 353
MartinGurtner 60:8399756e1ba1 354 p_cb->state = NRF_DRV_STATE_UNINITIALIZED;
MartinGurtner 60:8399756e1ba1 355 NRF_LOG_INFO("Instance uninitialized: %d.\r\n", p_instance->drv_inst_idx);
MartinGurtner 60:8399756e1ba1 356 }
MartinGurtner 60:8399756e1ba1 357
MartinGurtner 60:8399756e1ba1 358 void nrf_drv_twi_enable(nrf_drv_twi_t const * p_instance)
MartinGurtner 60:8399756e1ba1 359 {
MartinGurtner 60:8399756e1ba1 360 twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
MartinGurtner 60:8399756e1ba1 361 ASSERT(p_cb->state == NRF_DRV_STATE_INITIALIZED);
MartinGurtner 60:8399756e1ba1 362
MartinGurtner 60:8399756e1ba1 363 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 364 (
MartinGurtner 60:8399756e1ba1 365 NRF_TWIM_Type * p_twim = p_instance->reg.p_twim;
MartinGurtner 60:8399756e1ba1 366
MartinGurtner 60:8399756e1ba1 367 nrf_twim_enable(p_twim);
MartinGurtner 60:8399756e1ba1 368 )
MartinGurtner 60:8399756e1ba1 369 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 370 (
MartinGurtner 60:8399756e1ba1 371 NRF_TWI_Type * p_twi = p_instance->reg.p_twi;
MartinGurtner 60:8399756e1ba1 372
MartinGurtner 60:8399756e1ba1 373 nrf_twi_enable(p_twi);
MartinGurtner 60:8399756e1ba1 374 )
MartinGurtner 60:8399756e1ba1 375
MartinGurtner 60:8399756e1ba1 376 p_cb->state = NRF_DRV_STATE_POWERED_ON;
MartinGurtner 60:8399756e1ba1 377 NRF_LOG_INFO("Instance enabled: %d.\r\n", p_instance->drv_inst_idx);
MartinGurtner 60:8399756e1ba1 378 }
MartinGurtner 60:8399756e1ba1 379
MartinGurtner 60:8399756e1ba1 380 void nrf_drv_twi_disable(nrf_drv_twi_t const * p_instance)
MartinGurtner 60:8399756e1ba1 381 {
MartinGurtner 60:8399756e1ba1 382 twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
MartinGurtner 60:8399756e1ba1 383 ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED);
MartinGurtner 60:8399756e1ba1 384
MartinGurtner 60:8399756e1ba1 385 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 386 (
MartinGurtner 60:8399756e1ba1 387 NRF_TWIM_Type * p_twim = p_instance->reg.p_twim;
MartinGurtner 60:8399756e1ba1 388 p_cb->int_mask = 0;
MartinGurtner 60:8399756e1ba1 389 nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT);
MartinGurtner 60:8399756e1ba1 390 nrf_twim_shorts_disable(p_twim, DISABLE_ALL_INT_SHORT);
MartinGurtner 60:8399756e1ba1 391 nrf_twim_disable(p_twim);
MartinGurtner 60:8399756e1ba1 392 )
MartinGurtner 60:8399756e1ba1 393 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 394 (
MartinGurtner 60:8399756e1ba1 395 NRF_TWI_Type * p_twi = p_instance->reg.p_twi;
MartinGurtner 60:8399756e1ba1 396 nrf_twi_int_disable(p_twi, DISABLE_ALL_INT_SHORT);
MartinGurtner 60:8399756e1ba1 397 nrf_twi_shorts_disable(p_twi, DISABLE_ALL_INT_SHORT);
MartinGurtner 60:8399756e1ba1 398 nrf_twi_disable(p_twi);
MartinGurtner 60:8399756e1ba1 399 )
MartinGurtner 60:8399756e1ba1 400
MartinGurtner 60:8399756e1ba1 401 p_cb->state = NRF_DRV_STATE_INITIALIZED;
MartinGurtner 60:8399756e1ba1 402 NRF_LOG_INFO("Instance disabled: %d.\r\n", p_instance->drv_inst_idx);
MartinGurtner 60:8399756e1ba1 403 }
MartinGurtner 60:8399756e1ba1 404
MartinGurtner 60:8399756e1ba1 405 #ifdef TWI_IN_USE
MartinGurtner 60:8399756e1ba1 406 static bool twi_send_byte(NRF_TWI_Type * p_twi,
MartinGurtner 60:8399756e1ba1 407 uint8_t const * p_data,
MartinGurtner 60:8399756e1ba1 408 uint8_t length,
MartinGurtner 60:8399756e1ba1 409 uint8_t * p_bytes_transferred,
MartinGurtner 60:8399756e1ba1 410 bool no_stop)
MartinGurtner 60:8399756e1ba1 411 {
MartinGurtner 60:8399756e1ba1 412 if (*p_bytes_transferred < length)
MartinGurtner 60:8399756e1ba1 413 {
MartinGurtner 60:8399756e1ba1 414 nrf_twi_txd_set(p_twi, p_data[*p_bytes_transferred]);
MartinGurtner 60:8399756e1ba1 415 ++(*p_bytes_transferred);
MartinGurtner 60:8399756e1ba1 416 }
MartinGurtner 60:8399756e1ba1 417 else
MartinGurtner 60:8399756e1ba1 418 {
MartinGurtner 60:8399756e1ba1 419 if (no_stop)
MartinGurtner 60:8399756e1ba1 420 {
MartinGurtner 60:8399756e1ba1 421 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_SUSPEND);
MartinGurtner 60:8399756e1ba1 422 return false;
MartinGurtner 60:8399756e1ba1 423 }
MartinGurtner 60:8399756e1ba1 424 else
MartinGurtner 60:8399756e1ba1 425 {
MartinGurtner 60:8399756e1ba1 426 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
MartinGurtner 60:8399756e1ba1 427 }
MartinGurtner 60:8399756e1ba1 428 }
MartinGurtner 60:8399756e1ba1 429 return true;
MartinGurtner 60:8399756e1ba1 430 }
MartinGurtner 60:8399756e1ba1 431
MartinGurtner 60:8399756e1ba1 432 static void twi_receive_byte(NRF_TWI_Type * p_twi,
MartinGurtner 60:8399756e1ba1 433 uint8_t * p_data,
MartinGurtner 60:8399756e1ba1 434 uint8_t length,
MartinGurtner 60:8399756e1ba1 435 uint8_t * p_bytes_transferred)
MartinGurtner 60:8399756e1ba1 436 {
MartinGurtner 60:8399756e1ba1 437 if (*p_bytes_transferred < length)
MartinGurtner 60:8399756e1ba1 438 {
MartinGurtner 60:8399756e1ba1 439 p_data[*p_bytes_transferred] = nrf_twi_rxd_get(p_twi);
MartinGurtner 60:8399756e1ba1 440
MartinGurtner 60:8399756e1ba1 441 ++(*p_bytes_transferred);
MartinGurtner 60:8399756e1ba1 442
MartinGurtner 60:8399756e1ba1 443 if (*p_bytes_transferred == length - 1)
MartinGurtner 60:8399756e1ba1 444 {
MartinGurtner 60:8399756e1ba1 445 nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_STOP_MASK);
MartinGurtner 60:8399756e1ba1 446 }
MartinGurtner 60:8399756e1ba1 447 else if (*p_bytes_transferred == length)
MartinGurtner 60:8399756e1ba1 448 {
MartinGurtner 60:8399756e1ba1 449 return;
MartinGurtner 60:8399756e1ba1 450 }
MartinGurtner 60:8399756e1ba1 451
MartinGurtner 60:8399756e1ba1 452 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME);
MartinGurtner 60:8399756e1ba1 453 }
MartinGurtner 60:8399756e1ba1 454 }
MartinGurtner 60:8399756e1ba1 455
MartinGurtner 60:8399756e1ba1 456 static bool twi_transfer(NRF_TWI_Type * p_twi,
MartinGurtner 60:8399756e1ba1 457 bool * p_error,
MartinGurtner 60:8399756e1ba1 458 uint8_t * p_bytes_transferred,
MartinGurtner 60:8399756e1ba1 459 uint8_t * p_data,
MartinGurtner 60:8399756e1ba1 460 uint8_t length,
MartinGurtner 60:8399756e1ba1 461 bool no_stop)
MartinGurtner 60:8399756e1ba1 462 {
MartinGurtner 60:8399756e1ba1 463 bool do_stop_check = ((*p_error) || ((*p_bytes_transferred) == length));
MartinGurtner 60:8399756e1ba1 464
MartinGurtner 60:8399756e1ba1 465 if (*p_error)
MartinGurtner 60:8399756e1ba1 466 {
MartinGurtner 60:8399756e1ba1 467 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
MartinGurtner 60:8399756e1ba1 468 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT);
MartinGurtner 60:8399756e1ba1 469 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY);
MartinGurtner 60:8399756e1ba1 470 }
MartinGurtner 60:8399756e1ba1 471 else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
MartinGurtner 60:8399756e1ba1 472 {
MartinGurtner 60:8399756e1ba1 473 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
MartinGurtner 60:8399756e1ba1 474 NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR));
MartinGurtner 60:8399756e1ba1 475 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
MartinGurtner 60:8399756e1ba1 476 *p_error = true;
MartinGurtner 60:8399756e1ba1 477 }
MartinGurtner 60:8399756e1ba1 478 else
MartinGurtner 60:8399756e1ba1 479 {
MartinGurtner 60:8399756e1ba1 480 if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_TXDSENT))
MartinGurtner 60:8399756e1ba1 481 {
MartinGurtner 60:8399756e1ba1 482 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT);
MartinGurtner 60:8399756e1ba1 483 NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_TXDSENT));
MartinGurtner 60:8399756e1ba1 484 if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
MartinGurtner 60:8399756e1ba1 485 {
MartinGurtner 60:8399756e1ba1 486 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
MartinGurtner 60:8399756e1ba1 487 NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR));
MartinGurtner 60:8399756e1ba1 488 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
MartinGurtner 60:8399756e1ba1 489 *p_error = true;
MartinGurtner 60:8399756e1ba1 490 }
MartinGurtner 60:8399756e1ba1 491 else
MartinGurtner 60:8399756e1ba1 492 {
MartinGurtner 60:8399756e1ba1 493 if (!twi_send_byte(p_twi, p_data, length, p_bytes_transferred, no_stop))
MartinGurtner 60:8399756e1ba1 494 {
MartinGurtner 60:8399756e1ba1 495 return false;
MartinGurtner 60:8399756e1ba1 496 }
MartinGurtner 60:8399756e1ba1 497 }
MartinGurtner 60:8399756e1ba1 498 }
MartinGurtner 60:8399756e1ba1 499 else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_RXDREADY))
MartinGurtner 60:8399756e1ba1 500 {
MartinGurtner 60:8399756e1ba1 501 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY);
MartinGurtner 60:8399756e1ba1 502 NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_RXDREADY));
MartinGurtner 60:8399756e1ba1 503 if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
MartinGurtner 60:8399756e1ba1 504 {
MartinGurtner 60:8399756e1ba1 505 NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR));
MartinGurtner 60:8399756e1ba1 506 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
MartinGurtner 60:8399756e1ba1 507 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
MartinGurtner 60:8399756e1ba1 508 *p_error = true;
MartinGurtner 60:8399756e1ba1 509 }
MartinGurtner 60:8399756e1ba1 510 else
MartinGurtner 60:8399756e1ba1 511 {
MartinGurtner 60:8399756e1ba1 512 twi_receive_byte(p_twi, p_data, length, p_bytes_transferred);
MartinGurtner 60:8399756e1ba1 513 }
MartinGurtner 60:8399756e1ba1 514 }
MartinGurtner 60:8399756e1ba1 515 }
MartinGurtner 60:8399756e1ba1 516
MartinGurtner 60:8399756e1ba1 517 if (do_stop_check && nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED))
MartinGurtner 60:8399756e1ba1 518 {
MartinGurtner 60:8399756e1ba1 519 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED);
MartinGurtner 60:8399756e1ba1 520 NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_STOPPED));
MartinGurtner 60:8399756e1ba1 521 return false;
MartinGurtner 60:8399756e1ba1 522 }
MartinGurtner 60:8399756e1ba1 523
MartinGurtner 60:8399756e1ba1 524 return true;
MartinGurtner 60:8399756e1ba1 525 }
MartinGurtner 60:8399756e1ba1 526
MartinGurtner 60:8399756e1ba1 527 static ret_code_t twi_tx_start_transfer(twi_control_block_t * p_cb,
MartinGurtner 60:8399756e1ba1 528 NRF_TWI_Type * p_twi,
MartinGurtner 60:8399756e1ba1 529 uint8_t const * p_data,
MartinGurtner 60:8399756e1ba1 530 uint8_t length,
MartinGurtner 60:8399756e1ba1 531 bool no_stop)
MartinGurtner 60:8399756e1ba1 532 {
MartinGurtner 60:8399756e1ba1 533 ret_code_t ret_code = NRF_SUCCESS;
MartinGurtner 60:8399756e1ba1 534 volatile int32_t hw_timeout;
MartinGurtner 60:8399756e1ba1 535
MartinGurtner 60:8399756e1ba1 536 hw_timeout = HW_TIMEOUT;
MartinGurtner 60:8399756e1ba1 537
MartinGurtner 60:8399756e1ba1 538 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED);
MartinGurtner 60:8399756e1ba1 539 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
MartinGurtner 60:8399756e1ba1 540 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT);
MartinGurtner 60:8399756e1ba1 541 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY);
MartinGurtner 60:8399756e1ba1 542 nrf_twi_shorts_set(p_twi, 0);
MartinGurtner 60:8399756e1ba1 543
MartinGurtner 60:8399756e1ba1 544 p_cb->bytes_transferred = 0;
MartinGurtner 60:8399756e1ba1 545 p_cb->error = false;
MartinGurtner 60:8399756e1ba1 546
MartinGurtner 60:8399756e1ba1 547 // In case TWI is suspended resume its operation.
MartinGurtner 60:8399756e1ba1 548 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME);
MartinGurtner 60:8399756e1ba1 549 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STARTTX);
MartinGurtner 60:8399756e1ba1 550
MartinGurtner 60:8399756e1ba1 551 (void)twi_send_byte(p_twi, p_data, length, &p_cb->bytes_transferred, no_stop);
MartinGurtner 60:8399756e1ba1 552
MartinGurtner 60:8399756e1ba1 553 if (p_cb->handler)
MartinGurtner 60:8399756e1ba1 554 {
MartinGurtner 60:8399756e1ba1 555 p_cb->int_mask = NRF_TWI_INT_STOPPED_MASK |
MartinGurtner 60:8399756e1ba1 556 NRF_TWI_INT_ERROR_MASK |
MartinGurtner 60:8399756e1ba1 557 NRF_TWI_INT_TXDSENT_MASK |
MartinGurtner 60:8399756e1ba1 558 NRF_TWI_INT_RXDREADY_MASK;
MartinGurtner 60:8399756e1ba1 559 nrf_twi_int_enable(p_twi, p_cb->int_mask);
MartinGurtner 60:8399756e1ba1 560 }
MartinGurtner 60:8399756e1ba1 561 else
MartinGurtner 60:8399756e1ba1 562 {
MartinGurtner 60:8399756e1ba1 563 while ((hw_timeout > 0) && twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, (uint8_t *)p_data, length, no_stop))
MartinGurtner 60:8399756e1ba1 564 {
MartinGurtner 60:8399756e1ba1 565 hw_timeout--;
MartinGurtner 60:8399756e1ba1 566 }
MartinGurtner 60:8399756e1ba1 567
MartinGurtner 60:8399756e1ba1 568 if (p_cb->error)
MartinGurtner 60:8399756e1ba1 569 {
MartinGurtner 60:8399756e1ba1 570 uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi);
MartinGurtner 60:8399756e1ba1 571
MartinGurtner 60:8399756e1ba1 572 if (errorsrc)
MartinGurtner 60:8399756e1ba1 573 {
MartinGurtner 60:8399756e1ba1 574 ret_code = twi_process_error(errorsrc);
MartinGurtner 60:8399756e1ba1 575 }
MartinGurtner 60:8399756e1ba1 576 }
MartinGurtner 60:8399756e1ba1 577
MartinGurtner 60:8399756e1ba1 578 if (hw_timeout <= 0)
MartinGurtner 60:8399756e1ba1 579 {
MartinGurtner 60:8399756e1ba1 580 nrf_twi_disable(p_twi);
MartinGurtner 60:8399756e1ba1 581 nrf_twi_enable(p_twi);
MartinGurtner 60:8399756e1ba1 582 ret_code = NRF_ERROR_INTERNAL;
MartinGurtner 60:8399756e1ba1 583 }
MartinGurtner 60:8399756e1ba1 584
MartinGurtner 60:8399756e1ba1 585 }
MartinGurtner 60:8399756e1ba1 586 return ret_code;
MartinGurtner 60:8399756e1ba1 587 }
MartinGurtner 60:8399756e1ba1 588
MartinGurtner 60:8399756e1ba1 589 static ret_code_t twi_rx_start_transfer(twi_control_block_t * p_cb,
MartinGurtner 60:8399756e1ba1 590 NRF_TWI_Type * p_twi,
MartinGurtner 60:8399756e1ba1 591 uint8_t const * p_data,
MartinGurtner 60:8399756e1ba1 592 uint8_t length)
MartinGurtner 60:8399756e1ba1 593 {
MartinGurtner 60:8399756e1ba1 594 ret_code_t ret_code = NRF_SUCCESS;
MartinGurtner 60:8399756e1ba1 595 volatile int32_t hw_timeout;
MartinGurtner 60:8399756e1ba1 596
MartinGurtner 60:8399756e1ba1 597 hw_timeout = HW_TIMEOUT;
MartinGurtner 60:8399756e1ba1 598
MartinGurtner 60:8399756e1ba1 599 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED);
MartinGurtner 60:8399756e1ba1 600 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
MartinGurtner 60:8399756e1ba1 601 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT);
MartinGurtner 60:8399756e1ba1 602 nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY);
MartinGurtner 60:8399756e1ba1 603
MartinGurtner 60:8399756e1ba1 604 p_cb->bytes_transferred = 0;
MartinGurtner 60:8399756e1ba1 605 p_cb->error = false;
MartinGurtner 60:8399756e1ba1 606
MartinGurtner 60:8399756e1ba1 607 if (length == 1)
MartinGurtner 60:8399756e1ba1 608 {
MartinGurtner 60:8399756e1ba1 609 nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_STOP_MASK);
MartinGurtner 60:8399756e1ba1 610 }
MartinGurtner 60:8399756e1ba1 611 else
MartinGurtner 60:8399756e1ba1 612 {
MartinGurtner 60:8399756e1ba1 613 nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_SUSPEND_MASK);
MartinGurtner 60:8399756e1ba1 614 }
MartinGurtner 60:8399756e1ba1 615 // In case TWI is suspended resume its operation.
MartinGurtner 60:8399756e1ba1 616 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME);
MartinGurtner 60:8399756e1ba1 617 nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STARTRX);
MartinGurtner 60:8399756e1ba1 618
MartinGurtner 60:8399756e1ba1 619 if (p_cb->handler)
MartinGurtner 60:8399756e1ba1 620 {
MartinGurtner 60:8399756e1ba1 621 p_cb->int_mask = NRF_TWI_INT_STOPPED_MASK |
MartinGurtner 60:8399756e1ba1 622 NRF_TWI_INT_ERROR_MASK |
MartinGurtner 60:8399756e1ba1 623 NRF_TWI_INT_TXDSENT_MASK |
MartinGurtner 60:8399756e1ba1 624 NRF_TWI_INT_RXDREADY_MASK;
MartinGurtner 60:8399756e1ba1 625 nrf_twi_int_enable(p_twi, p_cb->int_mask);
MartinGurtner 60:8399756e1ba1 626 }
MartinGurtner 60:8399756e1ba1 627 else
MartinGurtner 60:8399756e1ba1 628 {
MartinGurtner 60:8399756e1ba1 629 while ((hw_timeout > 0) && twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, (uint8_t*)p_data, length, false))
MartinGurtner 60:8399756e1ba1 630 {
MartinGurtner 60:8399756e1ba1 631 hw_timeout--;
MartinGurtner 60:8399756e1ba1 632 }
MartinGurtner 60:8399756e1ba1 633
MartinGurtner 60:8399756e1ba1 634 if (p_cb->error)
MartinGurtner 60:8399756e1ba1 635 {
MartinGurtner 60:8399756e1ba1 636 uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi);
MartinGurtner 60:8399756e1ba1 637
MartinGurtner 60:8399756e1ba1 638 if (errorsrc)
MartinGurtner 60:8399756e1ba1 639 {
MartinGurtner 60:8399756e1ba1 640 ret_code = twi_process_error(errorsrc);
MartinGurtner 60:8399756e1ba1 641 }
MartinGurtner 60:8399756e1ba1 642 }
MartinGurtner 60:8399756e1ba1 643
MartinGurtner 60:8399756e1ba1 644 if (hw_timeout <= 0)
MartinGurtner 60:8399756e1ba1 645 {
MartinGurtner 60:8399756e1ba1 646 nrf_twi_disable(p_twi);
MartinGurtner 60:8399756e1ba1 647 nrf_twi_enable(p_twi);
MartinGurtner 60:8399756e1ba1 648 ret_code = NRF_ERROR_INTERNAL;
MartinGurtner 60:8399756e1ba1 649 }
MartinGurtner 60:8399756e1ba1 650 }
MartinGurtner 60:8399756e1ba1 651 return ret_code;
MartinGurtner 60:8399756e1ba1 652 }
MartinGurtner 60:8399756e1ba1 653
MartinGurtner 60:8399756e1ba1 654 __STATIC_INLINE ret_code_t twi_xfer(twi_control_block_t * p_cb,
MartinGurtner 60:8399756e1ba1 655 NRF_TWI_Type * p_twi,
MartinGurtner 60:8399756e1ba1 656 nrf_drv_twi_xfer_desc_t const * p_xfer_desc,
MartinGurtner 60:8399756e1ba1 657 uint32_t flags)
MartinGurtner 60:8399756e1ba1 658 {
MartinGurtner 60:8399756e1ba1 659
MartinGurtner 60:8399756e1ba1 660 ret_code_t err_code = NRF_SUCCESS;
MartinGurtner 60:8399756e1ba1 661
MartinGurtner 60:8399756e1ba1 662 /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */
MartinGurtner 60:8399756e1ba1 663 nrf_twi_int_disable(p_twi, DISABLE_ALL_INT_SHORT);
MartinGurtner 60:8399756e1ba1 664
MartinGurtner 60:8399756e1ba1 665 if (p_cb->busy)
MartinGurtner 60:8399756e1ba1 666 {
MartinGurtner 60:8399756e1ba1 667 nrf_twi_int_enable(p_twi, p_cb->int_mask);
MartinGurtner 60:8399756e1ba1 668 err_code = NRF_ERROR_BUSY;
MartinGurtner 60:8399756e1ba1 669 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 670 return err_code;
MartinGurtner 60:8399756e1ba1 671 }
MartinGurtner 60:8399756e1ba1 672 else
MartinGurtner 60:8399756e1ba1 673 {
MartinGurtner 60:8399756e1ba1 674 p_cb->busy = (NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & flags) ? false : true;
MartinGurtner 60:8399756e1ba1 675 }
MartinGurtner 60:8399756e1ba1 676
MartinGurtner 60:8399756e1ba1 677 if (flags & NRF_DRV_TWI_FLAG_HOLD_XFER)
MartinGurtner 60:8399756e1ba1 678 {
MartinGurtner 60:8399756e1ba1 679 err_code = NRF_ERROR_NOT_SUPPORTED;
MartinGurtner 60:8399756e1ba1 680 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 681 return err_code;
MartinGurtner 60:8399756e1ba1 682 }
MartinGurtner 60:8399756e1ba1 683
MartinGurtner 60:8399756e1ba1 684 p_cb->flags = flags;
MartinGurtner 60:8399756e1ba1 685 p_cb->xfer_desc = *p_xfer_desc;
MartinGurtner 60:8399756e1ba1 686 p_cb->curr_length = p_xfer_desc->primary_length;
MartinGurtner 60:8399756e1ba1 687 p_cb->p_curr_buf = p_xfer_desc->p_primary_buf;
MartinGurtner 60:8399756e1ba1 688 nrf_twi_address_set(p_twi, p_xfer_desc->address);
MartinGurtner 60:8399756e1ba1 689
MartinGurtner 60:8399756e1ba1 690 if (p_xfer_desc->type != NRF_DRV_TWI_XFER_RX)
MartinGurtner 60:8399756e1ba1 691 {
MartinGurtner 60:8399756e1ba1 692 p_cb->curr_no_stop = ((p_xfer_desc->type == NRF_DRV_TWI_XFER_TX) &&
MartinGurtner 60:8399756e1ba1 693 !(flags & NRF_DRV_TWI_FLAG_TX_NO_STOP)) ? false : true;
MartinGurtner 60:8399756e1ba1 694
MartinGurtner 60:8399756e1ba1 695 err_code = twi_tx_start_transfer(p_cb, p_twi, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length, p_cb->curr_no_stop);
MartinGurtner 60:8399756e1ba1 696 }
MartinGurtner 60:8399756e1ba1 697 else
MartinGurtner 60:8399756e1ba1 698 {
MartinGurtner 60:8399756e1ba1 699 p_cb->curr_no_stop = false;
MartinGurtner 60:8399756e1ba1 700
MartinGurtner 60:8399756e1ba1 701 err_code = twi_rx_start_transfer(p_cb, p_twi, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
MartinGurtner 60:8399756e1ba1 702 }
MartinGurtner 60:8399756e1ba1 703 if (p_cb->handler == NULL)
MartinGurtner 60:8399756e1ba1 704 {
MartinGurtner 60:8399756e1ba1 705 p_cb->busy = false;
MartinGurtner 60:8399756e1ba1 706 }
MartinGurtner 60:8399756e1ba1 707 return err_code;
MartinGurtner 60:8399756e1ba1 708 }
MartinGurtner 60:8399756e1ba1 709 #endif
MartinGurtner 60:8399756e1ba1 710
MartinGurtner 60:8399756e1ba1 711 // modification for mbed-os
MartinGurtner 60:8399756e1ba1 712 #if __MBED__
MartinGurtner 60:8399756e1ba1 713 bool nrf_drv_twi_is_busy(nrf_drv_twi_t const * p_instance)
MartinGurtner 60:8399756e1ba1 714 {
MartinGurtner 60:8399756e1ba1 715 twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
MartinGurtner 60:8399756e1ba1 716 return p_cb->busy;
MartinGurtner 60:8399756e1ba1 717 }
MartinGurtner 60:8399756e1ba1 718 #endif
MartinGurtner 60:8399756e1ba1 719
MartinGurtner 60:8399756e1ba1 720 #ifdef TWIM_IN_USE
MartinGurtner 60:8399756e1ba1 721
MartinGurtner 60:8399756e1ba1 722
MartinGurtner 60:8399756e1ba1 723 __STATIC_INLINE void twim_list_enable_handle(NRF_TWIM_Type * p_twim, uint32_t flags)
MartinGurtner 60:8399756e1ba1 724 {
MartinGurtner 60:8399756e1ba1 725 if (NRF_DRV_TWI_FLAG_TX_POSTINC & flags)
MartinGurtner 60:8399756e1ba1 726 {
MartinGurtner 60:8399756e1ba1 727 nrf_twim_tx_list_enable(p_twim);
MartinGurtner 60:8399756e1ba1 728 }
MartinGurtner 60:8399756e1ba1 729 else
MartinGurtner 60:8399756e1ba1 730 {
MartinGurtner 60:8399756e1ba1 731 nrf_twim_tx_list_disable(p_twim);
MartinGurtner 60:8399756e1ba1 732 }
MartinGurtner 60:8399756e1ba1 733
MartinGurtner 60:8399756e1ba1 734 if (NRF_DRV_TWI_FLAG_RX_POSTINC & flags)
MartinGurtner 60:8399756e1ba1 735 {
MartinGurtner 60:8399756e1ba1 736 nrf_twim_rx_list_enable(p_twim);
MartinGurtner 60:8399756e1ba1 737 }
MartinGurtner 60:8399756e1ba1 738 else
MartinGurtner 60:8399756e1ba1 739 {
MartinGurtner 60:8399756e1ba1 740 nrf_twim_rx_list_disable(p_twim);
MartinGurtner 60:8399756e1ba1 741 }
MartinGurtner 60:8399756e1ba1 742 }
MartinGurtner 60:8399756e1ba1 743 __STATIC_INLINE ret_code_t twim_xfer(twi_control_block_t * p_cb,
MartinGurtner 60:8399756e1ba1 744 NRF_TWIM_Type * p_twim,
MartinGurtner 60:8399756e1ba1 745 nrf_drv_twi_xfer_desc_t const * p_xfer_desc,
MartinGurtner 60:8399756e1ba1 746 uint32_t flags)
MartinGurtner 60:8399756e1ba1 747 {
MartinGurtner 60:8399756e1ba1 748 ret_code_t err_code = NRF_SUCCESS;
MartinGurtner 60:8399756e1ba1 749 nrf_twim_task_t start_task = NRF_TWIM_TASK_STARTTX;
MartinGurtner 60:8399756e1ba1 750 nrf_twim_event_t evt_to_wait = NRF_TWIM_EVENT_STOPPED;
MartinGurtner 60:8399756e1ba1 751
MartinGurtner 60:8399756e1ba1 752 if (!nrf_drv_is_in_RAM(p_xfer_desc->p_primary_buf))
MartinGurtner 60:8399756e1ba1 753 {
MartinGurtner 60:8399756e1ba1 754 err_code = NRF_ERROR_INVALID_ADDR;
MartinGurtner 60:8399756e1ba1 755 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 756 return err_code;
MartinGurtner 60:8399756e1ba1 757 }
MartinGurtner 60:8399756e1ba1 758 /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */
MartinGurtner 60:8399756e1ba1 759 nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT);
MartinGurtner 60:8399756e1ba1 760 if (p_cb->busy)
MartinGurtner 60:8399756e1ba1 761 {
MartinGurtner 60:8399756e1ba1 762 nrf_twim_int_enable(p_twim, p_cb->int_mask);
MartinGurtner 60:8399756e1ba1 763 err_code = NRF_ERROR_BUSY;
MartinGurtner 60:8399756e1ba1 764 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 765 return err_code;
MartinGurtner 60:8399756e1ba1 766 }
MartinGurtner 60:8399756e1ba1 767 else
MartinGurtner 60:8399756e1ba1 768 {
MartinGurtner 60:8399756e1ba1 769 p_cb->busy = ((NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & flags) ||
MartinGurtner 60:8399756e1ba1 770 (NRF_DRV_TWI_FLAG_REPEATED_XFER & flags)) ? false: true;
MartinGurtner 60:8399756e1ba1 771 }
MartinGurtner 60:8399756e1ba1 772
MartinGurtner 60:8399756e1ba1 773 p_cb->xfer_desc = *p_xfer_desc;
MartinGurtner 60:8399756e1ba1 774 p_cb->repeated = (flags & NRF_DRV_TWI_FLAG_REPEATED_XFER) ? true : false;
MartinGurtner 60:8399756e1ba1 775 nrf_twim_address_set(p_twim, p_xfer_desc->address);
MartinGurtner 60:8399756e1ba1 776
MartinGurtner 60:8399756e1ba1 777 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
MartinGurtner 60:8399756e1ba1 778 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
MartinGurtner 60:8399756e1ba1 779
MartinGurtner 60:8399756e1ba1 780 twim_list_enable_handle(p_twim, flags);
MartinGurtner 60:8399756e1ba1 781 switch (p_xfer_desc->type)
MartinGurtner 60:8399756e1ba1 782 {
MartinGurtner 60:8399756e1ba1 783 case NRF_DRV_TWI_XFER_TXTX:
MartinGurtner 60:8399756e1ba1 784 ASSERT(!(flags & NRF_DRV_TWI_FLAG_REPEATED_XFER));
MartinGurtner 60:8399756e1ba1 785 ASSERT(!(flags & NRF_DRV_TWI_FLAG_HOLD_XFER));
MartinGurtner 60:8399756e1ba1 786 ASSERT(!(flags & NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER));
MartinGurtner 60:8399756e1ba1 787 if (!nrf_drv_is_in_RAM(p_xfer_desc->p_secondary_buf))
MartinGurtner 60:8399756e1ba1 788 {
MartinGurtner 60:8399756e1ba1 789 err_code = NRF_ERROR_INVALID_ADDR;
MartinGurtner 60:8399756e1ba1 790 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 791 return err_code;
MartinGurtner 60:8399756e1ba1 792 }
MartinGurtner 60:8399756e1ba1 793 nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
MartinGurtner 60:8399756e1ba1 794 nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
MartinGurtner 60:8399756e1ba1 795 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
MartinGurtner 60:8399756e1ba1 796 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
MartinGurtner 60:8399756e1ba1 797 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
MartinGurtner 60:8399756e1ba1 798 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
MartinGurtner 60:8399756e1ba1 799 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
MartinGurtner 60:8399756e1ba1 800 while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED))
MartinGurtner 60:8399756e1ba1 801 {}
MartinGurtner 60:8399756e1ba1 802 NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_TXSTARTED));
MartinGurtner 60:8399756e1ba1 803 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
MartinGurtner 60:8399756e1ba1 804 nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
MartinGurtner 60:8399756e1ba1 805 p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
MartinGurtner 60:8399756e1ba1 806 break;
MartinGurtner 60:8399756e1ba1 807 case NRF_DRV_TWI_XFER_TXRX:
MartinGurtner 60:8399756e1ba1 808 nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
MartinGurtner 60:8399756e1ba1 809 if (!nrf_drv_is_in_RAM(p_xfer_desc->p_secondary_buf))
MartinGurtner 60:8399756e1ba1 810 {
MartinGurtner 60:8399756e1ba1 811 err_code = NRF_ERROR_INVALID_ADDR;
MartinGurtner 60:8399756e1ba1 812 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 813 return err_code;
MartinGurtner 60:8399756e1ba1 814 }
MartinGurtner 60:8399756e1ba1 815 nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
MartinGurtner 60:8399756e1ba1 816 nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK |
MartinGurtner 60:8399756e1ba1 817 NRF_TWIM_SHORT_LASTRX_STOP_MASK);
MartinGurtner 60:8399756e1ba1 818 p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
MartinGurtner 60:8399756e1ba1 819 break;
MartinGurtner 60:8399756e1ba1 820 case NRF_DRV_TWI_XFER_TX:
MartinGurtner 60:8399756e1ba1 821 nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
MartinGurtner 60:8399756e1ba1 822 if (NRF_DRV_TWI_FLAG_TX_NO_STOP & flags)
MartinGurtner 60:8399756e1ba1 823 {
MartinGurtner 60:8399756e1ba1 824 nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
MartinGurtner 60:8399756e1ba1 825 p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
MartinGurtner 60:8399756e1ba1 826 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
MartinGurtner 60:8399756e1ba1 827 evt_to_wait = NRF_TWIM_EVENT_SUSPENDED;
MartinGurtner 60:8399756e1ba1 828 }
MartinGurtner 60:8399756e1ba1 829 else
MartinGurtner 60:8399756e1ba1 830 {
MartinGurtner 60:8399756e1ba1 831 nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
MartinGurtner 60:8399756e1ba1 832 p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
MartinGurtner 60:8399756e1ba1 833 }
MartinGurtner 60:8399756e1ba1 834 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
MartinGurtner 60:8399756e1ba1 835 break;
MartinGurtner 60:8399756e1ba1 836 case NRF_DRV_TWI_XFER_RX:
MartinGurtner 60:8399756e1ba1 837 nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
MartinGurtner 60:8399756e1ba1 838 nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK);
MartinGurtner 60:8399756e1ba1 839 p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
MartinGurtner 60:8399756e1ba1 840 start_task = NRF_TWIM_TASK_STARTRX;
MartinGurtner 60:8399756e1ba1 841 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
MartinGurtner 60:8399756e1ba1 842 break;
MartinGurtner 60:8399756e1ba1 843 default:
MartinGurtner 60:8399756e1ba1 844 err_code = NRF_ERROR_INVALID_PARAM;
MartinGurtner 60:8399756e1ba1 845 break;
MartinGurtner 60:8399756e1ba1 846 }
MartinGurtner 60:8399756e1ba1 847
MartinGurtner 60:8399756e1ba1 848 if (!(flags & NRF_DRV_TWI_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRF_DRV_TWI_XFER_TXTX))
MartinGurtner 60:8399756e1ba1 849 {
MartinGurtner 60:8399756e1ba1 850 nrf_twim_task_trigger(p_twim, start_task);
MartinGurtner 60:8399756e1ba1 851 }
MartinGurtner 60:8399756e1ba1 852
MartinGurtner 60:8399756e1ba1 853 if (p_cb->handler)
MartinGurtner 60:8399756e1ba1 854 {
MartinGurtner 60:8399756e1ba1 855 if (flags & NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER)
MartinGurtner 60:8399756e1ba1 856 {
MartinGurtner 60:8399756e1ba1 857 p_cb->int_mask = NRF_TWIM_INT_ERROR_MASK;
MartinGurtner 60:8399756e1ba1 858 }
MartinGurtner 60:8399756e1ba1 859 nrf_twim_int_enable(p_twim, p_cb->int_mask);
MartinGurtner 60:8399756e1ba1 860 }
MartinGurtner 60:8399756e1ba1 861 else
MartinGurtner 60:8399756e1ba1 862 {
MartinGurtner 60:8399756e1ba1 863 while (!nrf_twim_event_check(p_twim, evt_to_wait))
MartinGurtner 60:8399756e1ba1 864 {
MartinGurtner 60:8399756e1ba1 865 if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
MartinGurtner 60:8399756e1ba1 866 {
MartinGurtner 60:8399756e1ba1 867 NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
MartinGurtner 60:8399756e1ba1 868 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
MartinGurtner 60:8399756e1ba1 869 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
MartinGurtner 60:8399756e1ba1 870 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
MartinGurtner 60:8399756e1ba1 871 evt_to_wait = NRF_TWIM_EVENT_STOPPED;
MartinGurtner 60:8399756e1ba1 872 }
MartinGurtner 60:8399756e1ba1 873 }
MartinGurtner 60:8399756e1ba1 874
MartinGurtner 60:8399756e1ba1 875 uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim);
MartinGurtner 60:8399756e1ba1 876
MartinGurtner 60:8399756e1ba1 877 p_cb->busy = false;
MartinGurtner 60:8399756e1ba1 878
MartinGurtner 60:8399756e1ba1 879 if (errorsrc)
MartinGurtner 60:8399756e1ba1 880 {
MartinGurtner 60:8399756e1ba1 881 err_code = twi_process_error(errorsrc);
MartinGurtner 60:8399756e1ba1 882 }
MartinGurtner 60:8399756e1ba1 883 }
MartinGurtner 60:8399756e1ba1 884 return err_code;
MartinGurtner 60:8399756e1ba1 885 }
MartinGurtner 60:8399756e1ba1 886 #endif
MartinGurtner 60:8399756e1ba1 887
MartinGurtner 60:8399756e1ba1 888 ret_code_t nrf_drv_twi_xfer(nrf_drv_twi_t const * p_instance,
MartinGurtner 60:8399756e1ba1 889 nrf_drv_twi_xfer_desc_t const * p_xfer_desc,
MartinGurtner 60:8399756e1ba1 890 uint32_t flags)
MartinGurtner 60:8399756e1ba1 891 {
MartinGurtner 60:8399756e1ba1 892
MartinGurtner 60:8399756e1ba1 893 ret_code_t err_code = NRF_SUCCESS;
MartinGurtner 60:8399756e1ba1 894 twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
MartinGurtner 60:8399756e1ba1 895
MartinGurtner 60:8399756e1ba1 896 // TXRX and TXTX transfers are support only in non-blocking mode.
MartinGurtner 60:8399756e1ba1 897 ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRF_DRV_TWI_XFER_TXRX)));
MartinGurtner 60:8399756e1ba1 898 ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRF_DRV_TWI_XFER_TXTX)));
MartinGurtner 60:8399756e1ba1 899
MartinGurtner 60:8399756e1ba1 900 NRF_LOG_INFO("Transfer type: %s.\r\n", (uint32_t)TRANSFER_TO_STR(p_xfer_desc->type));
MartinGurtner 60:8399756e1ba1 901 NRF_LOG_INFO("Transfer buffers length: primary: %d, secondary: %d.\r\n", p_xfer_desc->primary_length, p_xfer_desc->secondary_length);
MartinGurtner 60:8399756e1ba1 902 NRF_LOG_DEBUG("Primary buffer data:\r\n");
MartinGurtner 60:8399756e1ba1 903 NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length * sizeof(p_xfer_desc->p_primary_buf));
MartinGurtner 60:8399756e1ba1 904 NRF_LOG_DEBUG("Secondary buffer data:\r\n");
MartinGurtner 60:8399756e1ba1 905 NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length * sizeof(p_xfer_desc->p_secondary_buf));
MartinGurtner 60:8399756e1ba1 906
MartinGurtner 60:8399756e1ba1 907 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 908 (
MartinGurtner 60:8399756e1ba1 909
MartinGurtner 60:8399756e1ba1 910 err_code = twim_xfer(p_cb, (NRF_TWIM_Type *)p_instance->reg.p_twim, p_xfer_desc, flags);
MartinGurtner 60:8399756e1ba1 911 )
MartinGurtner 60:8399756e1ba1 912 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 913 (
MartinGurtner 60:8399756e1ba1 914 if ( (NRF_DRV_TWI_FLAG_TX_POSTINC | NRF_DRV_TWI_FLAG_RX_POSTINC) & flags)
MartinGurtner 60:8399756e1ba1 915 {
MartinGurtner 60:8399756e1ba1 916 err_code = NRF_ERROR_NOT_SUPPORTED;
MartinGurtner 60:8399756e1ba1 917 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 918 return err_code;
MartinGurtner 60:8399756e1ba1 919 }
MartinGurtner 60:8399756e1ba1 920
MartinGurtner 60:8399756e1ba1 921 err_code = twi_xfer(p_cb, (NRF_TWI_Type *)p_instance->reg.p_twi, p_xfer_desc, flags);
MartinGurtner 60:8399756e1ba1 922 )
MartinGurtner 60:8399756e1ba1 923 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
MartinGurtner 60:8399756e1ba1 924 return err_code;
MartinGurtner 60:8399756e1ba1 925 }
MartinGurtner 60:8399756e1ba1 926
MartinGurtner 60:8399756e1ba1 927 ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance,
MartinGurtner 60:8399756e1ba1 928 uint8_t address,
MartinGurtner 60:8399756e1ba1 929 uint8_t const * p_data,
MartinGurtner 60:8399756e1ba1 930 uint8_t length,
MartinGurtner 60:8399756e1ba1 931 bool no_stop)
MartinGurtner 60:8399756e1ba1 932 {
MartinGurtner 60:8399756e1ba1 933 nrf_drv_twi_xfer_desc_t xfer = NRF_DRV_TWI_XFER_DESC_TX(address, (uint8_t*)p_data, length);
MartinGurtner 60:8399756e1ba1 934
MartinGurtner 60:8399756e1ba1 935 return nrf_drv_twi_xfer(p_instance, &xfer, no_stop ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0);
MartinGurtner 60:8399756e1ba1 936 }
MartinGurtner 60:8399756e1ba1 937
MartinGurtner 60:8399756e1ba1 938 ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * p_instance,
MartinGurtner 60:8399756e1ba1 939 uint8_t address,
MartinGurtner 60:8399756e1ba1 940 uint8_t * p_data,
MartinGurtner 60:8399756e1ba1 941 uint8_t length)
MartinGurtner 60:8399756e1ba1 942 {
MartinGurtner 60:8399756e1ba1 943 nrf_drv_twi_xfer_desc_t xfer = NRF_DRV_TWI_XFER_DESC_RX(address, p_data, length);
MartinGurtner 60:8399756e1ba1 944 return nrf_drv_twi_xfer(p_instance, &xfer, 0);
MartinGurtner 60:8399756e1ba1 945 }
MartinGurtner 60:8399756e1ba1 946
MartinGurtner 60:8399756e1ba1 947 uint32_t nrf_drv_twi_data_count_get(nrf_drv_twi_t const * const p_instance)
MartinGurtner 60:8399756e1ba1 948 {
MartinGurtner 60:8399756e1ba1 949 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 950 (
MartinGurtner 60:8399756e1ba1 951 ASSERT(false);
MartinGurtner 60:8399756e1ba1 952 return 0;
MartinGurtner 60:8399756e1ba1 953 )
MartinGurtner 60:8399756e1ba1 954 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 955 (
MartinGurtner 60:8399756e1ba1 956 return m_cb[p_instance->drv_inst_idx].bytes_transferred;
MartinGurtner 60:8399756e1ba1 957 )
MartinGurtner 60:8399756e1ba1 958 }
MartinGurtner 60:8399756e1ba1 959 uint32_t nrf_drv_twi_start_task_get(nrf_drv_twi_t const * p_instance, nrf_drv_twi_xfer_type_t xfer_type)
MartinGurtner 60:8399756e1ba1 960 {
MartinGurtner 60:8399756e1ba1 961 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 962 (
MartinGurtner 60:8399756e1ba1 963 return (uint32_t)nrf_twim_task_address_get(p_instance->reg.p_twim,
MartinGurtner 60:8399756e1ba1 964 (xfer_type != NRF_DRV_TWI_XFER_RX) ? NRF_TWIM_TASK_STARTTX : NRF_TWIM_TASK_STARTRX);
MartinGurtner 60:8399756e1ba1 965 )
MartinGurtner 60:8399756e1ba1 966 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 967 (
MartinGurtner 60:8399756e1ba1 968 return (uint32_t)nrf_twi_task_address_get(p_instance->reg.p_twi,
MartinGurtner 60:8399756e1ba1 969 (xfer_type != NRF_DRV_TWI_XFER_RX) ? NRF_TWI_TASK_STARTTX : NRF_TWI_TASK_STARTRX);
MartinGurtner 60:8399756e1ba1 970 )
MartinGurtner 60:8399756e1ba1 971 }
MartinGurtner 60:8399756e1ba1 972
MartinGurtner 60:8399756e1ba1 973 uint32_t nrf_drv_twi_stopped_event_get(nrf_drv_twi_t const * p_instance)
MartinGurtner 60:8399756e1ba1 974 {
MartinGurtner 60:8399756e1ba1 975 CODE_FOR_TWIM
MartinGurtner 60:8399756e1ba1 976 (
MartinGurtner 60:8399756e1ba1 977 return (uint32_t)nrf_twim_event_address_get(p_instance->reg.p_twim, NRF_TWIM_EVENT_STOPPED);
MartinGurtner 60:8399756e1ba1 978 )
MartinGurtner 60:8399756e1ba1 979 CODE_FOR_TWI
MartinGurtner 60:8399756e1ba1 980 (
MartinGurtner 60:8399756e1ba1 981 return (uint32_t)nrf_twi_event_address_get(p_instance->reg.p_twi, NRF_TWI_EVENT_STOPPED);
MartinGurtner 60:8399756e1ba1 982 )
MartinGurtner 60:8399756e1ba1 983 }
MartinGurtner 60:8399756e1ba1 984
MartinGurtner 60:8399756e1ba1 985 #ifdef TWIM_IN_USE
MartinGurtner 60:8399756e1ba1 986 static void irq_handler_twim(NRF_TWIM_Type * p_twim, twi_control_block_t * p_cb)
MartinGurtner 60:8399756e1ba1 987 {
MartinGurtner 60:8399756e1ba1 988 ASSERT(p_cb->handler);
MartinGurtner 60:8399756e1ba1 989
MartinGurtner 60:8399756e1ba1 990 if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
MartinGurtner 60:8399756e1ba1 991 {
MartinGurtner 60:8399756e1ba1 992 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
MartinGurtner 60:8399756e1ba1 993 NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
MartinGurtner 60:8399756e1ba1 994 if (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
MartinGurtner 60:8399756e1ba1 995 {
MartinGurtner 60:8399756e1ba1 996 nrf_twim_int_disable(p_twim, p_cb->int_mask);
MartinGurtner 60:8399756e1ba1 997 p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
MartinGurtner 60:8399756e1ba1 998 nrf_twim_int_enable(p_twim, p_cb->int_mask);
MartinGurtner 60:8399756e1ba1 999
MartinGurtner 60:8399756e1ba1 1000 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
MartinGurtner 60:8399756e1ba1 1001 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
MartinGurtner 60:8399756e1ba1 1002 return;
MartinGurtner 60:8399756e1ba1 1003 }
MartinGurtner 60:8399756e1ba1 1004 }
MartinGurtner 60:8399756e1ba1 1005
MartinGurtner 60:8399756e1ba1 1006 nrf_drv_twi_evt_t event;
MartinGurtner 60:8399756e1ba1 1007
MartinGurtner 60:8399756e1ba1 1008 if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
MartinGurtner 60:8399756e1ba1 1009 {
MartinGurtner 60:8399756e1ba1 1010 NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED));
MartinGurtner 60:8399756e1ba1 1011 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
MartinGurtner 60:8399756e1ba1 1012 event.xfer_desc = p_cb->xfer_desc;
MartinGurtner 60:8399756e1ba1 1013 if (p_cb->error)
MartinGurtner 60:8399756e1ba1 1014 {
MartinGurtner 60:8399756e1ba1 1015
MartinGurtner 60:8399756e1ba1 1016 event.xfer_desc.primary_length = (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_RX) ?
MartinGurtner 60:8399756e1ba1 1017 (uint8_t)nrf_twim_rxd_amount_get(p_twim) : (uint8_t)nrf_twim_txd_amount_get(p_twim);
MartinGurtner 60:8399756e1ba1 1018 event.xfer_desc.secondary_length = (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX) ?
MartinGurtner 60:8399756e1ba1 1019 (uint8_t)nrf_twim_rxd_amount_get(p_twim) : (uint8_t)nrf_twim_txd_amount_get(p_twim);
MartinGurtner 60:8399756e1ba1 1020
MartinGurtner 60:8399756e1ba1 1021 }
MartinGurtner 60:8399756e1ba1 1022 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
MartinGurtner 60:8399756e1ba1 1023 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX);
MartinGurtner 60:8399756e1ba1 1024 if (!p_cb->repeated || p_cb->error)
MartinGurtner 60:8399756e1ba1 1025 {
MartinGurtner 60:8399756e1ba1 1026 nrf_twim_shorts_set(p_twim, 0);
MartinGurtner 60:8399756e1ba1 1027 p_cb->int_mask = 0;
MartinGurtner 60:8399756e1ba1 1028 nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT);
MartinGurtner 60:8399756e1ba1 1029 }
MartinGurtner 60:8399756e1ba1 1030 }
MartinGurtner 60:8399756e1ba1 1031 else
MartinGurtner 60:8399756e1ba1 1032 {
MartinGurtner 60:8399756e1ba1 1033 nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
MartinGurtner 60:8399756e1ba1 1034 NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_SUSPENDED));
MartinGurtner 60:8399756e1ba1 1035 if (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TX)
MartinGurtner 60:8399756e1ba1 1036 {
MartinGurtner 60:8399756e1ba1 1037 event.xfer_desc = p_cb->xfer_desc;
MartinGurtner 60:8399756e1ba1 1038 if (!p_cb->repeated)
MartinGurtner 60:8399756e1ba1 1039 {
MartinGurtner 60:8399756e1ba1 1040 nrf_twim_shorts_set(p_twim, 0);
MartinGurtner 60:8399756e1ba1 1041 p_cb->int_mask = 0;
MartinGurtner 60:8399756e1ba1 1042 nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT);
MartinGurtner 60:8399756e1ba1 1043 }
MartinGurtner 60:8399756e1ba1 1044 }
MartinGurtner 60:8399756e1ba1 1045 else
MartinGurtner 60:8399756e1ba1 1046 {
MartinGurtner 60:8399756e1ba1 1047 nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
MartinGurtner 60:8399756e1ba1 1048 p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
MartinGurtner 60:8399756e1ba1 1049 nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT);
MartinGurtner 60:8399756e1ba1 1050 nrf_twim_int_enable(p_twim, p_cb->int_mask);
MartinGurtner 60:8399756e1ba1 1051 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
MartinGurtner 60:8399756e1ba1 1052 nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
MartinGurtner 60:8399756e1ba1 1053 return;
MartinGurtner 60:8399756e1ba1 1054 }
MartinGurtner 60:8399756e1ba1 1055 }
MartinGurtner 60:8399756e1ba1 1056
MartinGurtner 60:8399756e1ba1 1057 uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim);
MartinGurtner 60:8399756e1ba1 1058 if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK)
MartinGurtner 60:8399756e1ba1 1059 {
MartinGurtner 60:8399756e1ba1 1060 event.type = NRF_DRV_TWI_EVT_ADDRESS_NACK;
MartinGurtner 60:8399756e1ba1 1061 NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_ADDRESS_NACK));
MartinGurtner 60:8399756e1ba1 1062 }
MartinGurtner 60:8399756e1ba1 1063 else if (errorsrc & NRF_TWIM_ERROR_DATA_NACK)
MartinGurtner 60:8399756e1ba1 1064 {
MartinGurtner 60:8399756e1ba1 1065 event.type = NRF_DRV_TWI_EVT_DATA_NACK;
MartinGurtner 60:8399756e1ba1 1066 NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DATA_NACK));
MartinGurtner 60:8399756e1ba1 1067 }
MartinGurtner 60:8399756e1ba1 1068 else
MartinGurtner 60:8399756e1ba1 1069 {
MartinGurtner 60:8399756e1ba1 1070 event.type = NRF_DRV_TWI_EVT_DONE;
MartinGurtner 60:8399756e1ba1 1071 NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DONE));
MartinGurtner 60:8399756e1ba1 1072 }
MartinGurtner 60:8399756e1ba1 1073
MartinGurtner 60:8399756e1ba1 1074 if (!p_cb->repeated)
MartinGurtner 60:8399756e1ba1 1075 {
MartinGurtner 60:8399756e1ba1 1076 p_cb->busy = false;
MartinGurtner 60:8399756e1ba1 1077 }
MartinGurtner 60:8399756e1ba1 1078 p_cb->handler(&event, p_cb->p_context);
MartinGurtner 60:8399756e1ba1 1079 }
MartinGurtner 60:8399756e1ba1 1080 #endif // TWIM_IN_USE
MartinGurtner 60:8399756e1ba1 1081
MartinGurtner 60:8399756e1ba1 1082 #ifdef TWI_IN_USE
MartinGurtner 60:8399756e1ba1 1083 static void irq_handler_twi(NRF_TWI_Type * p_twi, twi_control_block_t * p_cb)
MartinGurtner 60:8399756e1ba1 1084 {
MartinGurtner 60:8399756e1ba1 1085 ASSERT(p_cb->handler);
MartinGurtner 60:8399756e1ba1 1086
MartinGurtner 60:8399756e1ba1 1087 if (twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, p_cb->p_curr_buf, p_cb->curr_length, p_cb->curr_no_stop ))
MartinGurtner 60:8399756e1ba1 1088 {
MartinGurtner 60:8399756e1ba1 1089 return;
MartinGurtner 60:8399756e1ba1 1090 }
MartinGurtner 60:8399756e1ba1 1091
MartinGurtner 60:8399756e1ba1 1092 if (!p_cb->error &&
MartinGurtner 60:8399756e1ba1 1093 ((p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX) ||
MartinGurtner 60:8399756e1ba1 1094 (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX)) &&
MartinGurtner 60:8399756e1ba1 1095 p_cb->p_curr_buf == p_cb->xfer_desc.p_primary_buf)
MartinGurtner 60:8399756e1ba1 1096 {
MartinGurtner 60:8399756e1ba1 1097 p_cb->p_curr_buf = p_cb->xfer_desc.p_secondary_buf;
MartinGurtner 60:8399756e1ba1 1098 p_cb->curr_length = p_cb->xfer_desc.secondary_length;
MartinGurtner 60:8399756e1ba1 1099 p_cb->curr_no_stop = (p_cb->flags & NRF_DRV_TWI_FLAG_TX_NO_STOP);
MartinGurtner 60:8399756e1ba1 1100
MartinGurtner 60:8399756e1ba1 1101 if (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX)
MartinGurtner 60:8399756e1ba1 1102 {
MartinGurtner 60:8399756e1ba1 1103 (void)twi_tx_start_transfer(p_cb, p_twi, p_cb->p_curr_buf, p_cb->curr_length, p_cb->curr_no_stop);
MartinGurtner 60:8399756e1ba1 1104 }
MartinGurtner 60:8399756e1ba1 1105 else
MartinGurtner 60:8399756e1ba1 1106 {
MartinGurtner 60:8399756e1ba1 1107 (void)twi_rx_start_transfer(p_cb, p_twi, p_cb->p_curr_buf, p_cb->curr_length);
MartinGurtner 60:8399756e1ba1 1108 }
MartinGurtner 60:8399756e1ba1 1109 }
MartinGurtner 60:8399756e1ba1 1110 else
MartinGurtner 60:8399756e1ba1 1111 {
MartinGurtner 60:8399756e1ba1 1112 nrf_drv_twi_evt_t event;
MartinGurtner 60:8399756e1ba1 1113 event.xfer_desc = p_cb->xfer_desc;
MartinGurtner 60:8399756e1ba1 1114
MartinGurtner 60:8399756e1ba1 1115 if (p_cb->error)
MartinGurtner 60:8399756e1ba1 1116 {
MartinGurtner 60:8399756e1ba1 1117 uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi);
MartinGurtner 60:8399756e1ba1 1118 if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK)
MartinGurtner 60:8399756e1ba1 1119 {
MartinGurtner 60:8399756e1ba1 1120 event.type = NRF_DRV_TWI_EVT_ADDRESS_NACK;
MartinGurtner 60:8399756e1ba1 1121 NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_ADDRESS_NACK));
MartinGurtner 60:8399756e1ba1 1122 }
MartinGurtner 60:8399756e1ba1 1123 else if (errorsrc & NRF_TWI_ERROR_DATA_NACK)
MartinGurtner 60:8399756e1ba1 1124 {
MartinGurtner 60:8399756e1ba1 1125 event.type = NRF_DRV_TWI_EVT_DATA_NACK;
MartinGurtner 60:8399756e1ba1 1126 NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DATA_NACK));
MartinGurtner 60:8399756e1ba1 1127 }
MartinGurtner 60:8399756e1ba1 1128 }
MartinGurtner 60:8399756e1ba1 1129 else
MartinGurtner 60:8399756e1ba1 1130 {
MartinGurtner 60:8399756e1ba1 1131 event.type = NRF_DRV_TWI_EVT_DONE;
MartinGurtner 60:8399756e1ba1 1132 NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DONE));
MartinGurtner 60:8399756e1ba1 1133 }
MartinGurtner 60:8399756e1ba1 1134
MartinGurtner 60:8399756e1ba1 1135 p_cb->busy = false;
MartinGurtner 60:8399756e1ba1 1136
MartinGurtner 60:8399756e1ba1 1137 if (!(NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & p_cb->flags))
MartinGurtner 60:8399756e1ba1 1138 {
MartinGurtner 60:8399756e1ba1 1139 p_cb->handler(&event, p_cb->p_context);
MartinGurtner 60:8399756e1ba1 1140 }
MartinGurtner 60:8399756e1ba1 1141 }
MartinGurtner 60:8399756e1ba1 1142
MartinGurtner 60:8399756e1ba1 1143 }
MartinGurtner 60:8399756e1ba1 1144 #endif // TWI_IN_USE
MartinGurtner 60:8399756e1ba1 1145
MartinGurtner 60:8399756e1ba1 1146 #if NRF_MODULE_ENABLED(TWI0)
MartinGurtner 60:8399756e1ba1 1147 IRQ_HANDLER(0)
MartinGurtner 60:8399756e1ba1 1148 {
MartinGurtner 60:8399756e1ba1 1149 #if (TWI0_USE_EASY_DMA == 1)
MartinGurtner 60:8399756e1ba1 1150 irq_handler_twim(NRF_TWIM0,
MartinGurtner 60:8399756e1ba1 1151 #else
MartinGurtner 60:8399756e1ba1 1152 irq_handler_twi(NRF_TWI0,
MartinGurtner 60:8399756e1ba1 1153 #endif
MartinGurtner 60:8399756e1ba1 1154 &m_cb[TWI0_INSTANCE_INDEX]);
MartinGurtner 60:8399756e1ba1 1155 }
MartinGurtner 60:8399756e1ba1 1156 #endif // NRF_MODULE_ENABLED(TWI0)
MartinGurtner 60:8399756e1ba1 1157
MartinGurtner 60:8399756e1ba1 1158 #if NRF_MODULE_ENABLED(TWI1)
MartinGurtner 60:8399756e1ba1 1159 IRQ_HANDLER(1)
MartinGurtner 60:8399756e1ba1 1160 {
MartinGurtner 60:8399756e1ba1 1161 #if (TWI1_USE_EASY_DMA == 1)
MartinGurtner 60:8399756e1ba1 1162 irq_handler_twim(NRF_TWIM1,
MartinGurtner 60:8399756e1ba1 1163 #else
MartinGurtner 60:8399756e1ba1 1164 irq_handler_twi(NRF_TWI1,
MartinGurtner 60:8399756e1ba1 1165 #endif
MartinGurtner 60:8399756e1ba1 1166 &m_cb[TWI1_INSTANCE_INDEX]);
MartinGurtner 60:8399756e1ba1 1167 }
MartinGurtner 60:8399756e1ba1 1168 #endif // NRF_MODULE_ENABLED(TWI1)
MartinGurtner 60:8399756e1ba1 1169 #endif // TWI_COUNT
MartinGurtner 60:8399756e1ba1 1170 #endif // NRF_MODULE_ENABLED(TWI)