SAM4SD32 (SAM4S-EK2)
Loading...
Searching...
No Matches
Two-Wire Interface (TWI)

Driver for the TWI (Two-Wire Interface). More...

Macros

#define I2C_FAST_MODE_SPEED   400000
#define LOW_LEVEL_TIME_LIMIT   384000
#define TWI_CLK_CALC_ARGU   4
#define TWI_CLK_DIV_MAX   0xFF
#define TWI_CLK_DIV_MIN   7
#define TWI_CLK_DIVIDER   2
#define TWI_WP_KEY_VALUE   TWI_WPMR_WPKEY_PASSWD

Functions

void twi_disable_interrupt (Twi *p_twi, uint32_t ul_sources)
 Disable TWI interrupts.
void twi_disable_master_mode (Twi *p_twi)
 Disable TWI master mode.
void twi_disable_slave_mode (Twi *p_twi)
 Disable TWI slave mode.
void twi_enable_interrupt (Twi *p_twi, uint32_t ul_sources)
 Enable TWI interrupts.
void twi_enable_master_mode (Twi *p_twi)
 Enable TWI master mode.
void twi_enable_slave_mode (Twi *p_twi)
 Enable TWI slave mode.
uint32_t twi_get_interrupt_mask (Twi *p_twi)
 Read TWI interrupt mask.
uint32_t twi_get_interrupt_status (Twi *p_twi)
 Get TWI interrupt status.
Pdc * twi_get_pdc_base (Twi *p_twi)
 Get TWI PDC base address.
uint32_t twi_master_init (Twi *p_twi, const twi_options_t *p_opt)
 Initialize TWI master mode.
uint32_t twi_master_read (Twi *p_twi, twi_packet_t *p_packet)
 Read multiple bytes from a TWI compatible slave device.
uint32_t twi_master_write (Twi *p_twi, twi_packet_t *p_packet)
 Write multiple bytes to a TWI compatible slave device.
uint32_t twi_mk_addr (const uint8_t *addr, int len)
 Construct the TWI module address register field.
uint32_t twi_probe (Twi *p_twi, uint8_t uc_slave_addr)
 Test if a chip answers a given I2C address.
uint8_t twi_read_byte (Twi *p_twi)
 Reads a byte from the TWI bus.
void twi_reset (Twi *p_twi)
 Reset TWI.
void twi_set_slave_addr (Twi *p_twi, uint32_t ul_device_addr)
 Set TWI slave address.
uint32_t twi_set_speed (Twi *p_twi, uint32_t ul_speed, uint32_t ul_mck)
 Set the I2C bus speed in conjunction with the clock frequency.
void twi_slave_init (Twi *p_twi, uint32_t ul_device_addr)
 Initialize TWI slave mode.
uint32_t twi_slave_read (Twi *p_twi, uint8_t *p_data)
 Read data from master.
uint32_t twi_slave_write (Twi *p_twi, uint8_t *p_data)
 Write data to TWI bus.
void twi_write_byte (Twi *p_twi, uint8_t uc_byte)
 Sends a byte of data to one of the TWI slaves on the bus.

Detailed Description

Driver for the TWI (Two-Wire Interface).

This driver provides access to the main features of the TWI controller. The TWI interconnects components on a unique two-wire bus. The TWI is programmable as a master or a slave with sequential or single-byte access. Multiple master capability is supported.

Usage
  1. Enable the TWI peripheral clock in the PMC.
  2. Enable the required TWI PIOs (see pio.h).
  3. Enable TWI master mode by calling twi_enable_master_mode if it is a master on the I2C bus.
  4. Configure the TWI in master mode by calling twi_master_init.
  5. Send data to a slave device on the I2C bus by calling twi_master_write.
  6. Receive data from a slave device on the I2C bus by calling the twi_master_read.
  7. Enable TWI slave mode by calling twi_enable_slave_mode if it is a slave on the I2C bus.
  8. Configure the TWI in slave mode by calling twi_slave_init.

Macro Definition Documentation

◆ I2C_FAST_MODE_SPEED

#define I2C_FAST_MODE_SPEED   400000

Definition at line 72 of file twi.c.

Referenced by twi_set_speed().

◆ LOW_LEVEL_TIME_LIMIT

