# MIOS32_IIC

## Data Structures
union | transfer_state_t
struct | iic_rec_t
## Defines
#define | I2C_PERIPHERAL_FRQ (MIOS32_SYS_CPU_FREQUENCY/4)
#define | MIOS32_IIC0_SCL_PORT GPIOB
#define | MIOS32_IIC0_SCL_PIN GPIO_Pin_10
#define | MIOS32_IIC0_SDA_PORT GPIOB
#define | MIOS32_IIC0_SDA_PIN GPIO_Pin_11
#define | MIOS32_IIC1_SCL_PORT GPIOB
#define | MIOS32_IIC1_SCL_PIN GPIO_Pin_6
#define | MIOS32_IIC1_SDA_PORT GPIOB
#define | MIOS32_IIC1_SDA_PIN GPIO_Pin_7
#define | MIOS32_IIC0_DUTYCYCLE I2C_DutyCycle_2
#define | MIOS32_IIC1_DUTYCYCLE I2C_DutyCycle_2
#define | MIOS32_IIC0_SCL_PORT GPIOB
#define | MIOS32_IIC0_SCL_PIN GPIO_Pin_10
#define | MIOS32_IIC0_SCL_AF { GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2); }
#define | MIOS32_IIC0_SDA_PORT GPIOB
#define | MIOS32_IIC0_SDA_PIN GPIO_Pin_11
#define | MIOS32_IIC0_SDA_AF { GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2); }
#define | MIOS32_IIC1_SCL_PORT GPIOB
#define | MIOS32_IIC1_SCL_PIN GPIO_Pin_6
#define | MIOS32_IIC1_SCL_AF { GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); }
#define | MIOS32_IIC1_SDA_PORT GPIOB
#define | MIOS32_IIC1_SDA_PIN GPIO_Pin_9
#define | MIOS32_IIC1_SDA_AF { GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1); }
## Functions
s32 | MIOS32_IIC_Init (u32 mode)
s32 | MIOS32_IIC_TransferBegin (u8 iic_port, mios32_iic_semaphore_t semaphore_type)
s32 | MIOS32_IIC_TransferFinished (u8 iic_port)
s32 | MIOS32_IIC_LastErrorGet (u8 iic_port)
s32 | MIOS32_IIC_TransferCheck (u8 iic_port)
s32 | MIOS32_IIC_TransferWait (u8 iic_port)
s32 | MIOS32_IIC_Transfer (u8 iic_port, mios32_iic_transfer_t transfer, u8 address, u8 *buffer, u16 len)
void | I2C0_IRQHandler (void)
void | I2C2_EV_IRQHandler (void)
void | I2C2_ER_IRQHandler (void)
## Variables
volatile u32 | MIOS32_IIC_unexpected_event

## Detailed Description

IIC driver for MIOS32

IIC driver for MIOS32

Interrupt driven approach, inspired by STM32 AN2824, enriched by more generic buffer send/receive routines and a proper error/failsave handling

Some remarks: A common polling method would work unstable on receive transactions if the sending rouine is interrupted, so that NAK + STOP cannot be requested early enough before the last byte should be received See also this enlightening forum thread http://www.st.com/mcu/forums-cat-6701-23.html

DMA transfers are no solution for MIOS32, as it should stay compatible to mid-range devices (-> no DMA2), and the available DMA channels which could be used for I2C2 are already allocated by SPI1 and SPI2

The interrupt has to run with higher priority - it has to be ensured that the received data is read from DR register before the ACK of the previous byte is sent, otherwise the I2C peripheral can get busy permanently, waiting for a NAK which it will never transmit as it will never request a byte in master mode -> lifelock -> design flaw

I must highlight that I don't really like the I2C concept of STM32. It's unbelievable that the guys specified a pipeline based approach, but haven't put the NAK/Stop condition into the transaction pipeline

## Define Documentation

#define I2C_PERIPHERAL_FRQ (MIOS32_SYS_CPU_FREQUENCY/4)

#define MIOS32_IIC0_DUTYCYCLE I2C_DutyCycle_2

#define MIOS32_IIC0_SCL_AF { GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2); }

#define MIOS32_IIC0_SCL_PIN GPIO_Pin_10

#define MIOS32_IIC0_SCL_PORT GPIOB

#define MIOS32_IIC0_SDA_AF { GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2); }

#define MIOS32_IIC0_SDA_PIN GPIO_Pin_11

#define MIOS32_IIC0_SDA_PORT GPIOB

#define MIOS32_IIC1_DUTYCYCLE I2C_DutyCycle_2

