1 /*******************************************************************************
\r
2 * (c) Copyright 2009-2015 Microsemi SoC Products Group. All rights reserved.
\r
4 * CoreI2C software driver implementation.
\r
6 * SVN $Revision: 7984 $
\r
7 * SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $
\r
14 #include <sys/stat.h>
\r
15 #include <sys/times.h>
\r
18 #include "cpu_types.h"
\r
19 #include "core_smbus_regs.h"
\r
20 #include "core_i2c.h"
\r
22 #include "hal_assert.h"
\r
31 /*------------------------------------------------------------------------------
\r
32 * I2C transaction direction.
\r
34 #define WRITE_DIR 0u
\r
37 /* -- TRANSACTIONS TYPES -- */
\r
38 #define NO_TRANSACTION 0u
\r
39 #define MASTER_WRITE_TRANSACTION 1u
\r
40 #define MASTER_READ_TRANSACTION 2u
\r
41 #define MASTER_RANDOM_READ_TRANSACTION 3u
\r
42 #define WRITE_SLAVE_TRANSACTION 4u
\r
43 #define READ_SLAVE_TRANSACTION 5u
\r
45 /* -- SMBUS H/W STATES -- */
\r
46 /* -- MASTER STATES -- */
\r
47 #define ST_BUS_ERROR 0x00u /* Bus error during MST or selected slave modes */
\r
48 #define ST_I2C_IDLE 0xF8u /* No activity and no interrupt either... */
\r
49 #define ST_START 0x08u /* start condition sent */
\r
50 #define ST_RESTART 0x10u /* repeated start */
\r
51 #define ST_SLAW_ACK 0x18u /* SLA+W sent, ack received */
\r
52 #define ST_SLAW_NACK 0x20u /* SLA+W sent, nack received */
\r
53 #define ST_TX_DATA_ACK 0x28u /* Data sent, ACK'ed */
\r
54 #define ST_TX_DATA_NACK 0x30u /* Data sent, NACK'ed */
\r
55 #define ST_LOST_ARB 0x38u /* Master lost arbitration */
\r
56 #define ST_SLAR_ACK 0x40u /* SLA+R sent, ACK'ed */
\r
57 #define ST_SLAR_NACK 0x48u /* SLA+R sent, NACK'ed */
\r
58 #define ST_RX_DATA_ACK 0x50u /* Data received, ACK sent */
\r
59 #define ST_RX_DATA_NACK 0x58u /* Data received, NACK sent */
\r
60 #define ST_RESET_ACTIVATED 0xD0u /* Master reset is activated */
\r
61 #define ST_STOP_TRANSMIT 0xE0u /* Stop has been transmitted */
\r
63 /* -- SLAVE STATES -- */
\r
64 #define ST_SLAVE_SLAW 0x60u /* SLA+W received */
\r
65 #define ST_SLAVE_SLAR_ACK 0xA8u /* SLA+R received, ACK returned */
\r
66 #define ST_SLV_LA 0x68u /* Slave lost arbitration */
\r
67 #define ST_GCA 0x70u /* GCA received */
\r
68 #define ST_GCA_LA 0x78u /* GCA lost arbitration */
\r
69 #define ST_RDATA 0x80u /* Data received */
\r
70 #define ST_SLA_NACK 0x88u /* Slave addressed, NACK returned */
\r
71 #define ST_GCA_ACK 0x90u /* Previously addresses with GCA, data ACKed */
\r
72 #define ST_GCA_NACK 0x98u /* GCA addressed, NACK returned */
\r
73 #define ST_RSTOP 0xA0u /* Stop received */
\r
74 #define ST_SLARW_LA 0xB0u /* Arbitration lost */
\r
75 #define ST_RACK 0xB8u /* Byte sent, ACK received */
\r
76 #define ST_SLAVE_RNACK 0xC0u /* Byte sent, NACK received */
\r
77 #define ST_FINAL 0xC8u /* Final byte sent, ACK received */
\r
78 #define ST_SLV_RST 0xD8u /* Slave reset state */
\r
81 /* I2C Channel base offset */
\r
82 #define CHANNEL_BASE_SHIFT 5u
\r
83 #define CHANNEL_MASK 0x1E0u
\r
86 * Maximum address offset length in slave write-read transactions.
\r
87 * A maximum of two bytes will be interpreted as address offset within the slave
\r
90 #define MAX_OFFSET_LENGTH 2u
\r
92 /*------------------------------------------------------------------------------
\r
93 * I2C interrupts control functions implemented "i2c_interrupt.c".
\r
94 * the implementation of these functions depend on the underlying hardware
\r
95 * design and how the CoreI2C interrupt line is connected to the system's
\r
96 * interrupt controller.
\r
98 void I2C_enable_irq( i2c_instance_t * this_i2c );
\r
99 void I2C_disable_irq( i2c_instance_t * this_i2c );
\r
100 static void enable_slave_if_required(i2c_instance_t * this_i2c);
\r
102 /*------------------------------------------------------------------------------
\r
104 * See "core_i2c.h" for details of how to use this function.
\r
108 i2c_instance_t * this_i2c,
\r
109 addr_t base_address,
\r
110 uint8_t ser_address,
\r
111 i2c_clock_divider_t ser_clock_speed
\r
115 uint_fast16_t clock_speed = (uint_fast16_t)ser_clock_speed;
\r
118 * We need to disable ints while doing this as there is no guarantee we
\r
119 * have not been called already and the ISR is active.
\r
122 saved_psr=HAL_disable_interrupts();
\r
125 * Initialize all items of the this_i2c data structure to zero. This
\r
126 * initializes all state variables to their init value. It relies on
\r
127 * the fact that NO_TRANSACTION, I2C_SUCCESS and I2C_RELEASE_BUS all
\r
128 * have an actual value of zero.
\r
130 memset(this_i2c, 0, sizeof(i2c_instance_t));
\r
133 * Set base address of I2C hardware used by this instance.
\r
135 this_i2c->base_address = base_address;
\r
138 * Update Serial address of the device
\r
140 this_i2c->ser_address = ((uint_fast8_t)ser_address << 1u);
\r
143 * Configure hardware.
\r
145 HAL_set_8bit_reg_field(this_i2c->base_address, ENS1, 0x00); /* Reset I2C hardware. */
\r
146 HAL_set_8bit_reg_field(this_i2c->base_address, ENS1, 0x01); /* set enable bit */
\r
147 HAL_set_8bit_reg_field(this_i2c->base_address, CR2, ( (clock_speed >> 2) & 0x01) );
\r
148 HAL_set_8bit_reg_field(this_i2c->base_address, CR1, ( (clock_speed >> 1) & 0x01) );
\r
149 HAL_set_8bit_reg_field(this_i2c->base_address, CR0, ( clock_speed & 0x01) );
\r
151 HAL_set_8bit_reg(this_i2c->base_address, ADDRESS, this_i2c->ser_address);
\r
152 HAL_set_8bit_reg(this_i2c->base_address, ADDRESS1, this_i2c->ser_address);
\r
155 * Finally safe to enable interrupts.
\r
158 HAL_restore_interrupts( saved_psr );
\r
160 /*------------------------------------------------------------------------------
\r
161 * I2C_channel_init()
\r
162 * See "core_i2c.h" for details of how to use this function.
\r
164 void I2C_channel_init
\r
166 i2c_instance_t * this_i2c_channel,
\r
167 i2c_instance_t * this_i2c,
\r
168 i2c_channel_number_t channel_number,
\r
169 i2c_clock_divider_t ser_clock_speed
\r
173 uint_fast16_t clock_speed = (uint_fast16_t)ser_clock_speed;
\r
175 HAL_ASSERT(channel_number < I2C_MAX_CHANNELS);
\r
176 HAL_ASSERT(I2C_CHANNEL_0 != channel_number);
\r
179 * Cannot allow channel 0 in this function as we will trash the hardware
\r
180 * base address and slave address.
\r
182 if ((channel_number < I2C_MAX_CHANNELS) &&
\r
183 (I2C_CHANNEL_0 != channel_number))
\r
186 * We need to disable ints while doing this as the hardware should already
\r
187 * be active at this stage.
\r
190 saved_psr=HAL_disable_interrupts();
\r
192 * Initialize channel data.
\r
194 memset(this_i2c_channel, 0, sizeof(i2c_instance_t));
\r
196 this_i2c_channel->base_address =
\r
197 ((this_i2c->base_address) & ~((addr_t)CHANNEL_MASK))
\r
198 | (((addr_t)channel_number) << CHANNEL_BASE_SHIFT);
\r
200 this_i2c_channel->ser_address = this_i2c->ser_address;
\r
202 HAL_set_8bit_reg_field(this_i2c_channel->base_address, ENS1, 0x00); /* Reset I2C channel hardware. */
\r
203 HAL_set_8bit_reg_field(this_i2c_channel->base_address, ENS1, 0x01); /* set enable bit */
\r
204 HAL_set_8bit_reg_field(this_i2c_channel->base_address, CR2, ( (clock_speed >> 2) & 0x01) );
\r
205 HAL_set_8bit_reg_field(this_i2c_channel->base_address, CR1, ( (clock_speed >> 1) & 0x01) );
\r
206 HAL_set_8bit_reg_field(this_i2c_channel->base_address, CR0, ( clock_speed & 0x01) );
\r
208 * Finally safe to enable interrupts.
\r
211 HAL_restore_interrupts( saved_psr );
\r
215 /*------------------------------------------------------------------------------
\r
217 * See "core_i2c.h" for details of how to use this function.
\r
221 i2c_instance_t * this_i2c,
\r
222 uint8_t serial_addr,
\r
223 const uint8_t * write_buffer,
\r
224 uint16_t write_size,
\r
229 volatile uint8_t stat_ctrl;
\r
232 saved_psr=HAL_disable_interrupts();
\r
234 /* Update the transaction only when there is no transaction going on I2C */
\r
235 if( this_i2c->transaction == NO_TRANSACTION)
\r
237 this_i2c->transaction = MASTER_WRITE_TRANSACTION;
\r
240 /* Update the Pending transaction information so that transaction can restarted */
\r
241 this_i2c->pending_transaction = MASTER_WRITE_TRANSACTION ;
\r
243 /* Update target address */
\r
244 this_i2c->target_addr = (uint_fast8_t)serial_addr << 1u;
\r
245 this_i2c->dir = WRITE_DIR;
\r
246 this_i2c->master_tx_buffer = write_buffer;
\r
247 this_i2c->master_tx_size = write_size;
\r
248 this_i2c->master_tx_idx = 0u;
\r
250 /* Set I2C status in progress */
\r
251 this_i2c->master_status = I2C_IN_PROGRESS;
\r
252 this_i2c->options = options;
\r
254 if(I2C_IN_PROGRESS == this_i2c->slave_status)
\r
256 this_i2c->is_transaction_pending = 1u;
\r
260 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);
\r
264 * Clear interrupts if required (depends on repeated starts).
\r
265 * Since the Bus is on hold, only then prior status needs to
\r
268 if ( I2C_HOLD_BUS == this_i2c->bus_status )
\r
270 HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);
\r
273 stat_ctrl = HAL_get_8bit_reg( this_i2c->base_address, STATUS);
\r
274 stat_ctrl = stat_ctrl; /* Avoids lint warning. */
\r
276 /* Enable the interrupt. ( Re-enable) */
\r
277 I2C_enable_irq( this_i2c );
\r
280 HAL_restore_interrupts(saved_psr);
\r
283 /*------------------------------------------------------------------------------
\r
285 * See "core_i2c.h" for details of how to use this function.
\r
289 i2c_instance_t * this_i2c,
\r
290 uint8_t serial_addr,
\r
291 uint8_t * read_buffer,
\r
292 uint16_t read_size,
\r
297 volatile uint8_t stat_ctrl;
\r
300 saved_psr=HAL_disable_interrupts();
\r
302 /* Update the transaction only when there is no transaction going on I2C */
\r
303 if( this_i2c->transaction == NO_TRANSACTION)
\r
305 this_i2c->transaction = MASTER_READ_TRANSACTION;
\r
308 /* Update the Pending transaction information so that transaction can restarted */
\r
309 this_i2c->pending_transaction = MASTER_READ_TRANSACTION ;
\r
311 /* Update target address */
\r
312 this_i2c->target_addr = (uint_fast8_t)serial_addr << 1u;
\r
314 this_i2c->dir = READ_DIR;
\r
316 this_i2c->master_rx_buffer = read_buffer;
\r
317 this_i2c->master_rx_size = read_size;
\r
318 this_i2c->master_rx_idx = 0u;
\r
320 /* Set I2C status in progress */
\r
321 this_i2c->master_status = I2C_IN_PROGRESS;
\r
323 this_i2c->options = options;
\r
325 if(I2C_IN_PROGRESS == this_i2c->slave_status)
\r
327 this_i2c->is_transaction_pending = 1u;
\r
331 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);
\r
335 * Clear interrupts if required (depends on repeated starts).
\r
336 * Since the Bus is on hold, only then prior status needs to
\r
339 if ( I2C_HOLD_BUS == this_i2c->bus_status )
\r
341 HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);
\r
344 stat_ctrl = HAL_get_8bit_reg( this_i2c->base_address, STATUS);
\r
345 stat_ctrl = stat_ctrl; /* Avoids lint warning. */
\r
347 /* Enable the interrupt. ( Re-enable) */
\r
348 I2C_enable_irq( this_i2c );
\r
350 HAL_restore_interrupts( saved_psr );
\r
354 /*------------------------------------------------------------------------------
\r
356 * See "core_i2c.h" for details of how to use this function.
\r
358 void I2C_write_read
\r
360 i2c_instance_t * this_i2c,
\r
361 uint8_t serial_addr,
\r
362 const uint8_t * addr_offset,
\r
363 uint16_t offset_size,
\r
364 uint8_t * read_buffer,
\r
365 uint16_t read_size,
\r
369 HAL_ASSERT(offset_size > 0u);
\r
370 HAL_ASSERT(addr_offset != (uint8_t *)0);
\r
371 HAL_ASSERT(read_size > 0u);
\r
372 HAL_ASSERT(read_buffer != (uint8_t *)0);
\r
374 this_i2c->master_status = I2C_FAILED;
\r
376 if((read_size > 0u) && (offset_size > 0u))
\r
379 volatile uint8_t stat_ctrl;
\r
382 saved_psr=HAL_disable_interrupts();
\r
384 /* Update the transaction only when there is no transaction going on I2C */
\r
385 if( this_i2c->transaction == NO_TRANSACTION)
\r
387 this_i2c->transaction = MASTER_RANDOM_READ_TRANSACTION;
\r
390 /* Update the Pending transaction information so that transaction can restarted */
\r
391 this_i2c->pending_transaction = MASTER_RANDOM_READ_TRANSACTION ;
\r
393 /* Update target address */
\r
394 this_i2c->target_addr = (uint_fast8_t)serial_addr << 1u;
\r
396 this_i2c->dir = WRITE_DIR;
\r
398 this_i2c->master_tx_buffer = addr_offset;
\r
399 this_i2c->master_tx_size = offset_size;
\r
400 this_i2c->master_tx_idx = 0u;
\r
402 this_i2c->master_rx_buffer = read_buffer;
\r
403 this_i2c->master_rx_size = read_size;
\r
404 this_i2c->master_rx_idx = 0u;
\r
406 /* Set I2C status in progress */
\r
407 this_i2c->master_status = I2C_IN_PROGRESS;
\r
408 this_i2c->options = options;
\r
410 if(I2C_IN_PROGRESS == this_i2c->slave_status)
\r
412 this_i2c->is_transaction_pending = 1u;
\r
416 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);
\r
420 * Clear interrupts if required (depends on repeated starts).
\r
421 * Since the Bus is on hold, only then prior status needs to
\r
424 if ( I2C_HOLD_BUS == this_i2c->bus_status )
\r
426 HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);
\r
429 stat_ctrl = HAL_get_8bit_reg( this_i2c->base_address, STATUS);
\r
430 stat_ctrl = stat_ctrl; /* Avoids lint warning. */
\r
432 /* Enable the interrupt. ( Re-enable) */
\r
433 I2C_enable_irq( this_i2c );
\r
436 HAL_restore_interrupts( saved_psr );
\r
440 /*------------------------------------------------------------------------------
\r
442 * See "core_i2c.h" for details of how to use this function.
\r
444 i2c_status_t I2C_get_status
\r
446 i2c_instance_t * this_i2c
\r
449 i2c_status_t i2c_status ;
\r
451 i2c_status = this_i2c->master_status ;
\r
456 /*------------------------------------------------------------------------------
\r
457 * I2C_wait_complete()
\r
458 * See "core_i2c.h" for details of how to use this function.
\r
460 i2c_status_t I2C_wait_complete
\r
462 i2c_instance_t * this_i2c,
\r
463 uint32_t timeout_ms
\r
466 i2c_status_t i2c_status;
\r
469 * Because we have no idea of what CPU we are supposed to be running on
\r
470 * we need to guard this write to the timeout value to avoid ISR/user code
\r
471 * interaction issues. Checking the status below should be fine as only a
\r
472 * single byte should change in that.
\r
475 saved_psr=HAL_disable_interrupts();
\r
476 this_i2c->master_timeout_ms = timeout_ms;
\r
478 HAL_restore_interrupts( saved_psr );
\r
480 /* Run the loop until state returns I2C_FAILED or I2C_SUCESS*/
\r
482 i2c_status = this_i2c->master_status;
\r
483 } while(I2C_IN_PROGRESS == i2c_status);
\r
487 /*------------------------------------------------------------------------------
\r
488 * I2C_system_tick()
\r
489 * See "core_i2c.h" for details of how to use this function.
\r
491 void I2C_system_tick
\r
493 i2c_instance_t * this_i2c,
\r
494 uint32_t ms_since_last_tick
\r
497 if(this_i2c->master_timeout_ms != I2C_NO_TIMEOUT)
\r
499 if(this_i2c->master_timeout_ms > ms_since_last_tick)
\r
501 this_i2c->master_timeout_ms -= ms_since_last_tick;
\r
507 * We need to disable interrupts here to ensure we can update the
\r
508 * shared data without the I2C ISR interrupting us.
\r
511 saved_psr=HAL_disable_interrupts();
\r
514 * Mark current transaction as having timed out.
\r
516 this_i2c->master_status = I2C_TIMED_OUT;
\r
517 this_i2c->transaction = NO_TRANSACTION;
\r
518 this_i2c->is_transaction_pending = 0;
\r
521 HAL_restore_interrupts( saved_psr );
\r
524 * Make sure we do not incorrectly signal a timeout for subsequent
\r
527 this_i2c->master_timeout_ms = I2C_NO_TIMEOUT;
\r
532 /*------------------------------------------------------------------------------
\r
533 * I2C_set_slave_tx_buffer()
\r
534 * See "core_i2c.h" for details of how to use this function.
\r
536 void I2C_set_slave_tx_buffer
\r
538 i2c_instance_t * this_i2c,
\r
539 const uint8_t * tx_buffer,
\r
546 * We need to disable interrupts here to ensure we can update the
\r
547 * shared data without the I2C ISR interrupting us.
\r
550 saved_psr=HAL_disable_interrupts();
\r
552 this_i2c->slave_tx_buffer = tx_buffer;
\r
553 this_i2c->slave_tx_size = tx_size;
\r
554 this_i2c->slave_tx_idx = 0u;
\r
557 HAL_restore_interrupts( saved_psr );
\r
560 /*------------------------------------------------------------------------------
\r
561 * I2C_set_slave_rx_buffer()
\r
562 * See "core_i2c.h" for details of how to use this function.
\r
564 void I2C_set_slave_rx_buffer
\r
566 i2c_instance_t * this_i2c,
\r
567 uint8_t * rx_buffer,
\r
574 * We need to disable interrupts here to ensure we can update the
\r
575 * shared data without the I2C ISR interrupting us.
\r
578 saved_psr=HAL_disable_interrupts();
\r
580 this_i2c->slave_rx_buffer = rx_buffer;
\r
581 this_i2c->slave_rx_size = rx_size;
\r
582 this_i2c->slave_rx_idx = 0u;
\r
585 HAL_restore_interrupts( saved_psr );
\r
588 /*------------------------------------------------------------------------------
\r
589 * I2C_set_slave_mem_offset_length()
\r
590 * See "core_i2c.h" for details of how to use this function.
\r
592 void I2C_set_slave_mem_offset_length
\r
594 i2c_instance_t * this_i2c,
\r
595 uint8_t offset_length
\r
598 HAL_ASSERT(offset_length <= MAX_OFFSET_LENGTH);
\r
601 * Single byte update, should be interrupt safe
\r
603 if(offset_length > MAX_OFFSET_LENGTH)
\r
605 this_i2c->slave_mem_offset_length = MAX_OFFSET_LENGTH;
\r
609 this_i2c->slave_mem_offset_length = offset_length;
\r
613 /*------------------------------------------------------------------------------
\r
614 * I2C_register_write_handler()
\r
615 * See "core_i2c.h" for details of how to use this function.
\r
617 void I2C_register_write_handler
\r
619 i2c_instance_t * this_i2c,
\r
620 i2c_slave_wr_handler_t handler
\r
626 * We need to disable interrupts here to ensure we can update the
\r
627 * shared data without the I2C ISR interrupting us.
\r
630 saved_psr=HAL_disable_interrupts();
\r
632 this_i2c->slave_write_handler = handler;
\r
635 HAL_restore_interrupts( saved_psr );
\r
638 /*------------------------------------------------------------------------------
\r
639 * I2C_enable_slave()
\r
640 * See "core_i2c.h" for details of how to use this function.
\r
642 void I2C_enable_slave
\r
644 i2c_instance_t * this_i2c
\r
650 * We need to disable interrupts here to ensure we can update the
\r
651 * hardware register and slave mode flag without the I2C ISR interrupting
\r
655 saved_psr=HAL_disable_interrupts();
\r
657 /* Set the Assert Acknowledge bit. */
\r
658 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);
\r
660 /* Enable slave mode */
\r
661 this_i2c->is_slave_enabled = 1u;
\r
664 HAL_restore_interrupts( saved_psr );
\r
666 /* Enable I2C IRQ*/
\r
667 I2C_enable_irq( this_i2c );
\r
670 /*------------------------------------------------------------------------------
\r
671 * I2C_disable_slave()
\r
672 * See "core_i2c.h" for details of how to use this function.
\r
674 void I2C_disable_slave
\r
676 i2c_instance_t * this_i2c
\r
682 * We need to disable interrupts here to ensure we can update the
\r
683 * hardware register without the I2C ISR interrupting us.
\r
686 saved_psr=HAL_disable_interrupts();
\r
688 /* Reset the assert acknowledge bit. */
\r
689 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);
\r
691 /* Disable slave mode with IRQ blocked to make whole change atomic */
\r
692 this_i2c->is_slave_enabled = 0u;
\r
695 HAL_restore_interrupts( saved_psr );
\r
698 /*------------------------------------------------------------------------------
\r
701 static void enable_slave_if_required
\r
703 i2c_instance_t * this_i2c
\r
707 * This function is only called from within the ISR and so does not need
\r
708 * guarding on the register access.
\r
710 if( 0 != this_i2c->is_slave_enabled )
\r
712 HAL_set_8bit_reg_field( this_i2c->base_address, AA, 0x01u );
\r
715 /*------------------------------------------------------------------------------
\r
716 * I2C_set_slave_second_addr()
\r
717 * See "i2c.h" for details of how to use this function.
\r
719 void I2C_set_slave_second_addr
\r
721 i2c_instance_t * this_i2c,
\r
722 uint8_t second_slave_addr
\r
725 uint8_t second_slave_address;
\r
728 This function does not support CoreI2C hardware configured with a fixed
\r
729 second slave address. The current implementation of the ADDR1[0] register
\r
730 bit makes it difficult for the driver to support both programmable and
\r
731 fixed second slave address, so we choose to support programmable only.
\r
732 With the programmable configuration, ADDR1[0] and ADDR0[0] both control
\r
733 enable/disable of GCA recognition, as an effective OR of the 2 bit fields.
\r
734 Therefore we set ADDR1[0] to 0 here, so that only ADDR0[0] controls GCA.
\r
736 second_slave_address = (uint8_t)((second_slave_addr << 1u) & (~SLAVE1_EN_MASK));
\r
739 * Single byte register write, should be interrupt safe
\r
741 HAL_set_8bit_reg(this_i2c->base_address, ADDRESS1, second_slave_address);
\r
744 /*------------------------------------------------------------------------------
\r
745 * I2C_disable_slave_second_addr()
\r
746 * See "i2c.h" for details of how to use this function.
\r
748 void I2C_disable_slave_second_addr
\r
750 i2c_instance_t * this_i2c
\r
754 We are disabling the second slave address by setting the value of the 2nd
\r
755 slave address to the primary slave address. The reason for using this method
\r
756 of disabling 2nd slave address is that ADDRESS1[0] has different meaning
\r
757 depending on hardware configuration. Its use would likely interfere with
\r
758 the intended GCA setting.
\r
761 * Single byte register write, should be interrupt safe
\r
763 HAL_set_8bit_reg(this_i2c->base_address, ADDRESS1, this_i2c->ser_address);
\r
766 /*------------------------------------------------------------------------------
\r
768 * See "i2c.h" for details of how to use this function.
\r
773 i2c_instance_t * this_i2c
\r
777 * This read modify write access should be interrupt safe as the address
\r
778 * register is not written to in the ISR.
\r
780 /* accept GC addressing. */
\r
781 HAL_set_8bit_reg_field(this_i2c->base_address, GC, 0x01u);
\r
784 /*------------------------------------------------------------------------------
\r
786 * See "i2c.h" for details of how to use this function.
\r
790 i2c_instance_t * this_i2c
\r
794 * This read modify write access should be interrupt safe as the address
\r
795 * register is not written to in the ISR.
\r
797 /* Clear GC addressing. */
\r
798 HAL_set_8bit_reg_field(this_i2c->base_address, GC, 0x00u);
\r
801 /*------------------------------------------------------------------------------
\r
803 * See "core_i2c.h" for details of how to use this function.
\r
807 i2c_instance_t * this_i2c
\r
810 volatile uint8_t status;
\r
813 uint8_t clear_irq = 1u;
\r
815 status = HAL_get_8bit_reg( this_i2c->base_address, STATUS);
\r
819 /************** MASTER TRANSMITTER / RECEIVER *******************/
\r
821 case ST_START: /* start has been xmt'd */
\r
822 case ST_RESTART: /* repeated start has been xmt'd */
\r
823 //write_hex(STDOUT_FILENO, status);
\r
824 HAL_set_8bit_reg_field( this_i2c->base_address, STA, 0x00u);
\r
825 HAL_set_8bit_reg( this_i2c->base_address, DATA, this_i2c->target_addr); /* write call address */
\r
826 HAL_set_8bit_reg_field( this_i2c->base_address, DIR, this_i2c->dir); /* set direction bit */
\r
827 if(this_i2c->dir == WRITE_DIR)
\r
829 this_i2c->master_tx_idx = 0u;
\r
833 this_i2c->master_rx_idx = 0u;
\r
837 * Clear the pending transaction. This condition will be true if the slave
\r
838 * has acquired the bus to carry out pending master transaction which
\r
839 * it had received during its slave transmission or reception mode.
\r
841 if(this_i2c->is_transaction_pending)
\r
843 this_i2c->is_transaction_pending = 0u;
\r
847 * Make sure to update proper transaction after master START
\r
850 if(this_i2c->transaction != this_i2c->pending_transaction)
\r
852 this_i2c->transaction = this_i2c->pending_transaction;
\r
857 /* Set start bit. Let's keep trying! Don't give up! */
\r
858 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);
\r
861 case ST_STOP_TRANSMIT:
\r
862 /* Stop has been transmitted. Do nothing */
\r
865 /******************* MASTER TRANSMITTER *************************/
\r
867 //write_hex(STDOUT_FILENO, status);
\r
868 /* SLA+W has been transmitted; not ACK has been received - let's stop. */
\r
869 HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);
\r
870 this_i2c->master_status = I2C_FAILED;
\r
871 this_i2c->transaction = NO_TRANSACTION;
\r
872 enable_slave_if_required(this_i2c);
\r
876 case ST_TX_DATA_ACK:
\r
877 //write_hex(STDOUT_FILENO, status);
\r
878 /* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */
\r
879 if (this_i2c->master_tx_idx < this_i2c->master_tx_size)
\r
881 HAL_set_8bit_reg(this_i2c->base_address, DATA, (uint_fast8_t)this_i2c->master_tx_buffer[this_i2c->master_tx_idx++]);
\r
883 else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION )
\r
885 /* We are finished sending the address offset part of a random read transaction.
\r
886 * It is is time to send a restart in order to change direction. */
\r
887 this_i2c->dir = READ_DIR;
\r
888 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);
\r
890 else /* done sending. let's stop */
\r
893 * Set the transaction back to NO_TRANSACTION to allow user to do further
\r
896 this_i2c->transaction = NO_TRANSACTION;
\r
897 hold_bus = this_i2c->options & I2C_HOLD_BUS;
\r
899 /* Store the information of current I2C bus status in the bus_status*/
\r
900 this_i2c->bus_status = hold_bus;
\r
901 if ( hold_bus == 0u )
\r
903 HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u); /*xmt stop condition */
\r
904 enable_slave_if_required(this_i2c);
\r
908 I2C_disable_irq( this_i2c );
\r
911 this_i2c->master_status = I2C_SUCCESS;
\r
915 case ST_TX_DATA_NACK:
\r
916 //write_hex(STDOUT_FILENO, status);
\r
917 /* data byte SENT, ACK to be received
\r
918 * In fact, this means we've received a NACK (This may not be
\r
919 * obvious, but if we've rec'd an ACK then we would be in state
\r
920 * 0x28!) hence, let's send a stop bit
\r
922 HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);/* xmt stop condition */
\r
923 this_i2c->master_status = I2C_FAILED;
\r
926 * Set the transaction back to NO_TRANSACTION to allow user to do further
\r
929 this_i2c->transaction = NO_TRANSACTION;
\r
930 enable_slave_if_required(this_i2c);
\r
933 /********************* MASTER (or slave?) RECEIVER *************************/
\r
935 /* STATUS codes 08H, 10H, 38H are all covered in MTX mode */
\r
936 case ST_SLAR_ACK: /* SLA+R tx'ed. */
\r
937 // //write_hex(STDOUT_FILENO, status);
\r
938 /* Let's make sure we ACK the first data byte received (set AA bit in CTRL) unless
\r
939 * the next byte is the last byte of the read transaction.
\r
941 if(this_i2c->master_rx_size > 1u)
\r
943 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);
\r
945 else if(1u == this_i2c->master_rx_size)
\r
947 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);
\r
949 else /* this_i2c->master_rx_size == 0u */
\r
951 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);
\r
952 HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);
\r
953 this_i2c->master_status = I2C_SUCCESS;
\r
954 this_i2c->transaction = NO_TRANSACTION;
\r
958 case ST_SLAR_NACK: /* SLA+R tx'ed; let's release the bus (send a stop condition) */
\r
959 // //write_hex(STDOUT_FILENO, status);
\r
960 HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u);
\r
961 this_i2c->master_status = I2C_FAILED;
\r
964 * Set the transaction back to NO_TRANSACTION to allow user to do further
\r
967 this_i2c->transaction = NO_TRANSACTION;
\r
968 enable_slave_if_required(this_i2c);
\r
971 case ST_RX_DATA_ACK: /* Data byte received, ACK returned */
\r
972 // //write_hex(STDOUT_FILENO, status);
\r
973 /* First, get the data */
\r
974 this_i2c->master_rx_buffer[this_i2c->master_rx_idx++] = HAL_get_8bit_reg(this_i2c->base_address, DATA);
\r
975 if( this_i2c->master_rx_idx >= (this_i2c->master_rx_size - 1u))
\r
977 /* If we're at the second last byte, let's set AA to 0 so
\r
978 * we return a NACK at the last byte. */
\r
979 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);
\r
983 case ST_RX_DATA_NACK: /* Data byte received, NACK returned */
\r
984 // //write_hex(STDOUT_FILENO, status);
\r
985 /* Get the data, then send a stop condition */
\r
986 this_i2c->master_rx_buffer[this_i2c->master_rx_idx] = HAL_get_8bit_reg(this_i2c->base_address, DATA);
\r
988 hold_bus = this_i2c->options & I2C_HOLD_BUS;
\r
990 /* Store the information of current I2C bus status in the bus_status*/
\r
991 this_i2c->bus_status = hold_bus;
\r
992 if ( hold_bus == 0u )
\r
994 HAL_set_8bit_reg_field(this_i2c->base_address, STO, 0x01u); /*xmt stop condition */
\r
996 /* Bus is released, now we can start listening to bus, if it is slave */
\r
997 enable_slave_if_required(this_i2c);
\r
1001 I2C_disable_irq( this_i2c );
\r
1005 * Set the transaction back to NO_TRANSACTION to allow user to do further
\r
1008 this_i2c->transaction = NO_TRANSACTION;
\r
1009 this_i2c->master_status = I2C_SUCCESS;
\r
1012 /******************** SLAVE RECEIVER **************************/
\r
1013 case ST_GCA_NACK: /* NACK after, GCA addressing */
\r
1014 case ST_SLA_NACK: /* Re-enable AA (assert ack) bit for future transmissions */
\r
1015 //write_hex(STDOUT_FILENO, status);
\r
1016 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);
\r
1018 this_i2c->transaction = NO_TRANSACTION;
\r
1019 this_i2c->slave_status = I2C_SUCCESS;
\r
1021 /* Check if transaction was pending. If yes, set the START bit */
\r
1022 if(this_i2c->is_transaction_pending)
\r
1024 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);
\r
1028 case ST_GCA_LA: /* Arbitr. lost (GCA rec'd) */
\r
1029 case ST_SLV_LA: /* Arbitr. lost (SLA rec'd) */
\r
1030 //write_hex(STDOUT_FILENO, status);
\r
1032 * We lost arbitration and either the GCE or our address was the
\r
1033 * one received so pend the master operation we were starting.
\r
1035 this_i2c->is_transaction_pending = 1u;
\r
1036 /* Fall through to normal ST processing as we are now in slave mode */
\r
1038 case ST_GCA: /* General call address received, ACK returned */
\r
1039 case ST_SLAVE_SLAW: /* SLA+W received, ACK returned */
\r
1040 //write_hex(STDOUT_FILENO, status);
\r
1041 this_i2c->transaction = WRITE_SLAVE_TRANSACTION;
\r
1042 this_i2c->slave_rx_idx = 0u;
\r
1043 this_i2c->random_read_addr = 0u;
\r
1045 * If Start Bit is set clear it, but store that information since it is because of
\r
1046 * pending transaction
\r
1048 if(HAL_get_8bit_reg_field(this_i2c->base_address, STA))
\r
1050 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x00u);
\r
1051 this_i2c->is_transaction_pending = 1u;
\r
1053 this_i2c->slave_status = I2C_IN_PROGRESS;
\r
1054 #ifdef INCLUDE_SLA_IN_RX_PAYLOAD
\r
1055 /* Fall through to put address as first byte in payload buffer */
\r
1057 /* Only break from this case if the slave address must NOT be included at the
\r
1058 * beginning of the received write data. */
\r
1061 case ST_GCA_ACK: /* DATA received; ACK sent after GCA */
\r
1062 case ST_RDATA: /* DATA received; must clear DATA register */
\r
1063 //write_hex(STDOUT_FILENO, status);
\r
1064 if((this_i2c->slave_rx_buffer != (uint8_t *)0)
\r
1065 && (this_i2c->slave_rx_idx < this_i2c->slave_rx_size))
\r
1067 data = HAL_get_8bit_reg(this_i2c->base_address, DATA);
\r
1068 this_i2c->slave_rx_buffer[this_i2c->slave_rx_idx++] = data;
\r
1070 #ifdef INCLUDE_SLA_IN_RX_PAYLOAD
\r
1071 if((ST_RDATA == status) || (ST_GCA_ACK == status))
\r
1073 /* Ignore the slave address byte in the random read address
\r
1074 computation in the case where INCLUDE_SLA_IN_RX_PAYLOAD
\r
1077 this_i2c->random_read_addr = (this_i2c->random_read_addr << 8) + data;
\r
1078 #ifdef INCLUDE_SLA_IN_RX_PAYLOAD
\r
1083 if(this_i2c->slave_rx_idx >= this_i2c->slave_rx_size)
\r
1085 /* Rx buffer is full. NACK next received byte. */
\r
1086 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);
\r
1091 //write_hex(STDOUT_FILENO, status);
\r
1092 /* STOP or repeated START occurred. */
\r
1093 /* We cannot be sure if the transaction has actually completed as
\r
1094 * this hardware state reports that either a STOP or repeated START
\r
1095 * condition has occurred. We assume that this is a repeated START
\r
1096 * if the transaction was a write from the master to this point.*/
\r
1097 if ( this_i2c->transaction == WRITE_SLAVE_TRANSACTION )
\r
1099 if ( this_i2c->slave_rx_idx == this_i2c->slave_mem_offset_length )
\r
1101 this_i2c->slave_tx_idx = this_i2c->random_read_addr;
\r
1103 /* Call the slave's write transaction handler if it exists. */
\r
1104 if ( this_i2c->slave_write_handler != 0u )
\r
1106 i2c_slave_handler_ret_t h_ret;
\r
1107 h_ret = this_i2c->slave_write_handler( this_i2c, this_i2c->slave_rx_buffer, (uint16_t)this_i2c->slave_rx_idx );
\r
1108 if ( I2C_REENABLE_SLAVE_RX == h_ret )
\r
1110 /* There is a small risk that the write handler could
\r
1111 * call I2C_disable_slave() but return
\r
1112 * I2C_REENABLE_SLAVE_RX in error so we only enable
\r
1113 * ACKs if still in slave mode. */
\r
1114 enable_slave_if_required(this_i2c);
\r
1118 HAL_set_8bit_reg_field( this_i2c->base_address, AA, 0x0u );
\r
1119 /* Clear slave mode flag as well otherwise in mixed
\r
1120 * master/slave applications, the AA bit will get set by
\r
1121 * subsequent master operations. */
\r
1122 this_i2c->is_slave_enabled = 0u;
\r
1127 /* Re-enable address acknowledge in case we were ready to nack the next received byte. */
\r
1128 HAL_set_8bit_reg_field( this_i2c->base_address, AA, 0x01u );
\r
1131 else /* A stop or repeated start outside a write/read operation */
\r
1134 * Reset slave_tx_idx so that a subsequent read will result in the slave's
\r
1135 * transmit buffer being sent from the first byte.
\r
1137 this_i2c->slave_tx_idx = 0u;
\r
1139 * See if we need to re-enable acknowledgement as some error conditions, such
\r
1140 * as a master prematurely ending a transfer, can see us get here with AA set
\r
1141 * to 0 which will disable slave operation if we are not careful.
\r
1143 enable_slave_if_required(this_i2c);
\r
1146 /* Mark any previous master write transaction as complete. */
\r
1147 this_i2c->slave_status = I2C_SUCCESS;
\r
1149 /* Check if transaction was pending. If yes, set the START bit */
\r
1150 if(this_i2c->is_transaction_pending)
\r
1152 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);
\r
1156 * Set the transaction back to NO_TRANSACTION to allow user to do further
\r
1159 this_i2c->transaction = NO_TRANSACTION;
\r
1163 case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */
\r
1164 //write_hex(STDOUT_FILENO, status);
\r
1166 * Set the transaction back to NO_TRANSACTION to allow user to do further
\r
1169 this_i2c->transaction = NO_TRANSACTION;
\r
1171 * Reset slave_tx_idx so that a subsequent read will result in the slave's
\r
1172 * transmit buffer being sent from the first byte.
\r
1174 this_i2c->slave_tx_idx = 0u;
\r
1176 * Clear status to I2C_FAILED only if there was an operation in progress.
\r
1178 if(I2C_IN_PROGRESS == this_i2c->slave_status)
\r
1180 this_i2c->slave_status = I2C_FAILED;
\r
1183 enable_slave_if_required(this_i2c); /* Make sure AA is set correctly */
\r
1187 /****************** SLAVE TRANSMITTER **************************/
\r
1188 case ST_SLAVE_SLAR_ACK: /* SLA+R received, ACK returned */
\r
1189 case ST_SLARW_LA: /* Arbitration lost, and: */
\r
1190 case ST_RACK: /* Data tx'ed, ACK received */
\r
1191 //write_hex(STDOUT_FILENO, status);
\r
1192 if ( status == ST_SLAVE_SLAR_ACK )
\r
1194 this_i2c->transaction = READ_SLAVE_TRANSACTION;
\r
1195 this_i2c->random_read_addr = 0u;
\r
1196 this_i2c->slave_status = I2C_IN_PROGRESS;
\r
1197 /* If Start Bit is set clear it, but store that information since it is because of
\r
1198 * pending transaction
\r
1200 if(HAL_get_8bit_reg_field(this_i2c->base_address, STA))
\r
1202 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x00u);
\r
1203 this_i2c->is_transaction_pending = 1u;
\r
1206 if (this_i2c->slave_tx_idx >= this_i2c->slave_tx_size)
\r
1208 /* Ensure 0xFF is returned to the master when the slave specifies
\r
1209 * an empty transmit buffer. */
\r
1210 HAL_set_8bit_reg(this_i2c->base_address, DATA, 0xFFu);
\r
1214 /* Load the data the data byte to be sent to the master. */
\r
1215 HAL_set_8bit_reg(this_i2c->base_address, DATA, (uint_fast8_t)this_i2c->slave_tx_buffer[this_i2c->slave_tx_idx++]);
\r
1217 /* Determine if this is the last data byte to send to the master. */
\r
1218 if (this_i2c->slave_tx_idx >= this_i2c->slave_tx_size) /* last byte? */
\r
1220 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x00u);
\r
1221 /* Next read transaction will result in slave's transmit buffer
\r
1222 * being sent from the first byte. */
\r
1223 this_i2c->slave_tx_idx = 0u;
\r
1227 case ST_SLAVE_RNACK: /* Data byte has been transmitted; not-ACK has been received. */
\r
1228 case ST_FINAL: /* Last Data byte tx'ed, ACK received */
\r
1229 //write_hex(STDOUT_FILENO, status);
\r
1230 /* We assume that the transaction will be stopped by the master.
\r
1231 * Reset slave_tx_idx so that a subsequent read will result in the slave's
\r
1232 * transmit buffer being sent from the first byte. */
\r
1233 this_i2c->slave_tx_idx = 0u;
\r
1234 HAL_set_8bit_reg_field(this_i2c->base_address, AA, 0x01u);
\r
1236 /* Mark previous state as complete */
\r
1237 this_i2c->slave_status = I2C_SUCCESS;
\r
1238 /* Check if transaction was pending. If yes, set the START bit */
\r
1239 if(this_i2c->is_transaction_pending)
\r
1241 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x01u);
\r
1244 * Set the transaction back to NO_TRANSACTION to allow user to do further
\r
1247 this_i2c->transaction = NO_TRANSACTION;
\r
1251 /* Master Reset has been activated Wait 35 ms for interrupt to be set,
\r
1252 * clear interrupt and proceed to 0xF8 state. */
\r
1253 case ST_RESET_ACTIVATED:
\r
1254 case ST_BUS_ERROR: /* Bus error during MST or selected slave modes */
\r
1256 //write_hex(STDOUT_FILENO, status);
\r
1257 /* Some undefined state has encountered. Clear Start bit to make
\r
1258 * sure, next good transaction happen */
\r
1259 HAL_set_8bit_reg_field(this_i2c->base_address, STA, 0x00u);
\r
1261 * Set the transaction back to NO_TRANSACTION to allow user to do further
\r
1264 this_i2c->transaction = NO_TRANSACTION;
\r
1266 * Reset slave_tx_idx so that a subsequent read will result in the slave's
\r
1267 * transmit buffer being sent from the first byte.
\r
1269 this_i2c->slave_tx_idx = 0u;
\r
1271 * Clear statuses to I2C_FAILED only if there was an operation in progress.
\r
1273 if(I2C_IN_PROGRESS == this_i2c->master_status)
\r
1275 this_i2c->master_status = I2C_FAILED;
\r
1278 if(I2C_IN_PROGRESS == this_i2c->slave_status)
\r
1280 this_i2c->slave_status = I2C_FAILED;
\r
1288 /* clear interrupt. */
\r
1289 HAL_set_8bit_reg_field(this_i2c->base_address, SI, 0x00u);
\r
1292 /* Read the status register to ensure the last I2C registers write took place
\r
1293 * in a system built around a bus making use of posted writes. */
\r
1294 // status = HAL_get_8bit_reg( this_i2c->base_address, STATUS);
\r
1297 /*------------------------------------------------------------------------------
\r
1298 * I2C_smbus_init()
\r
1299 * See "i2c.h" for details of how to use this function.
\r
1305 * SMBus enable = 1
\r
1307 #define INIT_AND_ENABLE_SMBUS 0x54u
\r
1308 void I2C_smbus_init
\r
1310 i2c_instance_t * this_i2c
\r
1314 * Single byte register write, should be interrupt safe
\r
1316 /* Enable SMBUS */
\r
1317 HAL_set_8bit_reg(this_i2c->base_address, SMBUS, INIT_AND_ENABLE_SMBUS);
\r
1320 /*------------------------------------------------------------------------------
\r
1321 * I2C_enable_smbus_irq()
\r
1322 * See "i2c.h" for details of how to use this function.
\r
1324 void I2C_enable_smbus_irq
\r
1326 i2c_instance_t * this_i2c,
\r
1333 * We need to disable interrupts here to ensure we can update the
\r
1334 * hardware register without the SMBUS IRQs interrupting us.
\r
1337 saved_psr=HAL_disable_interrupts();
\r
1339 if ( irq_type & I2C_SMBALERT_IRQ)
\r
1341 HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_IE, 0x01u);
\r
1343 if ( irq_type & I2C_SMBSUS_IRQ)
\r
1345 HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_IE, 0x01u);
\r
1349 HAL_restore_interrupts( saved_psr );
\r
1352 /*------------------------------------------------------------------------------
\r
1353 * I2C_disable_smbus_irq()
\r
1354 * See "i2c.h" for details of how to use this function.
\r
1356 void I2C_disable_smbus_irq
\r
1358 i2c_instance_t * this_i2c,
\r
1365 * We need to disable interrupts here to ensure we can update the
\r
1366 * hardware register without the SMBUS IRQs interrupting us.
\r
1369 saved_psr=HAL_disable_interrupts();
\r
1371 if ( irq_type & I2C_SMBALERT_IRQ)
\r
1373 HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_IE, 0x00u);
\r
1375 if (irq_type & I2C_SMBSUS_IRQ )
\r
1377 HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_IE, 0x00u);
\r
1381 HAL_restore_interrupts( saved_psr );
\r
1384 /*------------------------------------------------------------------------------
\r
1385 * I2C_suspend_smbus_slave()
\r
1386 * See "i2c.h" for details of how to use this function.
\r
1388 void I2C_suspend_smbus_slave
\r
1390 i2c_instance_t * this_i2c
\r
1396 * We need to disable interrupts here to ensure we can update the
\r
1397 * hardware register without the SMBUS IRQs interrupting us.
\r
1400 saved_psr=HAL_disable_interrupts();
\r
1402 HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_NO_CONTROL, 0x00u);
\r
1405 HAL_restore_interrupts( saved_psr );
\r
1408 /*------------------------------------------------------------------------------
\r
1409 * I2C_resume_smbus_slave()
\r
1410 * See "i2c.h" for details of how to use this function.
\r
1412 void I2C_resume_smbus_slave
\r
1414 i2c_instance_t * this_i2c
\r
1420 * We need to disable interrupts here to ensure we can update the
\r
1421 * hardware register without the SMBUS IRQs interrupting us.
\r
1424 saved_psr=HAL_disable_interrupts();
\r
1426 HAL_set_8bit_reg_field(this_i2c->base_address, SMBSUS_NO_CONTROL, 0x01u);
\r
1429 HAL_restore_interrupts( saved_psr );
\r
1432 /*------------------------------------------------------------------------------
\r
1433 * I2C_reset_smbus()
\r
1434 * See "i2c.h" for details of how to use this function.
\r
1436 void I2C_reset_smbus
\r
1438 i2c_instance_t * this_i2c
\r
1444 * We need to disable interrupts here to ensure we can update the
\r
1445 * hardware register without the SMBUS IRQs interrupting us.
\r
1448 saved_psr=HAL_disable_interrupts();
\r
1449 HAL_set_8bit_reg_field(this_i2c->base_address, SMBUS_MST_RESET, 0x01u);
\r
1452 HAL_restore_interrupts( saved_psr );
\r
1455 /*------------------------------------------------------------------------------
\r
1456 * I2C_set_smbus_alert()
\r
1457 * See "i2c.h" for details of how to use this function.
\r
1459 void I2C_set_smbus_alert
\r
1461 i2c_instance_t * this_i2c
\r
1467 * We need to disable interrupts here to ensure we can update the
\r
1468 * hardware register without the SMBUS IRQs interrupting us.
\r
1471 saved_psr=HAL_disable_interrupts();
\r
1472 HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_NO_CONTROL, 0x00u);
\r
1475 HAL_restore_interrupts( saved_psr );
\r
1478 /*------------------------------------------------------------------------------
\r
1479 * I2C_clear_smbus_alert()
\r
1480 * See "i2c.h" for details of how to use this function.
\r
1482 void I2C_clear_smbus_alert
\r
1484 i2c_instance_t * this_i2c
\r
1490 * We need to disable interrupts here to ensure we can update the
\r
1491 * hardware register without the SMBUS IRQs interrupting us.
\r
1494 saved_psr=HAL_disable_interrupts();
\r
1496 HAL_set_8bit_reg_field(this_i2c->base_address, SMBALERT_NO_CONTROL, 0x01u);
\r
1499 HAL_restore_interrupts( saved_psr );
\r
1502 /*------------------------------------------------------------------------------
\r
1503 * I2C_get_irq_status()
\r
1504 * See "i2c.h" for details of how to use this function.
\r
1506 uint8_t I2C_get_irq_status
\r
1508 i2c_instance_t * this_i2c
\r
1512 uint8_t irq_type = I2C_NO_IRQ ;
\r
1514 status = HAL_get_8bit_reg(this_i2c->base_address, SMBUS);
\r
1516 if( status & (uint8_t)SMBALERT_NI_STATUS_MASK )
\r
1518 irq_type |= I2C_SMBALERT_IRQ ;
\r
1521 if( status & (uint8_t)SMBSUS_NI_STATUS_MASK )
\r
1523 irq_type |= I2C_SMBSUS_IRQ ;
\r
1526 status = HAL_get_8bit_reg(this_i2c->base_address, CONTROL);
\r
1528 if( status & (uint8_t)SI_MASK )
\r
1530 irq_type |= I2C_INTR_IRQ ;
\r
1535 /*------------------------------------------------------------------------------
\r
1536 * I2C_set_slave_addr2()
\r
1537 * See "i2c.h" for details of how to use this function.
\r
1539 void I2C_set_user_data
\r
1541 i2c_instance_t * this_i2c,
\r
1542 void * p_user_data
\r
1545 this_i2c->p_user_data = p_user_data ;
\r
1548 /*------------------------------------------------------------------------------
\r
1549 * I2C_get_user_data()
\r
1550 * See "i2c.h" for details of how to use this function.
\r
1552 void * I2C_get_user_data
\r
1554 i2c_instance_t * this_i2c
\r
1557 return( this_i2c->p_user_data);
\r
1560 #ifdef __cplusplus
\r