#define LOW_LEVEL_TIME_LIMIT   384000

Definition at line 71 of file twi.c.

Referenced by twi_set_speed().

◆ TWI_CLK_CALC_ARGU

#define TWI_CLK_CALC_ARGU   4

Definition at line 77 of file twi.c.

Referenced by twi_set_speed().

◆ TWI_CLK_DIV_MAX

#define TWI_CLK_DIV_MAX   0xFF

Definition at line 79 of file twi.c.

Referenced by twi_set_speed().

◆ TWI_CLK_DIV_MIN

#define TWI_CLK_DIV_MIN   7

Definition at line 80 of file twi.c.

Referenced by twi_set_speed().

◆ TWI_CLK_DIVIDER

#define TWI_CLK_DIVIDER   2

Definition at line 73 of file twi.c.

Referenced by twi_set_speed().

◆ TWI_WP_KEY_VALUE

#define TWI_WP_KEY_VALUE   TWI_WPMR_WPKEY_PASSWD

Definition at line 82 of file twi.c.

Function Documentation

◆ twi_disable_interrupt()

void twi_disable_interrupt ( Twi * p_twi,
uint32_t ul_sources )

Disable TWI interrupts.

Parameters
p_twiPointer to a TWI instance.
ul_sourcesInterrupts to be disabled.

Definition at line 426 of file twi.c.

427{
428 /* Disable the specified interrupts */
429 p_twi->TWI_IDR = ul_sources;
430 /* Dummy read */
431 p_twi->TWI_SR;
432}
__I uint32_t TWI_SR
(Twi Offset: 0x20) Status Register
__O uint32_t TWI_IDR
(Twi Offset: 0x28) Interrupt Disable Register

References Twi::TWI_IDR, and Twi::TWI_SR.

◆ twi_disable_master_mode()

void twi_disable_master_mode ( Twi * p_twi)

Disable TWI master mode.

Parameters
p_twiPointer to a TWI instance.

Definition at line 104 of file twi.c.

105{
106 /* Set Master Disable bit */
107 p_twi->TWI_CR = TWI_CR_MSDIS;
108}
#define TWI_CR_MSDIS
(TWI_CR) TWI Master Mode Disabled
__O uint32_t TWI_CR
(Twi Offset: 0x00) Control Register

References Twi::TWI_CR, and TWI_CR_MSDIS.

◆ twi_disable_slave_mode()

void twi_disable_slave_mode ( Twi * p_twi)

Disable TWI slave mode.

Parameters
p_twiPointer to a TWI instance.

Definition at line 501 of file twi.c.

502{
503 /* Set Slave Disable bit */
504 p_twi->TWI_CR = TWI_CR_SVDIS;
505}
#define TWI_CR_SVDIS
(TWI_CR) TWI Slave Mode Disabled

References Twi::TWI_CR, and TWI_CR_SVDIS.

◆ twi_enable_interrupt()

void twi_enable_interrupt ( Twi * p_twi,
uint32_t ul_sources )

Enable TWI interrupts.

Parameters
p_twiPointer to a TWI instance.
ul_sourcesInterrupts to be enabled.

Definition at line 414 of file twi.c.

415{
416 /* Enable the specified interrupts */
417 p_twi->TWI_IER = ul_sources;
418}
__O uint32_t TWI_IER
(Twi Offset: 0x24) Interrupt Enable Register

References Twi::TWI_IER.

◆ twi_enable_master_mode()

void twi_enable_master_mode ( Twi * p_twi)

Enable TWI master mode.

Parameters
p_twiPointer to a TWI instance.

Definition at line 89 of file twi.c.

90{
91 /* Set Master Disable bit and Slave Disable bit */
92 p_twi->TWI_CR = TWI_CR_MSDIS;
93 p_twi->TWI_CR = TWI_CR_SVDIS;
94
95 /* Set Master Enable bit */
96 p_twi->TWI_CR = TWI_CR_MSEN;
97}
#define TWI_CR_MSEN
(TWI_CR) TWI Master Mode Enabled

References Twi::TWI_CR, TWI_CR_MSDIS, TWI_CR_MSEN, and TWI_CR_SVDIS.

Referenced by twi_master_init().

◆ twi_enable_slave_mode()