#define MIOS32_IIC1_SCL_AF { GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); }

#define MIOS32_IIC1_SCL_PIN GPIO_Pin_6

#define MIOS32_IIC1_SCL_PORT GPIOB

#define MIOS32_IIC1_SDA_AF { GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1); }

#define MIOS32_IIC1_SDA_PIN GPIO_Pin_9

#define MIOS32_IIC1_SDA_PIN GPIO_Pin_7

#define MIOS32_IIC1_SDA_PORT GPIOB

## Function Documentation

void I2C0_IRQHandler | ( | void |  | ) |

void I2C2_ER_IRQHandler | ( | void |  | ) |

void I2C2_EV_IRQHandler | ( | void |  | ) |

s32 MIOS32_IIC_Init | ( | u32 | mode | ) |

Initializes IIC driver

Parameters:

  `[in]` | mode | currently only mode 0 supported

Returns:
  < 0 if initialisation failed

Here is the call graph for this function:

s32 MIOS32_IIC_LastErrorGet | ( | u8 | iic_port | ) |

Returns the last transfer error
Will be updated by MIOS32_IIC_TransferCheck(), so that the error status doesn't get lost (the check function will return 0 when called again)
Will be cleared when a new transfer has been started successfully

Parameters:

  `[in]` | iic_port | the IIC port (0..MIOS32_IIC_NUM-1)

Returns:
  last error status

s32 MIOS32_IIC_Transfer | ( | u8 | iic_port,
|  | mios32_iic_transfer_t | transfer,
|  | u8 | address,
|  | u8 * | buffer,
|  | u16 | len |
| ) |  |  |

Starts a new transfer. If this function is called during an ongoing transfer, we wait until it has been finished and setup the new transfer

Parameters:

  `[in]` | transfer | type: IIC_Read: a common Read transfer IIC_Write: a common Write transfer IIC_Read_AbortIfFirstByteIs0: used to poll MBHP_IIC_MIDI: aborts transfer if the first received byte is 0 IIC_Write_WithoutStop: don't send stop condition after transfer to allow a restart condition (e.g. used to access EEPROMs)
  `[in]` | iic_port | the IIC port (0..MIOS32_IIC_NUM-1)
  `[in]` | address | of IIC device (bit 0 always cleared)
  `[in]` | *buffer | pointer to transmit/receive buffer
  `[in]` | len | number of bytes which should be transmitted/received

Returns:
  0 no error
  < 0 on errors, if MIOS32_IIC_ERROR_PREV_OFFSET is added, the previous transfer got an error (the previous task didn't use MIOS32_IIC_TransferWait to poll the transfer state)

Note:
  Note that the semaphore will be released automatically after an error (MIOS32_IIC_TransferBegin() has to be called again)

Here is the call graph for this function:

s32 MIOS32_IIC_TransferBegin | ( | u8 | iic_port,
|  | mios32_iic_semaphore_t | semaphore_type |
| ) |  |  |

Semaphore handling: requests the IIC interface

Parameters:

  `[in]` | iic_port | the IIC port (0..MIOS32_IIC_NUM-1)
  `[in]` | semaphore_type | is either IIC_Blocking or IIC_Non_Blocking

Returns:
  Non_Blocking: returns -1 to request a retry
  0 if IIC interface free

Here is the call graph for this function:

s32 MIOS32_IIC_TransferCheck | ( | u8 | iic_port | ) |

Checks if transfer is finished

Parameters:

  `[in]` | iic_port | the IIC port (0..MIOS32_IIC_NUM-1)

Returns:
  0 if no ongoing transfer
  1 if ongoing transfer
  < 0 if error during transfer

Note:
  Note that the semaphore will be released automatically after an error (MIOS32_IIC_TransferBegin() has to be called again)

s32 MIOS32_IIC_TransferFinished | ( | u8 | iic_port | ) |

Semaphore handling: releases the IIC interface for other tasks

Parameters:

  `[in]` | iic_port | the IIC port (0..MIOS32_IIC_NUM-1)

Returns:
  < 0 on errors

s32 MIOS32_IIC_TransferWait | ( | u8 | iic_port | ) |

Waits until transfer is finished

Parameters:

  `[in]` | iic_port | the IIC port (0..MIOS32_IIC_NUM-1)

Returns:
  0 if no ongoing transfer
  < 0 if error during transfer

Note:
  Note that the semaphore will be released automatically after an error (MIOS32_IIC_TransferBegin() has to be called again)

Here is the call graph for this function:

## Variable Documentation

volatile u32 MIOS32_IIC_unexpected_event