Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sahilmgandhi 18:6a4db94011d3 1 /**
sahilmgandhi 18:6a4db94011d3 2 * \file
sahilmgandhi 18:6a4db94011d3 3 *
sahilmgandhi 18:6a4db94011d3 4 * \brief Two-Wire Interface (TWI) driver for SAM.
sahilmgandhi 18:6a4db94011d3 5 *
sahilmgandhi 18:6a4db94011d3 6 * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
sahilmgandhi 18:6a4db94011d3 7 *
sahilmgandhi 18:6a4db94011d3 8 * \asf_license_start
sahilmgandhi 18:6a4db94011d3 9 *
sahilmgandhi 18:6a4db94011d3 10 * \page License
sahilmgandhi 18:6a4db94011d3 11 *
sahilmgandhi 18:6a4db94011d3 12 * Redistribution and use in source and binary forms, with or without
sahilmgandhi 18:6a4db94011d3 13 * modification, are permitted provided that the following conditions are met:
sahilmgandhi 18:6a4db94011d3 14 *
sahilmgandhi 18:6a4db94011d3 15 * 1. Redistributions of source code must retain the above copyright notice,
sahilmgandhi 18:6a4db94011d3 16 * this list of conditions and the following disclaimer.
sahilmgandhi 18:6a4db94011d3 17 *
sahilmgandhi 18:6a4db94011d3 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
sahilmgandhi 18:6a4db94011d3 19 * this list of conditions and the following disclaimer in the documentation
sahilmgandhi 18:6a4db94011d3 20 * and/or other materials provided with the distribution.
sahilmgandhi 18:6a4db94011d3 21 *
sahilmgandhi 18:6a4db94011d3 22 * 3. The name of Atmel may not be used to endorse or promote products derived
sahilmgandhi 18:6a4db94011d3 23 * from this software without specific prior written permission.
sahilmgandhi 18:6a4db94011d3 24 *
sahilmgandhi 18:6a4db94011d3 25 * 4. This software may only be redistributed and used in connection with an
sahilmgandhi 18:6a4db94011d3 26 * Atmel microcontroller product.
sahilmgandhi 18:6a4db94011d3 27 *
sahilmgandhi 18:6a4db94011d3 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
sahilmgandhi 18:6a4db94011d3 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
sahilmgandhi 18:6a4db94011d3 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
sahilmgandhi 18:6a4db94011d3 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
sahilmgandhi 18:6a4db94011d3 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sahilmgandhi 18:6a4db94011d3 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sahilmgandhi 18:6a4db94011d3 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sahilmgandhi 18:6a4db94011d3 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
sahilmgandhi 18:6a4db94011d3 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
sahilmgandhi 18:6a4db94011d3 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
sahilmgandhi 18:6a4db94011d3 38 * POSSIBILITY OF SUCH DAMAGE.
sahilmgandhi 18:6a4db94011d3 39 *
sahilmgandhi 18:6a4db94011d3 40 * \asf_license_stop
sahilmgandhi 18:6a4db94011d3 41 *
sahilmgandhi 18:6a4db94011d3 42 */
sahilmgandhi 18:6a4db94011d3 43 /*
sahilmgandhi 18:6a4db94011d3 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
sahilmgandhi 18:6a4db94011d3 45 */
sahilmgandhi 18:6a4db94011d3 46
sahilmgandhi 18:6a4db94011d3 47 #include "twi.h"
sahilmgandhi 18:6a4db94011d3 48
sahilmgandhi 18:6a4db94011d3 49 /// @cond 0
sahilmgandhi 18:6a4db94011d3 50 /**INDENT-OFF**/
sahilmgandhi 18:6a4db94011d3 51 #ifdef __cplusplus
sahilmgandhi 18:6a4db94011d3 52 extern "C" {
sahilmgandhi 18:6a4db94011d3 53 #endif
sahilmgandhi 18:6a4db94011d3 54 /**INDENT-ON**/
sahilmgandhi 18:6a4db94011d3 55 /// @endcond
sahilmgandhi 18:6a4db94011d3 56
sahilmgandhi 18:6a4db94011d3 57 /**
sahilmgandhi 18:6a4db94011d3 58 * \defgroup sam_drivers_twi_group Two-Wire Interface (TWI)
sahilmgandhi 18:6a4db94011d3 59 *
sahilmgandhi 18:6a4db94011d3 60 * Driver for the TWI (Two-Wire Interface). This driver provides access to the main
sahilmgandhi 18:6a4db94011d3 61 * features of the TWI controller.
sahilmgandhi 18:6a4db94011d3 62 * The TWI interconnects components on a unique two-wire bus.
sahilmgandhi 18:6a4db94011d3 63 * The TWI is programmable as a master or a slave with sequential or single-byte access.
sahilmgandhi 18:6a4db94011d3 64 * Multiple master capability is supported.
sahilmgandhi 18:6a4db94011d3 65 *
sahilmgandhi 18:6a4db94011d3 66 * \par Usage
sahilmgandhi 18:6a4db94011d3 67 *
sahilmgandhi 18:6a4db94011d3 68 * -# Enable the TWI peripheral clock in the PMC.
sahilmgandhi 18:6a4db94011d3 69 * -# Enable the required TWI PIOs (see pio.h).
sahilmgandhi 18:6a4db94011d3 70 * -# Enable TWI master mode by calling twi_enable_master_mode if it is a master on the I2C bus.
sahilmgandhi 18:6a4db94011d3 71 * -# Configure the TWI in master mode by calling twi_master_init.
sahilmgandhi 18:6a4db94011d3 72 * -# Send data to a slave device on the I2C bus by calling twi_master_write.
sahilmgandhi 18:6a4db94011d3 73 * -# Receive data from a slave device on the I2C bus by calling the twi_master_read.
sahilmgandhi 18:6a4db94011d3 74 * -# Enable TWI slave mode by calling twi_enable_slave_mode if it is a slave on the I2C bus.
sahilmgandhi 18:6a4db94011d3 75 * -# Configure the TWI in slave mode by calling twi_slave_init.
sahilmgandhi 18:6a4db94011d3 76 *
sahilmgandhi 18:6a4db94011d3 77 * @{
sahilmgandhi 18:6a4db94011d3 78 */
sahilmgandhi 18:6a4db94011d3 79
sahilmgandhi 18:6a4db94011d3 80 #define I2C_FAST_MODE_SPEED 400000
sahilmgandhi 18:6a4db94011d3 81 #define TWI_CLK_DIVIDER 2
sahilmgandhi 18:6a4db94011d3 82 #define TWI_CLK_CALC_ARGU 4
sahilmgandhi 18:6a4db94011d3 83 #define TWI_CLK_DIV_MAX 0xFF
sahilmgandhi 18:6a4db94011d3 84 #define TWI_CLK_DIV_MIN 7
sahilmgandhi 18:6a4db94011d3 85
sahilmgandhi 18:6a4db94011d3 86 #define TWI_WP_KEY_VALUE TWI_WPMR_WPKEY_PASSWD
sahilmgandhi 18:6a4db94011d3 87
sahilmgandhi 18:6a4db94011d3 88 /**
sahilmgandhi 18:6a4db94011d3 89 * \brief Enable TWI master mode.
sahilmgandhi 18:6a4db94011d3 90 *
sahilmgandhi 18:6a4db94011d3 91 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 92 */
sahilmgandhi 18:6a4db94011d3 93 void twi_enable_master_mode(Twi *p_twi)
sahilmgandhi 18:6a4db94011d3 94 {
sahilmgandhi 18:6a4db94011d3 95 /* Set Master Disable bit and Slave Disable bit */
sahilmgandhi 18:6a4db94011d3 96 p_twi->TWI_CR = TWI_CR_MSDIS;
sahilmgandhi 18:6a4db94011d3 97 p_twi->TWI_CR = TWI_CR_SVDIS;
sahilmgandhi 18:6a4db94011d3 98
sahilmgandhi 18:6a4db94011d3 99 /* Set Master Enable bit */
sahilmgandhi 18:6a4db94011d3 100 p_twi->TWI_CR = TWI_CR_MSEN;
sahilmgandhi 18:6a4db94011d3 101 }
sahilmgandhi 18:6a4db94011d3 102
sahilmgandhi 18:6a4db94011d3 103 /**
sahilmgandhi 18:6a4db94011d3 104 * \brief Disable TWI master mode.
sahilmgandhi 18:6a4db94011d3 105 *
sahilmgandhi 18:6a4db94011d3 106 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 107 */
sahilmgandhi 18:6a4db94011d3 108 void twi_disable_master_mode(Twi *p_twi)
sahilmgandhi 18:6a4db94011d3 109 {
sahilmgandhi 18:6a4db94011d3 110 /* Set Master Disable bit */
sahilmgandhi 18:6a4db94011d3 111 p_twi->TWI_CR = TWI_CR_MSDIS;
sahilmgandhi 18:6a4db94011d3 112 }
sahilmgandhi 18:6a4db94011d3 113
sahilmgandhi 18:6a4db94011d3 114 /**
sahilmgandhi 18:6a4db94011d3 115 * \brief Initialize TWI master mode.
sahilmgandhi 18:6a4db94011d3 116 *
sahilmgandhi 18:6a4db94011d3 117 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 118 * \param p_opt Options for initializing the TWI module (see \ref twi_options_t).
sahilmgandhi 18:6a4db94011d3 119 *
sahilmgandhi 18:6a4db94011d3 120 * \return TWI_SUCCESS if initialization is complete, error code otherwise.
sahilmgandhi 18:6a4db94011d3 121 */
sahilmgandhi 18:6a4db94011d3 122 uint32_t twi_master_init(Twi *p_twi, const twi_options_t *p_opt)
sahilmgandhi 18:6a4db94011d3 123 {
sahilmgandhi 18:6a4db94011d3 124 uint32_t status = TWI_SUCCESS;
sahilmgandhi 18:6a4db94011d3 125
sahilmgandhi 18:6a4db94011d3 126 /* Disable TWI interrupts */
sahilmgandhi 18:6a4db94011d3 127 p_twi->TWI_IDR = ~0UL;
sahilmgandhi 18:6a4db94011d3 128
sahilmgandhi 18:6a4db94011d3 129 /* Dummy read in status register */
sahilmgandhi 18:6a4db94011d3 130 p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 131
sahilmgandhi 18:6a4db94011d3 132 /* Reset TWI peripheral */
sahilmgandhi 18:6a4db94011d3 133 twi_reset(p_twi);
sahilmgandhi 18:6a4db94011d3 134
sahilmgandhi 18:6a4db94011d3 135 twi_enable_master_mode(p_twi);
sahilmgandhi 18:6a4db94011d3 136
sahilmgandhi 18:6a4db94011d3 137 /* Select the speed */
sahilmgandhi 18:6a4db94011d3 138 if (twi_set_speed(p_twi, p_opt->speed, p_opt->master_clk) == FAIL) {
sahilmgandhi 18:6a4db94011d3 139 /* The desired speed setting is rejected */
sahilmgandhi 18:6a4db94011d3 140 status = TWI_INVALID_ARGUMENT;
sahilmgandhi 18:6a4db94011d3 141 }
sahilmgandhi 18:6a4db94011d3 142
sahilmgandhi 18:6a4db94011d3 143 if (p_opt->smbus == 1) {
sahilmgandhi 18:6a4db94011d3 144 p_twi->TWI_CR = TWI_CR_QUICK;
sahilmgandhi 18:6a4db94011d3 145 }
sahilmgandhi 18:6a4db94011d3 146
sahilmgandhi 18:6a4db94011d3 147 return status;
sahilmgandhi 18:6a4db94011d3 148 }
sahilmgandhi 18:6a4db94011d3 149
sahilmgandhi 18:6a4db94011d3 150 /**
sahilmgandhi 18:6a4db94011d3 151 * \brief Set the I2C bus speed in conjunction with the clock frequency.
sahilmgandhi 18:6a4db94011d3 152 *
sahilmgandhi 18:6a4db94011d3 153 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 154 * \param ul_speed The desired I2C bus speed (in Hz).
sahilmgandhi 18:6a4db94011d3 155 * \param ul_mck Main clock of the device (in Hz).
sahilmgandhi 18:6a4db94011d3 156 *
sahilmgandhi 18:6a4db94011d3 157 * \retval PASS New speed setting is accepted.
sahilmgandhi 18:6a4db94011d3 158 * \retval FAIL New speed setting is rejected.
sahilmgandhi 18:6a4db94011d3 159 */
sahilmgandhi 18:6a4db94011d3 160 uint32_t twi_set_speed(Twi *p_twi, uint32_t ul_speed, uint32_t ul_mck)
sahilmgandhi 18:6a4db94011d3 161 {
sahilmgandhi 18:6a4db94011d3 162 uint32_t ckdiv = 0;
sahilmgandhi 18:6a4db94011d3 163 uint32_t c_lh_div;
sahilmgandhi 18:6a4db94011d3 164
sahilmgandhi 18:6a4db94011d3 165 if (ul_speed > I2C_FAST_MODE_SPEED) {
sahilmgandhi 18:6a4db94011d3 166 return FAIL;
sahilmgandhi 18:6a4db94011d3 167 }
sahilmgandhi 18:6a4db94011d3 168
sahilmgandhi 18:6a4db94011d3 169 c_lh_div = ul_mck / (ul_speed * TWI_CLK_DIVIDER) - TWI_CLK_CALC_ARGU;
sahilmgandhi 18:6a4db94011d3 170
sahilmgandhi 18:6a4db94011d3 171 /* cldiv must fit in 8 bits, ckdiv must fit in 3 bits */
sahilmgandhi 18:6a4db94011d3 172 while ((c_lh_div > TWI_CLK_DIV_MAX) && (ckdiv < TWI_CLK_DIV_MIN)) {
sahilmgandhi 18:6a4db94011d3 173 /* Increase clock divider */
sahilmgandhi 18:6a4db94011d3 174 ckdiv++;
sahilmgandhi 18:6a4db94011d3 175 /* Divide cldiv value */
sahilmgandhi 18:6a4db94011d3 176 c_lh_div /= TWI_CLK_DIVIDER;
sahilmgandhi 18:6a4db94011d3 177 }
sahilmgandhi 18:6a4db94011d3 178
sahilmgandhi 18:6a4db94011d3 179 /* set clock waveform generator register */
sahilmgandhi 18:6a4db94011d3 180 p_twi->TWI_CWGR =
sahilmgandhi 18:6a4db94011d3 181 TWI_CWGR_CLDIV(c_lh_div) | TWI_CWGR_CHDIV(c_lh_div) |
sahilmgandhi 18:6a4db94011d3 182 TWI_CWGR_CKDIV(ckdiv);
sahilmgandhi 18:6a4db94011d3 183
sahilmgandhi 18:6a4db94011d3 184 return PASS;
sahilmgandhi 18:6a4db94011d3 185 }
sahilmgandhi 18:6a4db94011d3 186
sahilmgandhi 18:6a4db94011d3 187 /**
sahilmgandhi 18:6a4db94011d3 188 * \brief Test if a chip answers a given I2C address.
sahilmgandhi 18:6a4db94011d3 189 *
sahilmgandhi 18:6a4db94011d3 190 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 191 * \param uc_slave_addr Address of the remote chip to search for.
sahilmgandhi 18:6a4db94011d3 192 *
sahilmgandhi 18:6a4db94011d3 193 * \return TWI_SUCCESS if a chip was found, error code otherwise.
sahilmgandhi 18:6a4db94011d3 194 */
sahilmgandhi 18:6a4db94011d3 195 uint32_t twi_probe(Twi *p_twi, uint8_t uc_slave_addr)
sahilmgandhi 18:6a4db94011d3 196 {
sahilmgandhi 18:6a4db94011d3 197 twi_packet_t packet;
sahilmgandhi 18:6a4db94011d3 198 uint8_t data = 0;
sahilmgandhi 18:6a4db94011d3 199
sahilmgandhi 18:6a4db94011d3 200 /* Data to send */
sahilmgandhi 18:6a4db94011d3 201 packet.buffer = &data;
sahilmgandhi 18:6a4db94011d3 202 /* Data length */
sahilmgandhi 18:6a4db94011d3 203 packet.length = 1;
sahilmgandhi 18:6a4db94011d3 204 /* Slave chip address */
sahilmgandhi 18:6a4db94011d3 205 packet.chip = (uint32_t) uc_slave_addr;
sahilmgandhi 18:6a4db94011d3 206 /* Internal chip address */
sahilmgandhi 18:6a4db94011d3 207 packet.addr[0] = 0;
sahilmgandhi 18:6a4db94011d3 208 /* Address length */
sahilmgandhi 18:6a4db94011d3 209 packet.addr_length = 0;
sahilmgandhi 18:6a4db94011d3 210
sahilmgandhi 18:6a4db94011d3 211 /* Perform a master write access */
sahilmgandhi 18:6a4db94011d3 212 return (twi_master_write(p_twi, &packet));
sahilmgandhi 18:6a4db94011d3 213 }
sahilmgandhi 18:6a4db94011d3 214
sahilmgandhi 18:6a4db94011d3 215
sahilmgandhi 18:6a4db94011d3 216 /**
sahilmgandhi 18:6a4db94011d3 217 * \internal
sahilmgandhi 18:6a4db94011d3 218 * \brief Construct the TWI module address register field
sahilmgandhi 18:6a4db94011d3 219 *
sahilmgandhi 18:6a4db94011d3 220 * The TWI module address register is sent out MSB first. And the size controls
sahilmgandhi 18:6a4db94011d3 221 * which byte is the MSB to start with.
sahilmgandhi 18:6a4db94011d3 222 *
sahilmgandhi 18:6a4db94011d3 223 * Please see the device datasheet for details on this.
sahilmgandhi 18:6a4db94011d3 224 */
sahilmgandhi 18:6a4db94011d3 225 static uint32_t twi_mk_addr(const uint8_t *addr, int len)
sahilmgandhi 18:6a4db94011d3 226 {
sahilmgandhi 18:6a4db94011d3 227 uint32_t val;
sahilmgandhi 18:6a4db94011d3 228
sahilmgandhi 18:6a4db94011d3 229 if (len == 0)
sahilmgandhi 18:6a4db94011d3 230 return 0;
sahilmgandhi 18:6a4db94011d3 231
sahilmgandhi 18:6a4db94011d3 232 val = addr[0];
sahilmgandhi 18:6a4db94011d3 233 if (len > 1) {
sahilmgandhi 18:6a4db94011d3 234 val <<= 8;
sahilmgandhi 18:6a4db94011d3 235 val |= addr[1];
sahilmgandhi 18:6a4db94011d3 236 }
sahilmgandhi 18:6a4db94011d3 237 if (len > 2) {
sahilmgandhi 18:6a4db94011d3 238 val <<= 8;
sahilmgandhi 18:6a4db94011d3 239 val |= addr[2];
sahilmgandhi 18:6a4db94011d3 240 }
sahilmgandhi 18:6a4db94011d3 241 return val;
sahilmgandhi 18:6a4db94011d3 242 }
sahilmgandhi 18:6a4db94011d3 243
sahilmgandhi 18:6a4db94011d3 244 /**
sahilmgandhi 18:6a4db94011d3 245 * \brief Read multiple bytes from a TWI compatible slave device.
sahilmgandhi 18:6a4db94011d3 246 *
sahilmgandhi 18:6a4db94011d3 247 * \note This function will NOT return until all data has been read or error occurs.
sahilmgandhi 18:6a4db94011d3 248 *
sahilmgandhi 18:6a4db94011d3 249 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 250 * \param p_packet Packet information and data (see \ref twi_packet_t).
sahilmgandhi 18:6a4db94011d3 251 *
sahilmgandhi 18:6a4db94011d3 252 * \return TWI_SUCCESS if all bytes were read, error code otherwise.
sahilmgandhi 18:6a4db94011d3 253 */
sahilmgandhi 18:6a4db94011d3 254 uint32_t twi_master_read(Twi *p_twi, twi_packet_t *p_packet)
sahilmgandhi 18:6a4db94011d3 255 {
sahilmgandhi 18:6a4db94011d3 256 uint32_t status;
sahilmgandhi 18:6a4db94011d3 257 uint32_t cnt = p_packet->length;
sahilmgandhi 18:6a4db94011d3 258 uint8_t *buffer = p_packet->buffer;
sahilmgandhi 18:6a4db94011d3 259 uint8_t stop_sent = 0;
sahilmgandhi 18:6a4db94011d3 260 uint32_t timeout = TWI_TIMEOUT;;
sahilmgandhi 18:6a4db94011d3 261
sahilmgandhi 18:6a4db94011d3 262 /* Check argument */
sahilmgandhi 18:6a4db94011d3 263 if (cnt == 0) {
sahilmgandhi 18:6a4db94011d3 264 return TWI_INVALID_ARGUMENT;
sahilmgandhi 18:6a4db94011d3 265 }
sahilmgandhi 18:6a4db94011d3 266
sahilmgandhi 18:6a4db94011d3 267 /* Set read mode, slave address and 3 internal address byte lengths */
sahilmgandhi 18:6a4db94011d3 268 p_twi->TWI_MMR = 0;
sahilmgandhi 18:6a4db94011d3 269 p_twi->TWI_MMR = TWI_MMR_MREAD | TWI_MMR_DADR(p_packet->chip) |
sahilmgandhi 18:6a4db94011d3 270 ((p_packet->addr_length << TWI_MMR_IADRSZ_Pos) &
sahilmgandhi 18:6a4db94011d3 271 TWI_MMR_IADRSZ_Msk);
sahilmgandhi 18:6a4db94011d3 272
sahilmgandhi 18:6a4db94011d3 273 /* Set internal address for remote chip */
sahilmgandhi 18:6a4db94011d3 274 p_twi->TWI_IADR = 0;
sahilmgandhi 18:6a4db94011d3 275 p_twi->TWI_IADR = twi_mk_addr(p_packet->addr, p_packet->addr_length);
sahilmgandhi 18:6a4db94011d3 276
sahilmgandhi 18:6a4db94011d3 277 /* Send a START condition */
sahilmgandhi 18:6a4db94011d3 278 if (cnt == 1) {
sahilmgandhi 18:6a4db94011d3 279 p_twi->TWI_CR = TWI_CR_START | TWI_CR_STOP;
sahilmgandhi 18:6a4db94011d3 280 stop_sent = 1;
sahilmgandhi 18:6a4db94011d3 281 } else {
sahilmgandhi 18:6a4db94011d3 282 p_twi->TWI_CR = TWI_CR_START;
sahilmgandhi 18:6a4db94011d3 283 stop_sent = 0;
sahilmgandhi 18:6a4db94011d3 284 }
sahilmgandhi 18:6a4db94011d3 285
sahilmgandhi 18:6a4db94011d3 286 while (cnt > 0) {
sahilmgandhi 18:6a4db94011d3 287 status = p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 288 if (status & TWI_SR_NACK) {
sahilmgandhi 18:6a4db94011d3 289 return TWI_RECEIVE_NACK;
sahilmgandhi 18:6a4db94011d3 290 }
sahilmgandhi 18:6a4db94011d3 291
sahilmgandhi 18:6a4db94011d3 292 if (!timeout--) {
sahilmgandhi 18:6a4db94011d3 293 return TWI_ERROR_TIMEOUT;
sahilmgandhi 18:6a4db94011d3 294 }
sahilmgandhi 18:6a4db94011d3 295
sahilmgandhi 18:6a4db94011d3 296 /* Last byte ? */
sahilmgandhi 18:6a4db94011d3 297 if (cnt == 1 && !stop_sent) {
sahilmgandhi 18:6a4db94011d3 298 p_twi->TWI_CR = TWI_CR_STOP;
sahilmgandhi 18:6a4db94011d3 299 stop_sent = 1;
sahilmgandhi 18:6a4db94011d3 300 }
sahilmgandhi 18:6a4db94011d3 301
sahilmgandhi 18:6a4db94011d3 302 if (!(status & TWI_SR_RXRDY)) {
sahilmgandhi 18:6a4db94011d3 303 continue;
sahilmgandhi 18:6a4db94011d3 304 }
sahilmgandhi 18:6a4db94011d3 305 *buffer++ = p_twi->TWI_RHR;
sahilmgandhi 18:6a4db94011d3 306
sahilmgandhi 18:6a4db94011d3 307 cnt--;
sahilmgandhi 18:6a4db94011d3 308 timeout = TWI_TIMEOUT;
sahilmgandhi 18:6a4db94011d3 309 }
sahilmgandhi 18:6a4db94011d3 310
sahilmgandhi 18:6a4db94011d3 311 while (!(p_twi->TWI_SR & TWI_SR_TXCOMP)) {
sahilmgandhi 18:6a4db94011d3 312 }
sahilmgandhi 18:6a4db94011d3 313
sahilmgandhi 18:6a4db94011d3 314 p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 315
sahilmgandhi 18:6a4db94011d3 316 return TWI_SUCCESS;
sahilmgandhi 18:6a4db94011d3 317 }
sahilmgandhi 18:6a4db94011d3 318
sahilmgandhi 18:6a4db94011d3 319 /**
sahilmgandhi 18:6a4db94011d3 320 * \brief Write multiple bytes to a TWI compatible slave device.
sahilmgandhi 18:6a4db94011d3 321 *
sahilmgandhi 18:6a4db94011d3 322 * \note This function will NOT return until all data has been written or error occurred.
sahilmgandhi 18:6a4db94011d3 323 *
sahilmgandhi 18:6a4db94011d3 324 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 325 * \param p_packet Packet information and data (see \ref twi_packet_t).
sahilmgandhi 18:6a4db94011d3 326 *
sahilmgandhi 18:6a4db94011d3 327 * \return TWI_SUCCESS if all bytes were written, error code otherwise.
sahilmgandhi 18:6a4db94011d3 328 */
sahilmgandhi 18:6a4db94011d3 329 uint32_t twi_master_write(Twi *p_twi, twi_packet_t *p_packet)
sahilmgandhi 18:6a4db94011d3 330 {
sahilmgandhi 18:6a4db94011d3 331 uint32_t status;
sahilmgandhi 18:6a4db94011d3 332 uint32_t cnt = p_packet->length;
sahilmgandhi 18:6a4db94011d3 333 uint8_t *buffer = p_packet->buffer;
sahilmgandhi 18:6a4db94011d3 334
sahilmgandhi 18:6a4db94011d3 335 /* Check argument */
sahilmgandhi 18:6a4db94011d3 336 if (cnt == 0) {
sahilmgandhi 18:6a4db94011d3 337 return TWI_INVALID_ARGUMENT;
sahilmgandhi 18:6a4db94011d3 338 }
sahilmgandhi 18:6a4db94011d3 339
sahilmgandhi 18:6a4db94011d3 340 /* Set write mode, slave address and 3 internal address byte lengths */
sahilmgandhi 18:6a4db94011d3 341 p_twi->TWI_MMR = 0;
sahilmgandhi 18:6a4db94011d3 342 p_twi->TWI_MMR = TWI_MMR_DADR(p_packet->chip) |
sahilmgandhi 18:6a4db94011d3 343 ((p_packet->addr_length << TWI_MMR_IADRSZ_Pos) &
sahilmgandhi 18:6a4db94011d3 344 TWI_MMR_IADRSZ_Msk);
sahilmgandhi 18:6a4db94011d3 345
sahilmgandhi 18:6a4db94011d3 346 /* Set internal address for remote chip */
sahilmgandhi 18:6a4db94011d3 347 p_twi->TWI_IADR = 0;
sahilmgandhi 18:6a4db94011d3 348 p_twi->TWI_IADR = twi_mk_addr(p_packet->addr, p_packet->addr_length);
sahilmgandhi 18:6a4db94011d3 349
sahilmgandhi 18:6a4db94011d3 350 /* Send all bytes */
sahilmgandhi 18:6a4db94011d3 351 while (cnt > 0) {
sahilmgandhi 18:6a4db94011d3 352 status = p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 353 if (status & TWI_SR_NACK) {
sahilmgandhi 18:6a4db94011d3 354 return TWI_RECEIVE_NACK;
sahilmgandhi 18:6a4db94011d3 355 }
sahilmgandhi 18:6a4db94011d3 356
sahilmgandhi 18:6a4db94011d3 357 if (!(status & TWI_SR_TXRDY)) {
sahilmgandhi 18:6a4db94011d3 358 continue;
sahilmgandhi 18:6a4db94011d3 359 }
sahilmgandhi 18:6a4db94011d3 360 p_twi->TWI_THR = *buffer++;
sahilmgandhi 18:6a4db94011d3 361
sahilmgandhi 18:6a4db94011d3 362 cnt--;
sahilmgandhi 18:6a4db94011d3 363 }
sahilmgandhi 18:6a4db94011d3 364
sahilmgandhi 18:6a4db94011d3 365 while (1) {
sahilmgandhi 18:6a4db94011d3 366 status = p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 367 if (status & TWI_SR_NACK) {
sahilmgandhi 18:6a4db94011d3 368 return TWI_RECEIVE_NACK;
sahilmgandhi 18:6a4db94011d3 369 }
sahilmgandhi 18:6a4db94011d3 370
sahilmgandhi 18:6a4db94011d3 371 if (status & TWI_SR_TXRDY) {
sahilmgandhi 18:6a4db94011d3 372 break;
sahilmgandhi 18:6a4db94011d3 373 }
sahilmgandhi 18:6a4db94011d3 374 }
sahilmgandhi 18:6a4db94011d3 375
sahilmgandhi 18:6a4db94011d3 376 p_twi->TWI_CR = TWI_CR_STOP;
sahilmgandhi 18:6a4db94011d3 377
sahilmgandhi 18:6a4db94011d3 378 while (!(p_twi->TWI_SR & TWI_SR_TXCOMP)) {
sahilmgandhi 18:6a4db94011d3 379 }
sahilmgandhi 18:6a4db94011d3 380
sahilmgandhi 18:6a4db94011d3 381 return TWI_SUCCESS;
sahilmgandhi 18:6a4db94011d3 382 }
sahilmgandhi 18:6a4db94011d3 383
sahilmgandhi 18:6a4db94011d3 384 /**
sahilmgandhi 18:6a4db94011d3 385 * \brief Enable TWI interrupts.
sahilmgandhi 18:6a4db94011d3 386 *
sahilmgandhi 18:6a4db94011d3 387 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 388 * \param ul_sources Interrupts to be enabled.
sahilmgandhi 18:6a4db94011d3 389 */
sahilmgandhi 18:6a4db94011d3 390 void twi_enable_interrupt(Twi *p_twi, uint32_t ul_sources)
sahilmgandhi 18:6a4db94011d3 391 {
sahilmgandhi 18:6a4db94011d3 392 /* Enable the specified interrupts */
sahilmgandhi 18:6a4db94011d3 393 p_twi->TWI_IER = ul_sources;
sahilmgandhi 18:6a4db94011d3 394 }
sahilmgandhi 18:6a4db94011d3 395
sahilmgandhi 18:6a4db94011d3 396 /**
sahilmgandhi 18:6a4db94011d3 397 * \brief Disable TWI interrupts.
sahilmgandhi 18:6a4db94011d3 398 *
sahilmgandhi 18:6a4db94011d3 399 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 400 * \param ul_sources Interrupts to be disabled.
sahilmgandhi 18:6a4db94011d3 401 */
sahilmgandhi 18:6a4db94011d3 402 void twi_disable_interrupt(Twi *p_twi, uint32_t ul_sources)
sahilmgandhi 18:6a4db94011d3 403 {
sahilmgandhi 18:6a4db94011d3 404 /* Disable the specified interrupts */
sahilmgandhi 18:6a4db94011d3 405 p_twi->TWI_IDR = ul_sources;
sahilmgandhi 18:6a4db94011d3 406 /* Dummy read */
sahilmgandhi 18:6a4db94011d3 407 p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 408 }
sahilmgandhi 18:6a4db94011d3 409
sahilmgandhi 18:6a4db94011d3 410 /**
sahilmgandhi 18:6a4db94011d3 411 * \brief Get TWI interrupt status.
sahilmgandhi 18:6a4db94011d3 412 *
sahilmgandhi 18:6a4db94011d3 413 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 414 *
sahilmgandhi 18:6a4db94011d3 415 * \retval TWI interrupt status.
sahilmgandhi 18:6a4db94011d3 416 */
sahilmgandhi 18:6a4db94011d3 417 uint32_t twi_get_interrupt_status(Twi *p_twi)
sahilmgandhi 18:6a4db94011d3 418 {
sahilmgandhi 18:6a4db94011d3 419 return p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 420 }
sahilmgandhi 18:6a4db94011d3 421
sahilmgandhi 18:6a4db94011d3 422 /**
sahilmgandhi 18:6a4db94011d3 423 * \brief Read TWI interrupt mask.
sahilmgandhi 18:6a4db94011d3 424 *
sahilmgandhi 18:6a4db94011d3 425 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 426 *
sahilmgandhi 18:6a4db94011d3 427 * \return The interrupt mask value.
sahilmgandhi 18:6a4db94011d3 428 */
sahilmgandhi 18:6a4db94011d3 429 uint32_t twi_get_interrupt_mask(Twi *p_twi)
sahilmgandhi 18:6a4db94011d3 430 {
sahilmgandhi 18:6a4db94011d3 431 return p_twi->TWI_IMR;
sahilmgandhi 18:6a4db94011d3 432 }
sahilmgandhi 18:6a4db94011d3 433
sahilmgandhi 18:6a4db94011d3 434 /**
sahilmgandhi 18:6a4db94011d3 435 * \brief Reads a byte from the TWI bus.
sahilmgandhi 18:6a4db94011d3 436 *
sahilmgandhi 18:6a4db94011d3 437 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 438 *
sahilmgandhi 18:6a4db94011d3 439 * \return The byte read.
sahilmgandhi 18:6a4db94011d3 440 */
sahilmgandhi 18:6a4db94011d3 441 uint8_t twi_read_byte(Twi *p_twi)
sahilmgandhi 18:6a4db94011d3 442 {
sahilmgandhi 18:6a4db94011d3 443 return p_twi->TWI_RHR;
sahilmgandhi 18:6a4db94011d3 444 }
sahilmgandhi 18:6a4db94011d3 445
sahilmgandhi 18:6a4db94011d3 446 /**
sahilmgandhi 18:6a4db94011d3 447 * \brief Sends a byte of data to one of the TWI slaves on the bus.
sahilmgandhi 18:6a4db94011d3 448 *
sahilmgandhi 18:6a4db94011d3 449 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 450 * \param byte The byte to send.
sahilmgandhi 18:6a4db94011d3 451 */
sahilmgandhi 18:6a4db94011d3 452 void twi_write_byte(Twi *p_twi, uint8_t uc_byte)
sahilmgandhi 18:6a4db94011d3 453 {
sahilmgandhi 18:6a4db94011d3 454 p_twi->TWI_THR = uc_byte;
sahilmgandhi 18:6a4db94011d3 455 }
sahilmgandhi 18:6a4db94011d3 456
sahilmgandhi 18:6a4db94011d3 457 /**
sahilmgandhi 18:6a4db94011d3 458 * \brief Enable TWI slave mode.
sahilmgandhi 18:6a4db94011d3 459 *
sahilmgandhi 18:6a4db94011d3 460 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 461 */
sahilmgandhi 18:6a4db94011d3 462 void twi_enable_slave_mode(Twi *p_twi)
sahilmgandhi 18:6a4db94011d3 463 {
sahilmgandhi 18:6a4db94011d3 464 /* Set Master Disable bit and Slave Disable bit */
sahilmgandhi 18:6a4db94011d3 465 p_twi->TWI_CR = TWI_CR_MSDIS;
sahilmgandhi 18:6a4db94011d3 466 p_twi->TWI_CR = TWI_CR_SVDIS;
sahilmgandhi 18:6a4db94011d3 467
sahilmgandhi 18:6a4db94011d3 468 /* Set Slave Enable bit */
sahilmgandhi 18:6a4db94011d3 469 p_twi->TWI_CR = TWI_CR_SVEN;
sahilmgandhi 18:6a4db94011d3 470 }
sahilmgandhi 18:6a4db94011d3 471
sahilmgandhi 18:6a4db94011d3 472 /**
sahilmgandhi 18:6a4db94011d3 473 * \brief Disable TWI slave mode.
sahilmgandhi 18:6a4db94011d3 474 *
sahilmgandhi 18:6a4db94011d3 475 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 476 */
sahilmgandhi 18:6a4db94011d3 477 void twi_disable_slave_mode(Twi *p_twi)
sahilmgandhi 18:6a4db94011d3 478 {
sahilmgandhi 18:6a4db94011d3 479 /* Set Slave Disable bit */
sahilmgandhi 18:6a4db94011d3 480 p_twi->TWI_CR = TWI_CR_SVDIS;
sahilmgandhi 18:6a4db94011d3 481 }
sahilmgandhi 18:6a4db94011d3 482
sahilmgandhi 18:6a4db94011d3 483 /**
sahilmgandhi 18:6a4db94011d3 484 * \brief Initialize TWI slave mode.
sahilmgandhi 18:6a4db94011d3 485 *
sahilmgandhi 18:6a4db94011d3 486 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 487 * \param ul_device_addr Device address of the SAM slave device on the I2C bus.
sahilmgandhi 18:6a4db94011d3 488 */
sahilmgandhi 18:6a4db94011d3 489 void twi_slave_init(Twi *p_twi, uint32_t ul_device_addr)
sahilmgandhi 18:6a4db94011d3 490 {
sahilmgandhi 18:6a4db94011d3 491 /* Disable TWI interrupts */
sahilmgandhi 18:6a4db94011d3 492 p_twi->TWI_IDR = ~0UL;
sahilmgandhi 18:6a4db94011d3 493 p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 494
sahilmgandhi 18:6a4db94011d3 495 /* Reset TWI */
sahilmgandhi 18:6a4db94011d3 496 twi_reset(p_twi);
sahilmgandhi 18:6a4db94011d3 497
sahilmgandhi 18:6a4db94011d3 498 /* Set slave address in slave mode */
sahilmgandhi 18:6a4db94011d3 499 p_twi->TWI_SMR = TWI_SMR_SADR(ul_device_addr);
sahilmgandhi 18:6a4db94011d3 500
sahilmgandhi 18:6a4db94011d3 501 /* Enable slave mode */
sahilmgandhi 18:6a4db94011d3 502 twi_enable_slave_mode(p_twi);
sahilmgandhi 18:6a4db94011d3 503 }
sahilmgandhi 18:6a4db94011d3 504
sahilmgandhi 18:6a4db94011d3 505 /**
sahilmgandhi 18:6a4db94011d3 506 * \brief Set TWI slave address.
sahilmgandhi 18:6a4db94011d3 507 *
sahilmgandhi 18:6a4db94011d3 508 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 509 * \param ul_device_addr Device address of the SAM slave device on the I2C bus.
sahilmgandhi 18:6a4db94011d3 510 */
sahilmgandhi 18:6a4db94011d3 511 void twi_set_slave_addr(Twi *p_twi, uint32_t ul_device_addr)
sahilmgandhi 18:6a4db94011d3 512 {
sahilmgandhi 18:6a4db94011d3 513 /* Set slave address */
sahilmgandhi 18:6a4db94011d3 514 p_twi->TWI_SMR = TWI_SMR_SADR(ul_device_addr);
sahilmgandhi 18:6a4db94011d3 515 }
sahilmgandhi 18:6a4db94011d3 516
sahilmgandhi 18:6a4db94011d3 517 /**
sahilmgandhi 18:6a4db94011d3 518 * \brief Read data from master.
sahilmgandhi 18:6a4db94011d3 519 *
sahilmgandhi 18:6a4db94011d3 520 * \note This function will NOT return until master sends a STOP condition.
sahilmgandhi 18:6a4db94011d3 521 *
sahilmgandhi 18:6a4db94011d3 522 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 523 * \param p_data Pointer to the data buffer where data received will be stored.
sahilmgandhi 18:6a4db94011d3 524 *
sahilmgandhi 18:6a4db94011d3 525 * \return Number of bytes read.
sahilmgandhi 18:6a4db94011d3 526 */
sahilmgandhi 18:6a4db94011d3 527 uint32_t twi_slave_read(Twi *p_twi, uint8_t *p_data)
sahilmgandhi 18:6a4db94011d3 528 {
sahilmgandhi 18:6a4db94011d3 529 uint32_t status, cnt = 0;
sahilmgandhi 18:6a4db94011d3 530
sahilmgandhi 18:6a4db94011d3 531 do {
sahilmgandhi 18:6a4db94011d3 532 status = p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 533 if (status & TWI_SR_SVACC) {
sahilmgandhi 18:6a4db94011d3 534 if (!(status & TWI_SR_GACC) &&
sahilmgandhi 18:6a4db94011d3 535 ((status & (TWI_SR_SVREAD | TWI_SR_RXRDY))
sahilmgandhi 18:6a4db94011d3 536 == (TWI_SR_SVREAD | TWI_SR_RXRDY))) {
sahilmgandhi 18:6a4db94011d3 537 *p_data++ = (uint8_t) p_twi->TWI_RHR;
sahilmgandhi 18:6a4db94011d3 538 cnt++;
sahilmgandhi 18:6a4db94011d3 539 }
sahilmgandhi 18:6a4db94011d3 540 } else if ((status & (TWI_SR_EOSACC | TWI_SR_TXCOMP))
sahilmgandhi 18:6a4db94011d3 541 == (TWI_SR_EOSACC | TWI_SR_TXCOMP)) {
sahilmgandhi 18:6a4db94011d3 542 break;
sahilmgandhi 18:6a4db94011d3 543 }
sahilmgandhi 18:6a4db94011d3 544 } while (1);
sahilmgandhi 18:6a4db94011d3 545
sahilmgandhi 18:6a4db94011d3 546 return cnt;
sahilmgandhi 18:6a4db94011d3 547 }
sahilmgandhi 18:6a4db94011d3 548
sahilmgandhi 18:6a4db94011d3 549 /**
sahilmgandhi 18:6a4db94011d3 550 * \brief Write data to TWI bus.
sahilmgandhi 18:6a4db94011d3 551 *
sahilmgandhi 18:6a4db94011d3 552 * \note This function will NOT return until master sends a STOP condition.
sahilmgandhi 18:6a4db94011d3 553 *
sahilmgandhi 18:6a4db94011d3 554 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 555 * \param p_data Pointer to the data buffer to be sent.
sahilmgandhi 18:6a4db94011d3 556 *
sahilmgandhi 18:6a4db94011d3 557 * \return Number of bytes written.
sahilmgandhi 18:6a4db94011d3 558 */
sahilmgandhi 18:6a4db94011d3 559 uint32_t twi_slave_write(Twi *p_twi, uint8_t *p_data)
sahilmgandhi 18:6a4db94011d3 560 {
sahilmgandhi 18:6a4db94011d3 561 uint32_t status, cnt = 0;
sahilmgandhi 18:6a4db94011d3 562
sahilmgandhi 18:6a4db94011d3 563 do {
sahilmgandhi 18:6a4db94011d3 564 status = p_twi->TWI_SR;
sahilmgandhi 18:6a4db94011d3 565 if (status & TWI_SR_SVACC) {
sahilmgandhi 18:6a4db94011d3 566 if (!(status & (TWI_SR_GACC | TWI_SR_SVREAD)) &&
sahilmgandhi 18:6a4db94011d3 567 (status & TWI_SR_TXRDY)) {
sahilmgandhi 18:6a4db94011d3 568 p_twi->TWI_THR = *p_data++;
sahilmgandhi 18:6a4db94011d3 569 cnt++;
sahilmgandhi 18:6a4db94011d3 570 }
sahilmgandhi 18:6a4db94011d3 571 } else if ((status & (TWI_SR_EOSACC | TWI_SR_TXCOMP))
sahilmgandhi 18:6a4db94011d3 572 == (TWI_SR_EOSACC | TWI_SR_TXCOMP)) {
sahilmgandhi 18:6a4db94011d3 573 break;
sahilmgandhi 18:6a4db94011d3 574 }
sahilmgandhi 18:6a4db94011d3 575 } while (1);
sahilmgandhi 18:6a4db94011d3 576
sahilmgandhi 18:6a4db94011d3 577 return cnt;
sahilmgandhi 18:6a4db94011d3 578 }
sahilmgandhi 18:6a4db94011d3 579
sahilmgandhi 18:6a4db94011d3 580 /**
sahilmgandhi 18:6a4db94011d3 581 * \brief Reset TWI.
sahilmgandhi 18:6a4db94011d3 582 *
sahilmgandhi 18:6a4db94011d3 583 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 584 */
sahilmgandhi 18:6a4db94011d3 585 void twi_reset(Twi *p_twi)
sahilmgandhi 18:6a4db94011d3 586 {
sahilmgandhi 18:6a4db94011d3 587 /* Set SWRST bit to reset TWI peripheral */
sahilmgandhi 18:6a4db94011d3 588 p_twi->TWI_CR = TWI_CR_SWRST;
sahilmgandhi 18:6a4db94011d3 589 p_twi->TWI_RHR;
sahilmgandhi 18:6a4db94011d3 590 }
sahilmgandhi 18:6a4db94011d3 591
sahilmgandhi 18:6a4db94011d3 592 /**
sahilmgandhi 18:6a4db94011d3 593 * \brief Get TWI PDC base address.
sahilmgandhi 18:6a4db94011d3 594 *
sahilmgandhi 18:6a4db94011d3 595 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 596 *
sahilmgandhi 18:6a4db94011d3 597 * \return TWI PDC registers base for PDC driver to access.
sahilmgandhi 18:6a4db94011d3 598 */
sahilmgandhi 18:6a4db94011d3 599 Pdc *twi_get_pdc_base(Twi *p_twi)
sahilmgandhi 18:6a4db94011d3 600 {
sahilmgandhi 18:6a4db94011d3 601 Pdc *p_pdc_base = NULL;
sahilmgandhi 18:6a4db94011d3 602 #if !SAMG
sahilmgandhi 18:6a4db94011d3 603 if (p_twi == TWI0) {
sahilmgandhi 18:6a4db94011d3 604 p_pdc_base = PDC_TWI0;
sahilmgandhi 18:6a4db94011d3 605 } else
sahilmgandhi 18:6a4db94011d3 606 #endif
sahilmgandhi 18:6a4db94011d3 607 #ifdef PDC_TWI1
sahilmgandhi 18:6a4db94011d3 608 if (p_twi == TWI1) {
sahilmgandhi 18:6a4db94011d3 609 p_pdc_base = PDC_TWI1;
sahilmgandhi 18:6a4db94011d3 610 } else
sahilmgandhi 18:6a4db94011d3 611 #endif
sahilmgandhi 18:6a4db94011d3 612 #ifdef PDC_TWI2
sahilmgandhi 18:6a4db94011d3 613 if (p_twi == TWI2) {
sahilmgandhi 18:6a4db94011d3 614 p_pdc_base = PDC_TWI2;
sahilmgandhi 18:6a4db94011d3 615 } else
sahilmgandhi 18:6a4db94011d3 616 #endif
sahilmgandhi 18:6a4db94011d3 617 {
sahilmgandhi 18:6a4db94011d3 618 Assert(false);
sahilmgandhi 18:6a4db94011d3 619 }
sahilmgandhi 18:6a4db94011d3 620
sahilmgandhi 18:6a4db94011d3 621 return p_pdc_base;
sahilmgandhi 18:6a4db94011d3 622 }
sahilmgandhi 18:6a4db94011d3 623
sahilmgandhi 18:6a4db94011d3 624 #if (SAM4E || SAM4C || SAMG || SAM4CP || SAM4CM)
sahilmgandhi 18:6a4db94011d3 625 /**
sahilmgandhi 18:6a4db94011d3 626 * \brief Enables/Disables write protection mode.
sahilmgandhi 18:6a4db94011d3 627 *
sahilmgandhi 18:6a4db94011d3 628 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 629 * \param flag ture for enable, false for disable.
sahilmgandhi 18:6a4db94011d3 630 */
sahilmgandhi 18:6a4db94011d3 631 void twi_set_write_protection(Twi *p_twi, bool flag)
sahilmgandhi 18:6a4db94011d3 632 {
sahilmgandhi 18:6a4db94011d3 633
sahilmgandhi 18:6a4db94011d3 634 p_twi->TWI_WPMR = (flag ? TWI_WPMR_WPEN : 0) | TWI_WP_KEY_VALUE;
sahilmgandhi 18:6a4db94011d3 635 }
sahilmgandhi 18:6a4db94011d3 636
sahilmgandhi 18:6a4db94011d3 637 /**
sahilmgandhi 18:6a4db94011d3 638 * \brief Read the write protection status.
sahilmgandhi 18:6a4db94011d3 639 *
sahilmgandhi 18:6a4db94011d3 640 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 641 * \param p_status Pointer to save the status.
sahilmgandhi 18:6a4db94011d3 642 */
sahilmgandhi 18:6a4db94011d3 643 void twi_read_write_protection_status(Twi *p_twi, uint32_t *p_status)
sahilmgandhi 18:6a4db94011d3 644 {
sahilmgandhi 18:6a4db94011d3 645
sahilmgandhi 18:6a4db94011d3 646 *p_status = p_twi->TWI_WPSR;
sahilmgandhi 18:6a4db94011d3 647 }
sahilmgandhi 18:6a4db94011d3 648 #endif
sahilmgandhi 18:6a4db94011d3 649
sahilmgandhi 18:6a4db94011d3 650 #if SAMG55
sahilmgandhi 18:6a4db94011d3 651 /**
sahilmgandhi 18:6a4db94011d3 652 * \brief Set the prescaler, TLOW:SEXT, TLOW:MEXT and clock high max cycles for SMBUS mode.
sahilmgandhi 18:6a4db94011d3 653 *
sahilmgandhi 18:6a4db94011d3 654 * \param p_twi Base address of the TWI instance.
sahilmgandhi 18:6a4db94011d3 655 * \param ul_timing Parameter for prescaler, TLOW:SEXT, TLOW:MEXT and clock high max cycles.
sahilmgandhi 18:6a4db94011d3 656 */
sahilmgandhi 18:6a4db94011d3 657 void twi_smbus_set_timing(Twi *p_twi, uint32_t ul_timing)
sahilmgandhi 18:6a4db94011d3 658 {
sahilmgandhi 18:6a4db94011d3 659 p_twi->TWI_SMBTR = ul_timing;;
sahilmgandhi 18:6a4db94011d3 660 }
sahilmgandhi 18:6a4db94011d3 661
sahilmgandhi 18:6a4db94011d3 662 /**
sahilmgandhi 18:6a4db94011d3 663 * \brief Set length/direction/PEC for alternative command mode.
sahilmgandhi 18:6a4db94011d3 664 *
sahilmgandhi 18:6a4db94011d3 665 * \param p_twi Base address of the TWI instance.
sahilmgandhi 18:6a4db94011d3 666 * \param ul_alt_cmd Alternative command parameters.
sahilmgandhi 18:6a4db94011d3 667 */
sahilmgandhi 18:6a4db94011d3 668 void twi_set_alternative_command(Twi *p_twi, uint32_t ul_alt_cmd)
sahilmgandhi 18:6a4db94011d3 669 {
sahilmgandhi 18:6a4db94011d3 670 p_twi->TWI_ACR = ul_alt_cmd;;
sahilmgandhi 18:6a4db94011d3 671 }
sahilmgandhi 18:6a4db94011d3 672
sahilmgandhi 18:6a4db94011d3 673 /**
sahilmgandhi 18:6a4db94011d3 674 * \brief Set the filter for TWI.
sahilmgandhi 18:6a4db94011d3 675 *
sahilmgandhi 18:6a4db94011d3 676 * \param p_twi Base address of the TWI instance.
sahilmgandhi 18:6a4db94011d3 677 * \param ul_filter Filter value.
sahilmgandhi 18:6a4db94011d3 678 */
sahilmgandhi 18:6a4db94011d3 679 void twi_set_filter(Twi *p_twi, uint32_t ul_filter)
sahilmgandhi 18:6a4db94011d3 680 {
sahilmgandhi 18:6a4db94011d3 681 p_twi->TWI_FILTR = ul_filter;;
sahilmgandhi 18:6a4db94011d3 682 }
sahilmgandhi 18:6a4db94011d3 683
sahilmgandhi 18:6a4db94011d3 684 /**
sahilmgandhi 18:6a4db94011d3 685 * \brief A mask can be applied on the slave device address in slave mode in order to allow multiple
sahilmgandhi 18:6a4db94011d3 686 * address answer. For each bit of the MASK field set to one the corresponding SADR bit will be masked.
sahilmgandhi 18:6a4db94011d3 687 *
sahilmgandhi 18:6a4db94011d3 688 * \param p_twi Base address of the TWI instance.
sahilmgandhi 18:6a4db94011d3 689 * \param ul_mask Mask value.
sahilmgandhi 18:6a4db94011d3 690 */
sahilmgandhi 18:6a4db94011d3 691 void twi_mask_slave_addr(Twi *p_twi, uint32_t ul_mask)
sahilmgandhi 18:6a4db94011d3 692 {
sahilmgandhi 18:6a4db94011d3 693 p_twi->TWI_SMR |= TWI_SMR_MASK(ul_mask);
sahilmgandhi 18:6a4db94011d3 694 }
sahilmgandhi 18:6a4db94011d3 695
sahilmgandhi 18:6a4db94011d3 696 /**
sahilmgandhi 18:6a4db94011d3 697 * \brief Set sleepwalking match mode.
sahilmgandhi 18:6a4db94011d3 698 *
sahilmgandhi 18:6a4db94011d3 699 * \param p_twi Pointer to a TWI instance.
sahilmgandhi 18:6a4db94011d3 700 * \param ul_matching_addr1 Address 1 value.
sahilmgandhi 18:6a4db94011d3 701 * \param ul_matching_addr2 Address 2 value.
sahilmgandhi 18:6a4db94011d3 702 * \param ul_matching_addr3 Address 3 value.
sahilmgandhi 18:6a4db94011d3 703 * \param ul_matching_data Data value.
sahilmgandhi 18:6a4db94011d3 704 * \param flag1 ture for set, false for no.
sahilmgandhi 18:6a4db94011d3 705 * \param flag2 ture for set, false for no.
sahilmgandhi 18:6a4db94011d3 706 * \param flag3 ture for set, false for no.
sahilmgandhi 18:6a4db94011d3 707 * \param flag ture for set, false for no.
sahilmgandhi 18:6a4db94011d3 708 */
sahilmgandhi 18:6a4db94011d3 709 void twi_set_sleepwalking(Twi *p_twi,
sahilmgandhi 18:6a4db94011d3 710 uint32_t ul_matching_addr1, bool flag1,
sahilmgandhi 18:6a4db94011d3 711 uint32_t ul_matching_addr2, bool flag2,
sahilmgandhi 18:6a4db94011d3 712 uint32_t ul_matching_addr3, bool flag3,
sahilmgandhi 18:6a4db94011d3 713 uint32_t ul_matching_data, bool flag)
sahilmgandhi 18:6a4db94011d3 714 {
sahilmgandhi 18:6a4db94011d3 715 uint32_t temp = 0;
sahilmgandhi 18:6a4db94011d3 716
sahilmgandhi 18:6a4db94011d3 717 if (flag1) {
sahilmgandhi 18:6a4db94011d3 718 temp |= TWI_SWMR_SADR1(ul_matching_addr1);
sahilmgandhi 18:6a4db94011d3 719 }
sahilmgandhi 18:6a4db94011d3 720
sahilmgandhi 18:6a4db94011d3 721 if (flag2) {
sahilmgandhi 18:6a4db94011d3 722 temp |= TWI_SWMR_SADR2(ul_matching_addr2);
sahilmgandhi 18:6a4db94011d3 723 }
sahilmgandhi 18:6a4db94011d3 724
sahilmgandhi 18:6a4db94011d3 725 if (flag3) {
sahilmgandhi 18:6a4db94011d3 726 temp |= TWI_SWMR_SADR3(ul_matching_addr3);
sahilmgandhi 18:6a4db94011d3 727 }
sahilmgandhi 18:6a4db94011d3 728
sahilmgandhi 18:6a4db94011d3 729 if (flag) {
sahilmgandhi 18:6a4db94011d3 730 temp |= TWI_SWMR_DATAM(ul_matching_data);
sahilmgandhi 18:6a4db94011d3 731 }
sahilmgandhi 18:6a4db94011d3 732
sahilmgandhi 18:6a4db94011d3 733 p_twi->TWI_SWMR = temp;
sahilmgandhi 18:6a4db94011d3 734 }
sahilmgandhi 18:6a4db94011d3 735 #endif
sahilmgandhi 18:6a4db94011d3 736 //@}
sahilmgandhi 18:6a4db94011d3 737
sahilmgandhi 18:6a4db94011d3 738 /// @cond 0
sahilmgandhi 18:6a4db94011d3 739 /**INDENT-OFF**/
sahilmgandhi 18:6a4db94011d3 740 #ifdef __cplusplus
sahilmgandhi 18:6a4db94011d3 741 }
sahilmgandhi 18:6a4db94011d3 742 #endif
sahilmgandhi 18:6a4db94011d3 743 /**INDENT-ON**/
sahilmgandhi 18:6a4db94011d3 744 /// @endcond