void twi_enable_slave_mode ( Twi * p_twi)

Enable TWI slave mode.

Parameters
p_twiPointer to a TWI instance.

Definition at line 486 of file twi.c.

487{
488 /* Set Master Disable bit and Slave Disable bit */
489 p_twi->TWI_CR = TWI_CR_MSDIS;
490 p_twi->TWI_CR = TWI_CR_SVDIS;
491
492 /* Set Slave Enable bit */
493 p_twi->TWI_CR = TWI_CR_SVEN;
494}
#define TWI_CR_SVEN
(TWI_CR) TWI Slave Mode Enabled

References Twi::TWI_CR, TWI_CR_MSDIS, TWI_CR_SVDIS, and TWI_CR_SVEN.

Referenced by twi_slave_init().

◆ twi_get_interrupt_mask()

uint32_t twi_get_interrupt_mask ( Twi * p_twi)

Read TWI interrupt mask.

Parameters
p_twiPointer to a TWI instance.
Returns
The interrupt mask value.

Definition at line 453 of file twi.c.

454{
455 return p_twi->TWI_IMR;
456}
__I uint32_t TWI_IMR
(Twi Offset: 0x2C) Interrupt Mask Register

References Twi::TWI_IMR.

◆ twi_get_interrupt_status()

uint32_t twi_get_interrupt_status ( Twi * p_twi)

Get TWI interrupt status.

Parameters
p_twiPointer to a TWI instance.
Return values
TWIinterrupt status.

Definition at line 441 of file twi.c.

442{
443 return p_twi->TWI_SR;
444}

References Twi::TWI_SR.

◆ twi_get_pdc_base()

Pdc * twi_get_pdc_base ( Twi * p_twi)

Get TWI PDC base address.

Parameters
p_twiPointer to a TWI instance.
Returns
TWI PDC registers base for PDC driver to access.

Definition at line 623 of file twi.c.

624{
625 Pdc *p_pdc_base = NULL;
626#if !SAMG
627 if (p_twi == TWI0) {
628 p_pdc_base = PDC_TWI0;
629 } else
630#endif
631#ifdef PDC_TWI1
632 if (p_twi == TWI1) {
633 p_pdc_base = PDC_TWI1;
634 } else
635#endif
636#ifdef PDC_TWI2
637 if (p_twi == TWI2) {
638 p_pdc_base = PDC_TWI2;
639 } else
640#endif
641 {
642 Assert(false);
643 }
644
645 return p_pdc_base;
646}
#define PDC_TWI0
(PDC_TWI0 ) Base Address
Definition sam4sd32c.h:420
#define TWI0
(TWI0 ) Base Address
Definition sam4sd32c.h:419
#define TWI1
(TWI1 ) Base Address
Definition sam4sd32c.h:421
#define PDC_TWI1
(PDC_TWI1 ) Base Address
Definition sam4sd32c.h:422

References PDC_TWI0, PDC_TWI1, TWI0, and TWI1.

◆ twi_master_init()

uint32_t twi_master_init ( Twi * p_twi,
const twi_options_t * p_opt )

Initialize TWI master mode.

Parameters
p_twiPointer to a TWI instance.
p_optOptions for initializing the TWI module (see twi_options_t).
Returns
TWI_SUCCESS if initialization is complete, error code otherwise.

Definition at line 118 of file twi.c.

119{
120 uint32_t status = TWI_SUCCESS;
121
122 /* Disable TWI interrupts */
123 p_twi->TWI_IDR = ~0UL;
124
125 /* Dummy read in status register */
126 p_twi->TWI_SR;
127
128 /* Reset TWI peripheral */
129 twi_reset(p_twi);
130
132
133 /* Select the speed */
134 if (twi_set_speed(p_twi, p_opt->speed, p_opt->master_clk) == FAIL) {
135 /* The desired speed setting is rejected */
136 status = TWI_INVALID_ARGUMENT;
137 }
138
139 if (p_opt->smbus == 1) {
140 p_twi->TWI_CR = TWI_CR_QUICK;
141 }
142
143 return status;
144}
#define TWI_CR_QUICK
(TWI_CR) SMBUS Quick Command
void twi_enable_master_mode(Twi *p_twi)
Enable TWI master mode.
Definition twi.c:89
uint32_t twi_set_speed(Twi *p_twi, uint32_t ul_speed, uint32_t ul_mck)
Set the I2C bus speed in conjunction with the clock frequency.
Definition twi.c:156
void twi_reset(Twi *p_twi)
Reset TWI.
Definition twi.c:609
uint32_t speed
The baud rate of the TWI bus.
Definition twi.h:78
uint8_t smbus
SMBUS mode (set 1 to use SMBUS quick command, otherwise don't).
Definition twi.h:82
uint32_t master_clk
MCK for TWI.
Definition twi.h:76
#define TWI_SUCCESS
Return codes for TWI APIs.
Definition twi.h:57
#define TWI_INVALID_ARGUMENT
Definition twi.h:58

References twi_options::master_clk, twi_options::smbus, twi_options::speed, Twi::TWI_CR, TWI_CR_QUICK, twi_enable_master_mode(), Twi::TWI_IDR, TWI_INVALID_ARGUMENT, twi_reset(), twi_set_speed(), Twi::TWI_SR, and TWI_SUCCESS.

Referenced by twi_master_setup().

◆ twi_master_read()

uint32_t twi_master_read ( Twi * p_twi,
twi_packet_t * p_packet )

Read multiple bytes from a TWI compatible slave device.

Note
This function will NOT return until all data has been read or error occurs.
Parameters
p_twiPointer to a TWI instance.
p_packetPacket information and data (see twi_packet_t).
Returns
TWI_SUCCESS if all bytes were read, error code otherwise.

Definition at line 278 of file twi.c.

279{
280 uint32_t status;
281 uint32_t cnt = p_packet->length;
282 uint8_t *buffer = p_packet->buffer;
283 uint8_t stop_sent = 0;
284 uint32_t timeout = TWI_TIMEOUT;;
285
286 /* Check argument */
287 if (cnt == 0) {
289 }
290
291 /* Set read mode, slave address and 3 internal address byte lengths */
292 p_twi->TWI_MMR = 0;
293 p_twi->TWI_MMR = TWI_MMR_MREAD | TWI_MMR_DADR(p_packet->chip) |
294 ((p_packet->addr_length << TWI_MMR_IADRSZ_Pos) &
296
297 /* Set internal address for remote chip */
298 p_twi->TWI_IADR = 0;
299 p_twi->TWI_IADR = twi_mk_addr(p_packet->addr, p_packet->addr_length);
300
301 /* Send a START condition */
302 if (cnt == 1) {
304 stop_sent = 1;
305 } else {
306 p_twi->TWI_CR = TWI_CR_START;
307 stop_sent = 0;
308 }
309
310 while (cnt > 0) {
311 status = p_twi->TWI_SR;
312 if (status & TWI_SR_NACK) {
313 return TWI_RECEIVE_NACK;
314 }
315
316 if (!timeout--) {
317 return TWI_ERROR_TIMEOUT;
318 }
319
320 /* Last byte ? */
321 if (cnt == 1 && !stop_sent) {
322 p_twi->TWI_CR = TWI_CR_STOP;
323 stop_sent = 1;
324 }
325
326 if (!(status & TWI_SR_RXRDY)) {
327 continue;
328 }
329 *buffer++ = p_twi->TWI_RHR;
330
331 cnt--;
332 timeout = TWI_TIMEOUT;
333 }
334
335 while (!(p_twi->TWI_SR & TWI_SR_TXCOMP)) {
336 }
337
338 p_twi->TWI_SR;
339
340 return TWI_SUCCESS;
341}
#define TWI_MMR_MREAD
(TWI_MMR) Master Read Direction
#define TWI_SR_TXCOMP
(TWI_SR) Transmission Completed (automatically set / reset)
#define TWI_SR_RXRDY
(TWI_SR) Receive Holding Register Ready (automatically set / reset)
#define TWI_CR_START
(TWI_CR) Send a START Condition
#define TWI_SR_NACK
(TWI_SR) Not Acknowledged (clear on read)
#define TWI_MMR_IADRSZ_Msk
(TWI_MMR) Internal Device Address Size
#define TWI_CR_STOP
(TWI_CR) Send a STOP Condition
#define TWI_MMR_IADRSZ_Pos
#define TWI_MMR_DADR(value)
uint32_t twi_mk_addr(const uint8_t *addr, int len)
Construct the TWI module address register field.
Definition twi.c:249
__I uint32_t TWI_RHR
(Twi Offset: 0x30) Receive Holding Register
__IO uint32_t TWI_IADR
(Twi Offset: 0x0C) Internal Address Register
__IO uint32_t TWI_MMR
(Twi Offset: 0x04) Master Mode Register
uint32_t addr_length
Length of the TWI data address segment (1-3 bytes).
Definition twi.h:92
void * buffer
Where to find the data to be transferred.
Definition twi.h:94
uint32_t length
How many bytes do we want to transfer.
Definition twi.h:96
uint8_t chip
TWI chip address to communicate with.
Definition twi.h:98
uint8_t addr[3]
TWI address/commands to issue to the other chip (node).
Definition twi.h:90
#define TWI_RECEIVE_NACK
Definition twi.h:62
#define TWI_TIMEOUT
Time-out value (number of attempts).
Definition twi.h:51
#define TWI_ERROR_TIMEOUT
Definition twi.h:66

References twi_packet::addr, twi_packet::addr_length, twi_packet::buffer, twi_packet::chip, twi_packet::length, Twi::TWI_CR, TWI_CR_START, TWI_CR_STOP, TWI_ERROR_TIMEOUT, Twi::TWI_IADR, TWI_INVALID_ARGUMENT, twi_mk_addr(), Twi::TWI_MMR, TWI_MMR_DADR, TWI_MMR_IADRSZ_Msk, TWI_MMR_IADRSZ_Pos, TWI_MMR_MREAD, TWI_RECEIVE_NACK, Twi::TWI_RHR, Twi::TWI_SR, TWI_SR_NACK, TWI_SR_RXRDY, TWI_SR_TXCOMP, TWI_SUCCESS, and TWI_TIMEOUT.

◆ twi_master_write()

uint32_t twi_master_write ( Twi * p_twi,
twi_packet_t * p_packet )

Write multiple bytes to a TWI compatible slave device.

Note
This function will NOT return until all data has been written or error occurred.
Parameters
p_twiPointer to a TWI instance.
p_packetPacket information and data (see twi_packet_t).
Returns
TWI_SUCCESS if all bytes were written, error code otherwise.

Definition at line 353 of file twi.c.

354{
355 uint32_t status;
356 uint32_t cnt = p_packet->length;
357 uint8_t *buffer = p_packet->buffer;
358
359 /* Check argument */
360 if (cnt == 0) {
362 }
363
364 /* Set write mode, slave address and 3 internal address byte lengths */
365 p_twi->TWI_MMR = 0;
366 p_twi->TWI_MMR = TWI_MMR_DADR(p_packet->chip) |
367 ((p_packet->addr_length << TWI_MMR_IADRSZ_Pos) &
369
370 /* Set internal address for remote chip */
371 p_twi->TWI_IADR = 0;
372 p_twi->TWI_IADR = twi_mk_addr(p_packet->addr, p_packet->addr_length);
373
374 /* Send all bytes */
375 while (cnt > 0) {
376 status = p_twi->TWI_SR;
377 if (status & TWI_SR_NACK) {
378 return TWI_RECEIVE_NACK;
379 }
380
381 if (!(status & TWI_SR_TXRDY)) {
382 continue;
383 }
384 p_twi->TWI_THR = *buffer++;
385
386 cnt--;
387 }
388
389 while (1) {
390 status = p_twi->TWI_SR;
391 if (status & TWI_SR_NACK) {
392 return TWI_RECEIVE_NACK;
393 }
394
395 if (status & TWI_SR_TXRDY) {
396 break;
397 }
398 }
399
400 p_twi->TWI_CR = TWI_CR_STOP;
401
402 while (!(p_twi->TWI_SR & TWI_SR_TXCOMP)) {
403 }
404
405 return TWI_SUCCESS;
406}
#define TWI_SR_TXRDY
(TWI_SR) Transmit Holding Register Ready (automatically set / reset)
__O uint32_t TWI_THR
(Twi Offset: 0x34) Transmit Holding Register

References twi_packet::addr, twi_packet::addr_length, twi_packet::buffer, twi_packet::chip, twi_packet::length, Twi::TWI_CR, TWI_CR_STOP, Twi::TWI_IADR, TWI_INVALID_ARGUMENT, twi_mk_addr(), Twi::TWI_MMR, TWI_MMR_DADR, TWI_MMR_IADRSZ_Msk, TWI_MMR_IADRSZ_Pos, TWI_RECEIVE_NACK, Twi::TWI_SR, TWI_SR_NACK, TWI_SR_TXCOMP, TWI_SR_TXRDY, TWI_SUCCESS, and Twi::TWI_THR.

Referenced by twi_probe().

◆ twi_mk_addr()

uint32_t twi_mk_addr ( const uint8_t * addr,
int len )

Construct the TWI module address register field.

The TWI module address register is sent out MSB first. And the size controls which byte is the MSB to start with.

Please see the device datasheet for details on this.

Definition at line 249 of file twi.c.

250{
251 uint32_t val;
252
253 if (len == 0)
254 return 0;
255
256 val = addr[0];
257 if (len > 1) {
258 val <<= 8;
259 val |= addr[1];
260 }
261 if (len > 2) {
262 val <<= 8;
263 val |= addr[2];
264 }
265 return val;
266}

Referenced by twi_master_read(), and twi_master_write().

◆ twi_probe()

uint32_t twi_probe ( Twi * p_twi,
uint8_t uc_slave_addr )

Test if a chip answers a given I2C address.

Parameters
p_twiPointer to a TWI instance.
uc_slave_addrAddress of the remote chip to search for.
Returns
TWI_SUCCESS if a chip was found, error code otherwise.

Definition at line 219 of file twi.c.

220{
221 twi_packet_t packet;
222 uint8_t data = 0;
223
224 /* Data to send */
225 packet.buffer = &data;
226 /* Data length */
227 packet.length = 1;
228 /* Slave chip address */
229 packet.chip = (uint32_t) uc_slave_addr;
230 /* Internal chip address */
231 packet.addr[0] = 0;
232 /* Address length */
233 packet.addr_length = 0;
234
235 /* Perform a master write access */
236 return (twi_master_write(p_twi, &packet));
237}
uint32_t twi_master_write(Twi *p_twi, twi_packet_t *p_packet)
Write multiple bytes to a TWI compatible slave device.
Definition twi.c:353
struct twi_packet twi_packet_t
Information concerning the data transmission.

References twi_packet::addr, twi_packet::addr_length, twi_packet::buffer, twi_packet::chip, twi_packet::length, and twi_master_write().

◆ twi_read_byte()

uint8_t twi_read_byte ( Twi * p_twi)

Reads a byte from the TWI bus.

Parameters
p_twiPointer to a TWI instance.
Returns
The byte read.

Definition at line 465 of file twi.c.

466{
467 return p_twi->TWI_RHR;
468}

References Twi::TWI_RHR.

◆ twi_reset()

void twi_reset ( Twi * p_twi)

Reset TWI.

Parameters
p_twiPointer to a TWI instance.

Definition at line 609 of file twi.c.

610{
611 /* Set SWRST bit to reset TWI peripheral */
612 p_twi->TWI_CR = TWI_CR_SWRST;
613 p_twi->TWI_RHR;
614}
#define TWI_CR_SWRST
(TWI_CR) Software Reset

References Twi::TWI_CR, TWI_CR_SWRST, and Twi::TWI_RHR.

Referenced by twi_master_init(), and twi_slave_init().

◆ twi_set_slave_addr()

void twi_set_slave_addr ( Twi * p_twi,
uint32_t ul_device_addr )

Set TWI slave address.

Parameters
p_twiPointer to a TWI instance.
ul_device_addrDevice address of the SAM slave device on the I2C bus.

Definition at line 535 of file twi.c.

536{
537 /* Set slave address */
538 p_twi->TWI_SMR = TWI_SMR_SADR(ul_device_addr);
539}
#define TWI_SMR_SADR(value)
__IO uint32_t TWI_SMR
(Twi Offset: 0x08) Slave Mode Register

References Twi::TWI_SMR, and TWI_SMR_SADR.

◆ twi_set_speed()

uint32_t twi_set_speed ( Twi * p_twi,
uint32_t ul_speed,
uint32_t ul_mck )

Set the I2C bus speed in conjunction with the clock frequency.

Parameters
p_twiPointer to a TWI instance.
ul_speedThe desired I2C bus speed (in Hz).
ul_mckMain clock of the device (in Hz).
Return values
PASSNew speed setting is accepted.
FAILNew speed setting is rejected.

Definition at line 156 of file twi.c.

157{
158 uint32_t ckdiv = 0;
159 uint32_t c_lh_div;
160 uint32_t cldiv, chdiv;
161
162 if (ul_speed > I2C_FAST_MODE_SPEED) {
163 return FAIL;
164 }
165
166 /* Low level time not less than 1.3us of I2C Fast Mode. */
167 if (ul_speed > LOW_LEVEL_TIME_LIMIT) {
168 /* Low level of time fixed for 1.3us. */
170 chdiv = ul_mck / ((ul_speed + (ul_speed - LOW_LEVEL_TIME_LIMIT)) * TWI_CLK_DIVIDER) - TWI_CLK_CALC_ARGU;
171
172 /* cldiv must fit in 8 bits, ckdiv must fit in 3 bits */
173 while ((cldiv > TWI_CLK_DIV_MAX) && (ckdiv < TWI_CLK_DIV_MIN)) {
174 /* Increase clock divider */
175 ckdiv++;
176 /* Divide cldiv value */
177 cldiv /= TWI_CLK_DIVIDER;
178 }
179 /* chdiv must fit in 8 bits, ckdiv must fit in 3 bits */
180 while ((chdiv > TWI_CLK_DIV_MAX) && (ckdiv < TWI_CLK_DIV_MIN)) {
181 /* Increase clock divider */
182 ckdiv++;
183 /* Divide cldiv value */
184 chdiv /= TWI_CLK_DIVIDER;
185 }
186
187 /* set clock waveform generator register */
188 p_twi->TWI_CWGR =
189 TWI_CWGR_CLDIV(cldiv) | TWI_CWGR_CHDIV(chdiv) |
190 TWI_CWGR_CKDIV(ckdiv);
191 } else {
192 c_lh_div = ul_mck / (ul_speed * TWI_CLK_DIVIDER) - TWI_CLK_CALC_ARGU;
193
194 /* cldiv must fit in 8 bits, ckdiv must fit in 3 bits */
195 while ((c_lh_div > TWI_CLK_DIV_MAX) && (ckdiv < TWI_CLK_DIV_MIN)) {
196 /* Increase clock divider */
197 ckdiv++;
198 /* Divide cldiv value */
199 c_lh_div /= TWI_CLK_DIVIDER;
200 }
201
202 /* set clock waveform generator register */
203 p_twi->TWI_CWGR =
204 TWI_CWGR_CLDIV(c_lh_div) | TWI_CWGR_CHDIV(c_lh_div) |
205 TWI_CWGR_CKDIV(ckdiv);
206 }
207
208 return PASS;
209}
#define TWI_CWGR_CHDIV(value)
#define TWI_CWGR_CLDIV(value)
#define TWI_CWGR_CKDIV(value)
#define TWI_CLK_CALC_ARGU
Definition twi.c:77
#define I2C_FAST_MODE_SPEED
Definition twi.c:72
#define TWI_CLK_DIV_MAX
Definition twi.c:79
#define TWI_CLK_DIV_MIN
Definition twi.c:80
#define LOW_LEVEL_TIME_LIMIT
Definition twi.c:71
#define TWI_CLK_DIVIDER
Definition twi.c:73
__IO uint32_t TWI_CWGR
(Twi Offset: 0x10) Clock Waveform Generator Register

References I2C_FAST_MODE_SPEED, LOW_LEVEL_TIME_LIMIT, TWI_CLK_CALC_ARGU, TWI_CLK_DIV_MAX, TWI_CLK_DIV_MIN, TWI_CLK_DIVIDER, Twi::TWI_CWGR, TWI_CWGR_CHDIV, TWI_CWGR_CKDIV, and TWI_CWGR_CLDIV.

Referenced by twi_master_init().

◆ twi_slave_init()

void twi_slave_init ( Twi * p_twi,
uint32_t ul_device_addr )

Initialize TWI slave mode.

Parameters
p_twiPointer to a TWI instance.
ul_device_addrDevice address of the SAM slave device on the I2C bus.

Definition at line 513 of file twi.c.

514{
515 /* Disable TWI interrupts */
516 p_twi->TWI_IDR = ~0UL;
517 p_twi->TWI_SR;
518
519 /* Reset TWI */
520 twi_reset(p_twi);
521
522 /* Set slave address in slave mode */
523 p_twi->TWI_SMR = TWI_SMR_SADR(ul_device_addr);
524
525 /* Enable slave mode */
527}
void twi_enable_slave_mode(Twi *p_twi)
Enable TWI slave mode.
Definition twi.c:486

References twi_enable_slave_mode(), Twi::TWI_IDR, twi_reset(), Twi::TWI_SMR, TWI_SMR_SADR, and Twi::TWI_SR.

Referenced by twi_slave_setup().

◆ twi_slave_read()

uint32_t twi_slave_read ( Twi * p_twi,
uint8_t * p_data )

Read data from master.

Note
This function will NOT return until master sends a STOP condition.
Parameters
p_twiPointer to a TWI instance.
p_dataPointer to the data buffer where data received will be stored.
Returns
Number of bytes read.

Definition at line 551 of file twi.c.

552{
553 uint32_t status, cnt = 0;
554
555 do {
556 status = p_twi->TWI_SR;
557 if (status & TWI_SR_SVACC) {
558 if (!(status & TWI_SR_GACC) &&
559 ((status & (TWI_SR_SVREAD | TWI_SR_RXRDY))
560 == (TWI_SR_SVREAD | TWI_SR_RXRDY))) {
561 *p_data++ = (uint8_t) p_twi->TWI_RHR;
562 cnt++;
563 }
564 } else if ((status & (TWI_SR_EOSACC | TWI_SR_TXCOMP))
566 break;
567 }
568 } while (1);
569
570 return cnt;
571}
#define TWI_SR_GACC
(TWI_SR) General Call Access (clear on read)
#define TWI_SR_EOSACC
(TWI_SR) End Of Slave Access (clear on read)
#define TWI_SR_SVREAD
(TWI_SR) Slave Read (automatically set / reset)
#define TWI_SR_SVACC
(TWI_SR) Slave Access (automatically set / reset)

References Twi::TWI_RHR, Twi::TWI_SR, TWI_SR_EOSACC, TWI_SR_GACC, TWI_SR_RXRDY, TWI_SR_SVACC, TWI_SR_SVREAD, and TWI_SR_TXCOMP.

◆ twi_slave_write()

uint32_t twi_slave_write ( Twi * p_twi,
uint8_t * p_data )

Write data to TWI bus.

Note
This function will NOT return until master sends a STOP condition.
Parameters
p_twiPointer to a TWI instance.
p_dataPointer to the data buffer to be sent.
Returns
Number of bytes written.

Definition at line 583 of file twi.c.

584{
585 uint32_t status, cnt = 0;
586
587 do {
588 status = p_twi->TWI_SR;
589 if (status & TWI_SR_SVACC) {
590 if (!(status & (TWI_SR_GACC | TWI_SR_SVREAD)) &&
591 (status & TWI_SR_TXRDY)) {
592 p_twi->TWI_THR = *p_data++;
593 cnt++;
594 }
595 } else if ((status & (TWI_SR_EOSACC | TWI_SR_TXCOMP))
597 break;
598 }
599 } while (1);
600
601 return cnt;
602}

References Twi::TWI_SR, TWI_SR_EOSACC, TWI_SR_GACC, TWI_SR_SVACC, TWI_SR_SVREAD, TWI_SR_TXCOMP, TWI_SR_TXRDY, and Twi::TWI_THR.

◆ twi_write_byte()

void twi_write_byte ( Twi * p_twi,
uint8_t uc_byte )

Sends a byte of data to one of the TWI slaves on the bus.

Parameters
p_twiPointer to a TWI instance.
uc_byteThe byte to send.

Definition at line 476 of file twi.c.

477{
478 p_twi->TWI_THR = uc_byte;
479}

References Twi::TWI_THR.