Merge pull request #3324 from LMESTM/dev_i2c_common_code

Dev i2c common code
pull/3415/head
Martin Kojtal 2016-12-09 15:30:00 +01:00 committed by GitHub
commit 04f940de2d
68 changed files with 4807 additions and 6434 deletions

View File

@ -32,14 +32,22 @@ I2C master(PB_9, PB_8);
I2C master(D14, D15); // I2C_SDA, I2C_SCL
#endif
#if defined (TARGET_NUCLEO_F429ZI) || \
#if defined (TARGET_NUCLEO_F072RB) || \
defined (TARGET_NUCLEO_F030R8) || \
defined (TARGET_NUCLEO_F103RB) || \
defined (TARGET_NUCLEO_F207ZG) || \
defined (TARGET_NUCLEO_F446ZE) || \
defined (TARGET_NUCLEO_F429ZI) || \
defined (TARGET_DISCO_F429ZI) || \
defined (TARGET_NUCLEO_F446ZE)
defined (TARGET_NUCLEO_F767ZI) || \
defined (TARGET_NUCLEO_L053R8) || \
defined (TARGET_NUCLEO_L152RE) || \
defined (TARGET_NUCLEO_L476RG)
I2CSlave slave(PB_11, PB_10);
#elif defined(TARGET_NUCLEO_F303RE)
I2CSlave slave(D2, D8);
#else
I2CSlave slave(D3, D6);
#endif
volatile int why;
@ -95,7 +103,8 @@ int main()
while (!master_complete) {
if(slave.receive() == I2CSlave::ReadAddressed) {
slave.write(buf_slave, SIZE);
if(slave.write(buf_slave, SIZE))
notify_completion(false);
}
}
if (why != I2C_EVENT_TRANSFER_COMPLETE) {

View File

@ -66,10 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -60,10 +60,6 @@ struct analogin_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -60,10 +60,6 @@ struct analogin_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -60,10 +60,6 @@ struct analogin_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
struct can_s {
CANName can;
int index;

View File

@ -60,10 +60,6 @@ struct analogin_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -66,10 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
struct can_s {
CANName can;
int index;

View File

@ -66,10 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
struct can_s {
CANName can;
int index;

View File

@ -82,6 +82,34 @@ struct serial_s {
#endif
};
struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
* be kept as the first members of this struct
* to ensure i2c_get_obj to work as expected
*/
I2CName i2c;
I2C_HandleTypeDef handle;
uint8_t index;
int hz;
PinName sda;
PinName scl;
IRQn_Type event_i2cIRQ;
IRQn_Type error_i2cIRQ;
uint32_t XferOperation;
volatile uint8_t event;
#if DEVICE_I2CSLAVE
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
uint8_t stop;
uint8_t available_events;
#endif
};
#include "gpio_object.h"
#ifdef __cplusplus

View File

@ -2585,7 +2585,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = XferOptions;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferISR = I2C_Master_ISR_IT;
/* If size > MAX_NBYTE_SIZE, use reload mode */
@ -2598,15 +2598,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
{
hi2c->XferSize = hi2c->XferCount;
xfermode = hi2c->XferOptions;
/* If transfer direction not change, do not generate Restart Condition */
/* Mean Previous state is same as current state */
if(hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_TX)
{
xferrequest = I2C_NO_STARTSTOP;
}
}
/* Send Slave Address and set NBYTES to write */
I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, xferrequest);
@ -2659,7 +2651,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = XferOptions;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferISR = I2C_Master_ISR_IT;
/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
@ -2672,13 +2664,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
{
hi2c->XferSize = hi2c->XferCount;
xfermode = hi2c->XferOptions;
/* If transfer direction not change, do not generate Restart Condition */
/* Mean Previous state is same as current state */
if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX)
{
xferrequest = I2C_NO_STARTSTOP;
}
}
/* Send Slave Address and set NBYTES to read */

View File

@ -1,390 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#if DEVICE_I2C
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x1000)
#define LONG_TIMEOUT ((int)0x8000)
I2C_HandleTypeDef I2cHandle;
int i2c1_inited = 0;
#if defined(I2C2_BASE)
int i2c2_inited = 0;
#endif
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C1 clock and pinout if not done
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
__I2C1_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#if defined(I2C2_BASE)
// Enable I2C2 clock and pinout if not done
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__I2C2_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
// Reset to clear pending flags if any
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
}
void i2c_frequency(i2c_t *obj, int hz) {
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
// wait before init
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Common settings: I2C clock = 48 MHz, Analog filter = ON, Digital filter coefficient = 0
switch (hz) {
case 100000:
I2cHandle.Init.Timing = 0x10805E89; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
break;
case 400000:
I2cHandle.Init.Timing = 0x00901850; // Fast mode with Rise Time = 250ns and Fall Time = 100ns
break;
case 1000000:
I2cHandle.Init.Timing = 0x00700818; // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
break;
default:
break;
}
// I2C configuration
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0;
I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
HAL_I2C_Init(&I2cHandle);
}
inline int i2c_start(i2c_t *obj) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Wait the STOP condition has been previously correctly sent
timeout = FLAG_TIMEOUT;
while ((i2c->CR2 & I2C_CR2_STOP) == I2C_CR2_STOP){
if ((timeout--) == 0) {
return 1;
}
}
// Generate the START condition
i2c->CR2 |= I2C_CR2_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
inline int i2c_stop(i2c_t *obj) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
i2c->CR2 |= I2C_CR2_STOP;
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
int value;
// Update CR2 register
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ);
// Read all bytes
for (count = 0; count < length; count++) {
value = i2c_byte_read(obj, 0);
data[count] = (char)value;
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
// Wait until STOPF flag is set
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
// Clear STOP Flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
// Update CR2 register
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE);
for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]);
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop
if (stop) {
i2c_stop(obj);
// Wait until STOPF flag is set
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
// Clear STOP Flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return count;
}
int i2c_byte_read(i2c_t *obj, int last) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->RXDR;
}
int i2c_byte_write(i2c_t *obj, int data) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the previous byte is transmitted
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) {
if ((timeout--) == 0) {
return 0;
}
}
i2c->TXDR = (uint8_t)data;
return 1;
}
void i2c_reset(i2c_t *obj) {
int timeout;
// Wait before reset
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
#if defined(I2C2_BASE)
if (obj->i2c == I2C_2) {
__I2C2_FORCE_RESET();
__I2C2_RELEASE_RESET();
}
#endif
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg = 0;
// disable
i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
// Get the old register value
tmpreg = i2c->OAR1;
// Reset address bits
tmpreg &= 0xFC00;
// Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value
i2c->OAR1 = tmpreg;
// enable
i2c->OAR1 |= I2C_OAR1_OA1EN;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// Get the old register value
tmpreg = i2c->OAR1;
// Enable / disable slave
if (enable_slave == 1) {
tmpreg |= I2C_OAR1_OA1EN;
} else {
tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
}
// Set new mode
i2c->OAR1 = tmpreg;
}
// See I2CSlave.h
#define NoData 0 // the slave has not been addressed
#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj) {
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int retValue = NoData;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_DIR) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length) {
char size = 0;
while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
char size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
do {
i2c_byte_write(obj, data[size]);
size++;
} while (size < length);
return size;
}
#endif // DEVICE_I2CSLAVE
#endif // DEVICE_I2C

View File

@ -0,0 +1,86 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_I2C_DEVICE_H
#define MBED_I2C_DEVICE_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEVICE_I2C
#if defined I2C1_BASE
#define I2C1_EV_IRQn I2C1_IRQn
#define I2C1_ER_IRQn I2C1_IRQn
#endif
#if defined I2C2_BASE
#define I2C2_EV_IRQn I2C2_IRQn
#define I2C2_ER_IRQn I2C2_IRQn
#endif
#if defined I2C3_BASE
#define I2C3_EV_IRQn I2C3_IRQn
#define I2C3_ER_IRQn I2C3_IRQn
#endif
#define I2C_IT_ALL (I2C_IT_ERRI|I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_NACKI|I2C_IT_ADDRI|I2C_IT_RXI|I2C_IT_TXI)
/* Define IP version */
#define I2C_IP_VERSION_V2
/* Family specifc settings for clock source */
#define I2CAPI_I2C1_CLKSRC RCC_I2C1CLKSOURCE_SYSCLK
/* Provide the suitable timing depending on requested frequencie */
inline uint32_t get_i2c_timing(int hz)
{
uint32_t tim = 0;
switch (hz) {
case 100000:
tim = 0x10805E89; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
break;
case 400000:
tim = 0x00901850; // Fast mode with Rise Time = 250ns and Fall Time = 100ns
break;
case 1000000:
tim = 0x00700818; // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
break;
default:
break;
}
return tim;
}
#endif // DEVICE_I2C
#endif

View File

@ -3925,6 +3925,7 @@ static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c)
*/
static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
{
if(hi2c->State == HAL_I2C_STATE_BUSY_RX)
{
uint32_t tmp = 0U;
@ -3938,34 +3939,24 @@ static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
}
else if((tmp == 2U) || (tmp == 3U))
{
if(hi2c->XferOptions != I2C_NEXT_FRAME)
{
/* Disable Acknowledge */
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
/* Enable Pos */
hi2c->Instance->CR1 |= I2C_CR1_POS;
}
else
{
/* Enable Acknowledge */
hi2c->Instance->CR1 |= I2C_CR1_ACK;
}
/* Disable Acknowledge */
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
/* Enable Pos */
hi2c->Instance->CR1 |= I2C_CR1_POS;
/* Disable BUF interrupt */
__HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
}
else
{
if(hi2c->XferOptions != I2C_NEXT_FRAME)
/* Disable Acknowledge */
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
if(hi2c->XferOptions == I2C_NEXT_FRAME)
{
/* Disable Acknowledge */
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
}
else
{
/* Enable Acknowledge */
hi2c->Instance->CR1 |= I2C_CR1_ACK;
/* Enable Pos */
hi2c->Instance->CR1 |= I2C_CR1_POS;
}
/* Disable EVT, BUF and ERR interrupt */
@ -3975,17 +3966,17 @@ static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
(*hi2c->pBuffPtr++) = hi2c->Instance->DR;
hi2c->XferCount--;
tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
hi2c->State = HAL_I2C_STATE_READY;
if(hi2c->Mode == HAL_I2C_MODE_MEM)
{
hi2c->PreviousState = I2C_STATE_NONE;
hi2c->Mode = HAL_I2C_MODE_NONE;
HAL_I2C_MemRxCpltCallback(hi2c);
}
else
{
hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
hi2c->Mode = HAL_I2C_MODE_NONE;
HAL_I2C_MasterRxCpltCallback(hi2c);
}
@ -4003,6 +3994,7 @@ static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c)
{
/* Declaration of temporary variables to prevent undefined behavior of volatile usage */
uint32_t tmp;
uint32_t CurrentXferOptions = hi2c->XferOptions;
if(hi2c->XferCount == 3U)
@ -4022,19 +4014,21 @@ static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c)
/* Prepare next transfer or stop current transfer */
if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME))
{
if(CurrentXferOptions != I2C_NEXT_FRAME)
/* Disable Acknowledge */
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME))
{
/* Disable Acknowledge */
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
}
else
{
/* Enable Acknowledge */
hi2c->Instance->CR1 |= I2C_CR1_ACK;
/* Generate Start */
hi2c->Instance->CR1 |= I2C_CR1_START;
}
tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
}
else
{
hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
/* Generate Stop */
hi2c->Instance->CR1 |= I2C_CR1_STOP;
}
@ -4051,17 +4045,16 @@ static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c)
__HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
hi2c->State = HAL_I2C_STATE_READY;
hi2c->PreviousState = I2C_STATE_NONE;
if(hi2c->Mode == HAL_I2C_MODE_MEM)
{
hi2c->PreviousState = I2C_STATE_NONE;
hi2c->Mode = HAL_I2C_MODE_NONE;
HAL_I2C_MemRxCpltCallback(hi2c);
}
else
{
hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
hi2c->Mode = HAL_I2C_MODE_NONE;
HAL_I2C_MasterRxCpltCallback(hi2c);
@ -4076,6 +4069,7 @@ static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c)
return HAL_OK;
}
/**
* @brief Handle SB flag for Master
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains

View File

@ -1,529 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#if DEVICE_I2C
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x1000)
#define LONG_TIMEOUT ((int)0x8000)
I2C_HandleTypeDef I2cHandle;
int i2c1_inited = 0;
int i2c2_inited = 0;
int i2c3_inited = 0;
int fmpi2c1_inited = 0;
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C1 clock and pinout if not done
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__I2C1_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
// Enable I2C2 clock and pinout if not done
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__I2C2_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#if defined I2C3_BASE
// Enable I2C3 clock and pinout if not done
if ((obj->i2c == I2C_3) && !i2c3_inited) {
i2c3_inited = 1;
__I2C3_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
#if defined FMPI2C1_BASE
// Enable I2C3 clock and pinout if not done
if ((obj->i2c == FMPI2C_1) && !fmpi2c1_inited) {
fmpi2c1_inited = 1;
__HAL_RCC_FMPI2C1_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
// Reset to clear pending flags if any
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
// I2C master by default
obj->slave = 0;
}
void i2c_frequency(i2c_t *obj, int hz)
{
MBED_ASSERT((hz > 0) && (hz <= 400000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
// wait before init
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// I2C configuration
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.ClockSpeed = hz;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0;
HAL_I2C_Init(&I2cHandle);
if (obj->slave) {
/* Enable Address Acknowledge */
I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
}
}
inline int i2c_start(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Wait the STOP condition has been previously correctly sent
// This timeout can be avoid in some specific cases by simply clearing the STOP bit
timeout = FLAG_TIMEOUT;
while ((i2c->CR1 & I2C_CR1_STOP) == I2C_CR1_STOP) {
if ((timeout--) == 0) {
return 1;
}
}
// Generate the START condition
i2c->CR1 |= I2C_CR1_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
inline int i2c_stop(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
i2c->CR1 |= I2C_CR1_STOP;
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
int value;
i2c_start(obj);
// Wait until SB flag is set
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
i2c->DR = __HAL_I2C_7BIT_ADD_READ(address);
// Wait address is acknowledged
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
// Read all bytes except last one
for (count = 0; count < (length - 1); count++) {
value = i2c_byte_read(obj, 0);
data[count] = (char)value;
}
// If not repeated start, send stop.
// Warning: must be done BEFORE the data is read.
if (stop) {
i2c_stop(obj);
}
// Read the last byte
value = i2c_byte_read(obj, 1);
data[count] = (char)value;
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
i2c_start(obj);
// Wait until SB flag is set
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
i2c->DR = __HAL_I2C_7BIT_ADD_WRITE(address);
// Wait address is acknowledged
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
for (count = 0; count < length; count++) {
if (i2c_byte_write(obj, data[count]) != 1) {
i2c_stop(obj);
return -1;
}
}
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
}
return count;
}
int i2c_byte_read(i2c_t *obj, int last)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
if (last) {
// Don't acknowledge the last byte
i2c->CR1 &= ~I2C_CR1_ACK;
} else {
// Acknowledge the byte
i2c->CR1 |= I2C_CR1_ACK;
}
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->DR;
}
int i2c_byte_write(i2c_t *obj, int data)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
i2c->DR = (uint8_t)data;
// Wait until the byte is transmitted
timeout = FLAG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) &&
(__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == RESET)) {
if ((timeout--) == 0) {
return 0;
}
}
return 1;
}
void i2c_reset(i2c_t *obj)
{
int timeout;
// wait before reset
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
if (obj->i2c == I2C_2) {
__I2C2_FORCE_RESET();
__I2C2_RELEASE_RESET();
}
#if defined I2C3_BASE
if (obj->i2c == I2C_3) {
__I2C3_FORCE_RESET();
__I2C3_RELEASE_RESET();
}
#endif
#if defined FMPI2C1_BASE
if (obj->i2c == FMPI2C_1) {
__HAL_RCC_FMPI2C1_FORCE_RESET();
__HAL_RCC_FMPI2C1_RELEASE_RESET();
}
#endif
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg = 0;
// Get the old register value
tmpreg = i2c->OAR1;
// Reset address bits
tmpreg &= 0xFC00;
// Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value
i2c->OAR1 = tmpreg;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
if (enable_slave) {
obj->slave = 1;
/* Enable Address Acknowledge */
I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
}
}
// See I2CSlave.h
#define NoData 0 // the slave has not been addressed
#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj)
{
int retValue = NoData;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TRA) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
uint32_t Timeout;
int size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
while (length > 0) {
/* Wait until RXNE flag is set */
// Wait until the byte is received
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
/* Read data from DR */
(*data++) = I2cHandle.Instance->DR;
length--;
size++;
if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
/* Read data from DR */
(*data++) = I2cHandle.Instance->DR;
length--;
size++;
}
}
/* Wait until STOP flag is set */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
/* Clear STOP flag */
__HAL_I2C_CLEAR_STOPFLAG(&I2cHandle);
/* Wait until BUSY flag is reset */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
uint32_t Timeout;
int size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
while (length > 0) {
/* Wait until TXE flag is set */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
/* Write data to DR */
I2cHandle.Instance->DR = (*data++);
length--;
size++;
if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
/* Write data to DR */
I2cHandle.Instance->DR = (*data++);
length--;
size++;
}
}
/* Wait until AF flag is set */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_AF) == RESET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
/* Clear AF flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
/* Wait until BUSY flag is reset */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
I2cHandle.State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(&I2cHandle);
return size;
}
#endif // DEVICE_I2CSLAVE
#endif // DEVICE_I2C

View File

@ -0,0 +1,47 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_I2C_DEVICE_H
#define MBED_I2C_DEVICE_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEVICE_I2C
#define I2C_IP_VERSION_V1
#define I2C_IT_ALL (I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR)
#endif // DEVICE_I2C
#endif

View File

@ -99,8 +99,30 @@ struct spi_s {
};
struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
* be kept as the first members of this struct
*/
I2CName i2c;
uint32_t slave;
I2C_HandleTypeDef handle;
uint8_t index;
int hz;
PinName sda;
PinName scl;
IRQn_Type event_i2cIRQ;
IRQn_Type error_i2cIRQ;
uint8_t XferOperation;
volatile uint8_t event;
#if DEVICE_I2CSLAVE
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
uint8_t stop;
uint8_t available_events;
#endif
};
struct pwmout_s {

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -82,6 +82,34 @@ struct serial_s {
#endif
};
struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
* be kept as the first members of this struct
* to ensure i2c_get_obj to work as expected
*/
I2CName i2c;
I2C_HandleTypeDef handle;
uint8_t index;
int hz;
PinName sda;
PinName scl;
IRQn_Type event_i2cIRQ;
IRQn_Type error_i2cIRQ;
uint32_t XferOperation;
volatile uint8_t event;
#if DEVICE_I2CSLAVE
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
uint8_t stop;
uint8_t available_events;
#endif
};
#include "gpio_object.h"
#ifdef __cplusplus

View File

@ -2583,7 +2583,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = XferOptions;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferISR = I2C_Master_ISR_IT;
/* If size > MAX_NBYTE_SIZE, use reload mode */
@ -2596,13 +2596,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
{
hi2c->XferSize = hi2c->XferCount;
xfermode = hi2c->XferOptions;
/* If transfer direction not change, do not generate Restart Condition */
/* Mean Previous state is same as current state */
if(hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_TX)
{
xferrequest = I2C_NO_STARTSTOP;
}
}
@ -2657,7 +2650,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = XferOptions;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferISR = I2C_Master_ISR_IT;
/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
@ -2670,13 +2663,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
{
hi2c->XferSize = hi2c->XferCount;
xfermode = hi2c->XferOptions;
/* If transfer direction not change, do not generate Restart Condition */
/* Mean Previous state is same as current state */
if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX)
{
xferrequest = I2C_NO_STARTSTOP;
}
}
/* Send Slave Address and set NBYTES to read */

View File

@ -1,455 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#if DEVICE_I2C
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x4000)
#define LONG_TIMEOUT ((int)0x8000)
I2C_HandleTypeDef I2cHandle;
int i2c1_inited = 0;
int i2c2_inited = 0;
int i2c3_inited = 0;
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C clock and pinout if not done
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
__I2C1_CLK_ENABLE();
// Configure I2C1 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#if defined(I2C2_BASE)
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__I2C2_CLK_ENABLE();
// Configure I2C2 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
#if defined(I2C3_BASE)
if ((obj->i2c == I2C_3) && !i2c3_inited) {
i2c3_inited = 1;
__I2C3_CLK_ENABLE();
// Configure I2C3 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
// Reset to clear pending flags if any
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
}
void i2c_frequency(i2c_t *obj, int hz)
{
uint32_t tim = 0;
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
// wait before init
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
/*
Values calculated with I2C_Timing_Configuration_V1.0.1.xls file (see AN4235)
* Standard mode (up to 100 kHz)
* Fast Mode (up to 400 kHz)
* Fast Mode Plus (up to 1 MHz)
Below values obtained with:
- I2C clock source = 64 MHz (System Clock w/ HSI) or 72 (System Clock w/ HSE)
- Analog filter delay = ON
- Digital filter coefficient = 0
*/
if (SystemCoreClock == 64000000) {
switch (hz) {
case 100000:
tim = 0x10B17DB4; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00E22163; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x00A00D1E; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
break;
}
} else if (SystemCoreClock == 72000000) {
switch (hz) {
case 100000:
tim = 0x10D28DCB; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00F32571; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x00C00D24; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
break;
}
}
// Enable the Fast Mode Plus capability
if (hz == 1000000) {
if (obj->i2c == I2C_1) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C1);
}
#if defined(I2C2_BASE)
if (obj->i2c == I2C_2) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C2);
}
#endif
#if defined(I2C3_BASE)
if (obj->i2c == I2C_3) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C3);
}
#endif
}
// I2C configuration
I2cHandle.Init.Timing = tim;
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0;
I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
HAL_I2C_Init(&I2cHandle);
}
inline int i2c_start(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Wait the STOP condition has been previously correctly sent
timeout = FLAG_TIMEOUT;
while ((i2c->CR2 & I2C_CR2_STOP) == I2C_CR2_STOP){
if ((timeout--) == 0) {
return 1;
}
}
// Generate the START condition
i2c->CR2 |= I2C_CR2_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
inline int i2c_stop(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
i2c->CR2 |= I2C_CR2_STOP;
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
int value;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ);
// Read all bytes
for (count = 0; count < length; count++) {
value = i2c_byte_read(obj, 0);
data[count] = (char)value;
}
// Wait transfer complete
timeout = LONG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE);
for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]);
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return count;
}
int i2c_byte_read(i2c_t *obj, int last)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->RXDR;
}
int i2c_byte_write(i2c_t *obj, int data)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the previous byte is transmitted
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) {
if ((timeout--) == 0) {
return 0;
}
}
i2c->TXDR = (uint8_t)data;
return 1;
}
void i2c_reset(i2c_t *obj)
{
int timeout;
// wait before reset
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// disable
i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
// Get the old register value
tmpreg = i2c->OAR1;
// Reset address bits
tmpreg &= 0xFC00;
// Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value
i2c->OAR1 = tmpreg;
// enable
i2c->OAR1 |= I2C_OAR1_OA1EN;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// Get the old register value
tmpreg = i2c->OAR1;
// Enable / disable slave
if (enable_slave == 1) {
tmpreg |= I2C_OAR1_OA1EN;
} else {
tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
}
// Set new mode
i2c->OAR1 = tmpreg;
}
// See I2CSlave.h
#define NoData 0 // the slave has not been addressed
#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj)
{
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int retValue = NoData;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_DIR) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
char size = 0;
while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
char size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
do {
i2c_byte_write(obj, data[size]);
size++;
} while (size < length);
return size;
}
#endif // DEVICE_I2CSLAVE
#endif // DEVICE_I2C

View File

@ -0,0 +1,102 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_I2C_DEVICE_H
#define MBED_I2C_DEVICE_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEVICE_I2C
#define I2C_IP_VERSION_V2
#define I2C_IT_ALL (I2C_IT_ERRI|I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_NACKI|I2C_IT_ADDRI|I2C_IT_RXI|I2C_IT_TXI)
/* Family specifc settings for clock source */
#define I2CAPI_I2C1_CLKSRC RCC_I2C1CLKSOURCE_SYSCLK
#define I2CAPI_I2C2_CLKSRC RCC_I2C2CLKSOURCE_SYSCLK
#define I2CAPI_I2C3_CLKSRC RCC_I2C3CLKSOURCE_SYSCLK
/* Provide the suitable timing depending on requested frequencie */
inline uint32_t get_i2c_timing(int hz)
{
uint32_t tim = 0;
/*
Values calculated with I2C_Timing_Configuration_V1.0.1.xls file (see AN4235)
* Standard mode (up to 100 kHz)
* Fast Mode (up to 400 kHz)
* Fast Mode Plus (up to 1 MHz)
Below values obtained with:
- I2C clock source = 64 MHz (System Clock w/ HSI) or 72 (System Clock w/ HSE)
- Analog filter delay = ON
- Digital filter coefficient = 0
*/
if (SystemCoreClock == 64000000) {
switch (hz) {
case 100000:
tim = 0x10B17DB4; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00E22163; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x00A00D1E; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
break;
}
} else if (SystemCoreClock == 72000000) {
switch (hz) {
case 100000:
tim = 0x10D28DCB; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00F32571; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x00C00D24; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
break;
}
}
return tim;
}
#ifdef __cplusplus
}
#endif
#endif // DEVICE_I2C
#endif

View File

@ -91,6 +91,7 @@ struct i2c_s {
I2CName i2c;
I2C_HandleTypeDef handle;
uint8_t index;
int hz;
PinName sda;
PinName scl;
IRQn_Type event_i2cIRQ;

View File

@ -0,0 +1,48 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_I2C_DEVICE_H
#define MBED_I2C_DEVICE_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEVICE_I2C
/* Define IP version */
#define I2C_IP_VERSION_V1
#define I2C_IT_ALL (I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR)
#endif // DEVICE_I2C
#endif

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -82,6 +82,34 @@ struct serial_s {
#endif
};
struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
* be kept as the first members of this struct
* to ensure i2c_get_obj to work as expected
*/
I2CName i2c;
I2C_HandleTypeDef handle;
uint8_t index;
int hz;
PinName sda;
PinName scl;
IRQn_Type event_i2cIRQ;
IRQn_Type error_i2cIRQ;
uint32_t XferOperation;
volatile uint8_t event;
#if DEVICE_I2CSLAVE
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
uint8_t stop;
uint8_t available_events;
#endif
};
#include "gpio_object.h"
#ifdef __cplusplus

View File

@ -2536,7 +2536,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = XferOptions;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferISR = I2C_Master_ISR_IT;
/* If size > MAX_NBYTE_SIZE, use reload mode */
@ -2549,13 +2549,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
{
hi2c->XferSize = hi2c->XferCount;
xfermode = hi2c->XferOptions;
/* If transfer direction not change, do not generate Restart Condition */
/* Mean Previous state is same as current state */
if(hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_TX)
{
xferrequest = I2C_NO_STARTSTOP;
}
}
/* Send Slave Address and set NBYTES to write */
@ -2608,7 +2601,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = XferOptions;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferISR = I2C_Master_ISR_IT;
/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
@ -2621,13 +2614,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
{
hi2c->XferSize = hi2c->XferCount;
xfermode = hi2c->XferOptions;
/* If transfer direction not change, do not generate Restart Condition */
/* Mean Previous state is same as current state */
if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX)
{
xferrequest = I2C_NO_STARTSTOP;
}
}
/* Send Slave Address and set NBYTES to read */

View File

@ -1,443 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#if DEVICE_I2C
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#include "mbed_error.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x4000)
#define LONG_TIMEOUT ((int)0x8000)
I2C_HandleTypeDef I2cHandle;
int i2c1_inited = 0;
int i2c2_inited = 0;
int i2c3_inited = 0;
int i2c4_inited = 0;
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C clock and pinout if not done
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_PCLK1);
__HAL_RCC_I2C1_CLK_ENABLE();
// Configure I2C1 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#if defined(I2C2_BASE)
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__HAL_RCC_I2C2_CONFIG(RCC_I2C2CLKSOURCE_PCLK1);
__HAL_RCC_I2C2_CLK_ENABLE();
// Configure I2C2 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
#if defined(I2C3_BASE)
if ((obj->i2c == I2C_3) && !i2c3_inited) {
i2c3_inited = 1;
__HAL_RCC_I2C3_CONFIG(RCC_I2C3CLKSOURCE_PCLK1);
__HAL_RCC_I2C3_CLK_ENABLE();
// Configure I2C3 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
#if defined(I2C4_BASE)
if ((obj->i2c == I2C_4) && !i2c4_inited) {
i2c4_inited = 1;
__HAL_RCC_I2C4_CONFIG(RCC_I2C4CLKSOURCE_PCLK1);
__HAL_RCC_I2C4_CLK_ENABLE();
// Configure I2C4 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
// Reset to clear pending flags if any
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
}
void i2c_frequency(i2c_t *obj, int hz)
{
uint32_t tim = 0;
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
// wait before init
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0)) {}
/*
Values calculated with I2C_Timing_Configuration tool (excel file)
* Standard mode (up to 100 kHz)
* Fast Mode (up to 400 kHz)
* Fast Mode Plus (up to 1 MHz)
Below values obtained with:
- I2Cx clock source = APB1CLK = 54 MHz
- Analog filter delay = ON
- Digital filter coefficient = 0
*/
switch (hz) {
case 100000:
tim = 0x10916998; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00B11B54; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x0090091B; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
break;
}
// I2C configuration
I2cHandle.Init.Timing = tim;
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0;
I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
if (HAL_I2C_Init(&I2cHandle) != HAL_OK) {
error("Cannot initialize I2C");
}
}
inline int i2c_start(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Wait the STOP condition has been previously correctly sent
timeout = FLAG_TIMEOUT;
while ((i2c->CR2 & I2C_CR2_STOP) == I2C_CR2_STOP){
if ((timeout--) == 0) {
return 1;
}
}
// Generate the START condition
i2c->CR2 |= I2C_CR2_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
inline int i2c_stop(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
i2c->CR2 |= I2C_CR2_STOP;
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
int value;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ);
// Read all bytes
for (count = 0; count < length; count++) {
value = i2c_byte_read(obj, 0);
data[count] = (char)value;
}
// Wait transfer complete
timeout = LONG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE);
for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]);
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return count;
}
int i2c_byte_read(i2c_t *obj, int last)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->RXDR;
}
int i2c_byte_write(i2c_t *obj, int data)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the previous byte is transmitted
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) {
if ((timeout--) == 0) {
return 0;
}
}
i2c->TXDR = (uint8_t)data;
return 1;
}
void i2c_reset(i2c_t *obj)
{
int timeout;
// wait before reset
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// disable
i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
// Get the old register value
tmpreg = i2c->OAR1;
// Reset address bits
tmpreg &= 0xFC00;
// Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value
i2c->OAR1 = tmpreg;
// enable
i2c->OAR1 |= I2C_OAR1_OA1EN;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// Get the old register value
tmpreg = i2c->OAR1;
// Enable / disable slave
if (enable_slave == 1) {
tmpreg |= I2C_OAR1_OA1EN;
} else {
tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
}
// Set new mode
i2c->OAR1 = tmpreg;
}
// See I2CSlave.h
#define NoData 0 // the slave has not been addressed
#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj)
{
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int retValue = NoData;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_DIR) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
char size = 0;
while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
char size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
do {
i2c_byte_write(obj, data[size]);
size++;
} while (size < length);
return size;
}
#endif // DEVICE_I2CSLAVE
#endif // DEVICE_I2C

View File

@ -0,0 +1,87 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_I2C_DEVICE_H
#define MBED_I2C_DEVICE_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEVICE_I2C
#define I2C_IP_VERSION_V2
#define I2C_IT_ALL (I2C_IT_ERRI|I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_NACKI|I2C_IT_ADDRI|I2C_IT_RXI|I2C_IT_TXI)
/* Family specifc settings for clock source */
#define I2CAPI_I2C1_CLKSRC RCC_I2C1CLKSOURCE_PCLK1
#define I2CAPI_I2C2_CLKSRC RCC_I2C2CLKSOURCE_PCLK1
#define I2CAPI_I2C3_CLKSRC RCC_I2C3CLKSOURCE_PCLK1
#define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_PCLK1
/* Provide the suitable timing depending on requested frequencie */
inline uint32_t get_i2c_timing(int hz)
{
uint32_t tim = 0;
/*
Values calculated with I2C_Timing_Configuration tool (excel file)
* Standard mode (up to 100 kHz)
* Fast Mode (up to 400 kHz)
* Fast Mode Plus (up to 1 MHz)
Below values obtained with:
- I2Cx clock source = APB1CLK = 54 MHz
- Analog filter delay = ON
- Digital filter coefficient = 0
*/
switch (hz) {
case 100000:
tim = 0x10916998; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00B11B54; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x0090091B; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
break;
}
return tim;
}
#ifdef __cplusplus
}
#endif
#endif // DEVICE_I2C
#endif

View File

@ -66,10 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
struct trng_s {
RNG_HandleTypeDef handle;
};

View File

@ -60,10 +60,6 @@ struct analogin_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -60,10 +60,6 @@ struct analogin_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -66,10 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -66,10 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
};
struct trng_s {
RNG_HandleTypeDef handle;
};

View File

@ -82,6 +82,34 @@ struct serial_s {
#endif
};
struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
* be kept as the first members of this struct
* to ensure i2c_get_obj to work as expected
*/
I2CName i2c;
I2C_HandleTypeDef handle;
uint8_t index;
int hz;
PinName sda;
PinName scl;
IRQn_Type event_i2cIRQ;
IRQn_Type error_i2cIRQ;
uint32_t XferOperation;
volatile uint8_t event;
#if DEVICE_I2CSLAVE
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
uint8_t stop;
uint8_t available_events;
#endif
};
#include "gpio_object.h"
#ifdef __cplusplus

View File

@ -2,8 +2,8 @@
******************************************************************************
* @file stm32l0xx_hal_dma.c
* @author MCD Application Team
* @version V1.7.0
* @date 31-May-2016
* @version $VERSION$
* @date $DATE$
* @brief DMA HAL module driver.
*
* This file provides firmware functions to manage the following
@ -480,6 +480,49 @@ HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
return HAL_OK;
}
/**
* @brief Aborts the DMA Transfer in Interrupt mode.
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Stream.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
{
HAL_StatusTypeDef status = HAL_OK;
if(HAL_DMA_STATE_BUSY != hdma->State)
{
/* no transfer ongoing */
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
status = HAL_ERROR;
}
else
{
/* Disable DMA IT */
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
/* Disable the channel */
__HAL_DMA_DISABLE(hdma);
/* Clear all flags */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma));
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
/* Call User Abort callback */
if(hdma->XferAbortCallback != NULL)
{
hdma->XferAbortCallback(hdma);
}
}
return status;
}
/**
* @brief Polling for transfer complete.
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains

View File

@ -2,8 +2,8 @@
******************************************************************************
* @file stm32l0xx_hal_dma.h
* @author MCD Application Team
* @version V1.7.0
* @date 31-May-2016
* @version $VERSION$
* @date $DATE$
* @brief Header file of DMA HAL module.
******************************************************************************
* @attention
@ -139,19 +139,21 @@ typedef struct __DMA_HandleTypeDef
DMA_InitTypeDef Init; /*!< DMA communication parameters */
HAL_LockTypeDef Lock; /*!< DMA locking object */
HAL_LockTypeDef Lock; /*!< DMA locking object */
__IO HAL_DMA_StateTypeDef State; /*!< DMA transfer state */
void *Parent; /*!< Parent object state */
void *Parent; /*!< Parent object state */
void (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer complete callback */
void (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback */
void (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer error callback */
__IO uint32_t ErrorCode; /*!< DMA Error code */
void (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer abort callback */
__IO uint32_t ErrorCode; /*!< DMA Error code */
} DMA_HandleTypeDef;
@ -170,6 +172,7 @@ typedef struct __DMA_HandleTypeDef
*/
#define HAL_DMA_ERROR_NONE ((uint32_t)0x00000000U) /*!< No error */
#define HAL_DMA_ERROR_TE ((uint32_t)0x00000001U) /*!< Transfer error */
#define HAL_DMA_ERROR_NO_XFER ((uint32_t)0x00000004U) /*!< no ongoing transfer */
#define HAL_DMA_ERROR_TIMEOUT ((uint32_t)0x00000020U) /*!< Timeout error */
#if defined (STM32L011xx) || defined (STM32L021xx)
@ -643,6 +646,7 @@ HAL_StatusTypeDef HAL_DMA_DeInit (DMA_HandleTypeDef *hdma);
HAL_StatusTypeDef HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma);
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma);
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout);
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma);
/**

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,8 @@
******************************************************************************
* @file stm32l0xx_hal_i2c.h
* @author MCD Application Team
* @version V1.7.0
* @date 31-May-2016
* @version $VERSION$
* @date $DATE$
* @brief Header file of I2C HAL module.
******************************************************************************
* @attention
@ -33,7 +33,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32L0xx_HAL_I2C_H
@ -50,11 +50,11 @@
* @{
*/
/** @defgroup I2C I2C
/** @addtogroup I2C
* @{
*/
/* Exported types ------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup I2C_Exported_Types I2C Exported Types
* @{
*/
@ -73,22 +73,22 @@ typedef struct
This parameter can be a 7-bit or 10-bit address. */
uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected.
This parameter can be a value of @ref I2C_addressing_mode */
This parameter can be a value of @ref I2C_ADDRESSING_MODE */
uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected.
This parameter can be a value of @ref I2C_dual_addressing_mode */
This parameter can be a value of @ref I2C_DUAL_ADDRESSING_MODE */
uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected
This parameter can be a 7-bit address. */
uint32_t OwnAddress2Masks; /*!< Specifies the acknoledge mask address second device own address if dual addressing mode is selected
This parameter can be a value of @ref I2C_own_address2_masks */
uint32_t OwnAddress2Masks; /*!< Specifies the acknowledge mask address second device own address if dual addressing mode is selected
This parameter can be a value of @ref I2C_OWN_ADDRESS2_MASKS */
uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected.
This parameter can be a value of @ref I2C_general_call_addressing_mode */
This parameter can be a value of @ref I2C_GENERAL_CALL_ADDRESSING_MODE */
uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected.
This parameter can be a value of @ref I2C_nostretch_mode */
This parameter can be a value of @ref I2C_NOSTRETCH_MODE */
}I2C_InitTypeDef;
@ -97,71 +97,137 @@ typedef struct
*/
/** @defgroup HAL_state_structure_definition HAL state structure definition
* @brief HAL State structure definition
* @brief HAL State structure definition
* @note HAL I2C State value coding follow below described bitmap :\n
* b7-b6 Error information\n
* 00 : No Error\n
* 01 : Abort (Abort user request on going)\n
* 10 : Timeout\n
* 11 : Error\n
* b5 IP initilisation status\n
* 0 : Reset (IP not initialized)\n
* 1 : Init done (IP initialized and ready to use. HAL I2C Init function called)\n
* b4 (not used)\n
* x : Should be set to 0\n
* b3\n
* 0 : Ready or Busy (No Listen mode ongoing)\n
* 1 : Listen (IP in Address Listen Mode)\n
* b2 Intrinsic process state\n
* 0 : Ready\n
* 1 : Busy (IP busy with some configuration or internal operations)\n
* b1 Rx state\n
* 0 : Ready (no Rx operation ongoing)\n
* 1 : Busy (Rx operation ongoing)\n
* b0 Tx state\n
* 0 : Ready (no Tx operation ongoing)\n
* 1 : Busy (Tx operation ongoing)
* @{
*/
typedef enum
{
HAL_I2C_STATE_RESET = 0x00U, /*!< I2C not yet initialized or disabled */
HAL_I2C_STATE_READY = 0x01U, /*!< I2C initialized and ready for use */
HAL_I2C_STATE_BUSY = 0x02U, /*!< I2C internal process is ongoing */
HAL_I2C_STATE_MASTER_BUSY_TX = 0x12U, /*!< Master Data Transmission process is ongoing */
HAL_I2C_STATE_MASTER_BUSY_RX = 0x22U, /*!< Master Data Reception process is ongoing */
HAL_I2C_STATE_SLAVE_BUSY_TX = 0x32U, /*!< Slave Data Transmission process is ongoing */
HAL_I2C_STATE_SLAVE_BUSY_RX = 0x42U, /*!< Slave Data Reception process is ongoing */
HAL_I2C_STATE_MEM_BUSY_TX = 0x52U, /*!< Memory Data Transmission process is ongoing */
HAL_I2C_STATE_MEM_BUSY_RX = 0x62U, /*!< Memory Data Reception process is ongoing */
HAL_I2C_STATE_TIMEOUT = 0x03U, /*!< Timeout state */
HAL_I2C_STATE_ERROR = 0x04U /*!< Reception process is ongoing */
HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */
HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */
HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */
HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */
HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */
HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission
process is ongoing */
HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception
process is ongoing */
HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */
HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */
HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */
}HAL_I2C_StateTypeDef;
/**
/**
* @}
*/
/** @defgroup I2C_Error_Code I2C Error Code
* @brief I2C Error Code
* @{
*/
#define HAL_I2C_ERROR_NONE 0x00U /*!< No error */
#define HAL_I2C_ERROR_BERR 0x01U /*!< BERR error */
#define HAL_I2C_ERROR_ARLO 0x02U /*!< ARLO error */
#define HAL_I2C_ERROR_AF 0x04U /*!< ACKF error */
#define HAL_I2C_ERROR_OVR 0x08U /*!< OVR error */
#define HAL_I2C_ERROR_DMA 0x10U /*!< DMA transfer error */
#define HAL_I2C_ERROR_TIMEOUT 0x20U /*!< Timeout error */
#define HAL_I2C_ERROR_SIZE 0x40U /*!< Size Management error */
/**
* @}
*/
/** @defgroup I2C_handle_Structure_definition I2C handle Structure definition
* @brief I2C handle Structure definition
/** @defgroup HAL_mode_structure_definition HAL mode structure definition
* @brief HAL Mode structure definition
* @note HAL I2C Mode value coding follow below described bitmap :\n
* b7 (not used)\n
* x : Should be set to 0\n
* b6\n
* 0 : None\n
* 1 : Memory (HAL I2C communication is in Memory Mode)\n
* b5\n
* 0 : None\n
* 1 : Slave (HAL I2C communication is in Slave Mode)\n
* b4\n
* 0 : None\n
* 1 : Master (HAL I2C communication is in Master Mode)\n
* b3-b2-b1-b0 (not used)\n
* xxxx : Should be set to 0000
* @{
*/
typedef struct
typedef enum
{
I2C_TypeDef *Instance; /*!< I2C registers base address */
I2C_InitTypeDef Init; /*!< I2C communication parameters */
uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */
uint16_t XferSize; /*!< I2C transfer size */
__IO uint16_t XferCount; /*!< I2C transfer counter */
DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */
DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */
HAL_LockTypeDef Lock; /*!< I2C locking object */
__IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */
HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */
HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */
HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */
HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */
__IO uint32_t ErrorCode; /*!< I2C Error code, see I2C_Error_Code */
}HAL_I2C_ModeTypeDef;
/**
* @}
*/
/** @defgroup I2C_Error_Code_definition I2C Error Code definition
* @brief I2C Error Code definition
* @{
*/
#define HAL_I2C_ERROR_NONE (0x00000000U) /*!< No error */
#define HAL_I2C_ERROR_BERR (0x00000001U) /*!< BERR error */
#define HAL_I2C_ERROR_ARLO (0x00000002U) /*!< ARLO error */
#define HAL_I2C_ERROR_AF (0x00000004U) /*!< ACKF error */
#define HAL_I2C_ERROR_OVR (0x00000008U) /*!< OVR error */
#define HAL_I2C_ERROR_DMA (0x00000010U) /*!< DMA transfer error */
#define HAL_I2C_ERROR_TIMEOUT (0x00000020U) /*!< Timeout error */
#define HAL_I2C_ERROR_SIZE (0x00000040U) /*!< Size Management error */
/**
* @}
*/
/** @defgroup I2C_handle_Structure_definition I2C handle Structure definition
* @brief I2C handle Structure definition
* @{
*/
typedef struct __I2C_HandleTypeDef
{
I2C_TypeDef *Instance; /*!< I2C registers base address */
I2C_InitTypeDef Init; /*!< I2C communication parameters */
uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */
uint16_t XferSize; /*!< I2C transfer size */
__IO uint16_t XferCount; /*!< I2C transfer counter */
__IO uint32_t XferOptions; /*!< I2C sequantial transfer options, this parameter can
be a value of @ref I2C_XFEROPTIONS */
__IO uint32_t PreviousState; /*!< I2C communication Previous state */
HAL_StatusTypeDef (*XferISR)(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources); /*!< I2C transfer IRQ handler function pointer */
DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */
DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */
HAL_LockTypeDef Lock; /*!< I2C locking object */
__IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */
__IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */
__IO uint32_t ErrorCode; /*!< I2C Error code */
__IO uint32_t AddrEventCount; /*!< I2C Address Event counter */
}I2C_HandleTypeDef;
/**
* @}
@ -169,32 +235,44 @@ typedef struct
/**
* @}
*/
*/
/* Exported constants --------------------------------------------------------*/
/** @defgroup I2C_Exported_Constants I2C Exported Constants
* @{
*/
/** @defgroup I2C_addressing_mode I2C addressing mode
/** @defgroup I2C_XFEROPTIONS I2C Sequential Transfer Options
* @{
*/
#define I2C_ADDRESSINGMODE_7BIT ((uint32_t)0x00000001U)
#define I2C_ADDRESSINGMODE_10BIT ((uint32_t)0x00000002U)
#define I2C_FIRST_FRAME ((uint32_t)I2C_SOFTEND_MODE)
#define I2C_FIRST_AND_NEXT_FRAME ((uint32_t)(I2C_RELOAD_MODE | I2C_SOFTEND_MODE))
#define I2C_NEXT_FRAME ((uint32_t)(I2C_RELOAD_MODE | I2C_SOFTEND_MODE))
#define I2C_FIRST_AND_LAST_FRAME ((uint32_t)I2C_AUTOEND_MODE)
#define I2C_LAST_FRAME ((uint32_t)I2C_AUTOEND_MODE)
/**
* @}
*/
/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode
/** @defgroup I2C_ADDRESSING_MODE I2C Addressing Mode
* @{
*/
#define I2C_DUALADDRESS_DISABLE ((uint32_t)0x00000000U)
#define I2C_DUALADDRESS_ENABLE I2C_OAR2_OA2EN
#define I2C_ADDRESSINGMODE_7BIT (0x00000001U)
#define I2C_ADDRESSINGMODE_10BIT (0x00000002U)
/**
* @}
*/
/** @defgroup I2C_own_address2_masks I2C own address2 masks
/** @defgroup I2C_DUAL_ADDRESSING_MODE I2C Dual Addressing Mode
* @{
*/
#define I2C_DUALADDRESS_DISABLE (0x00000000U)
#define I2C_DUALADDRESS_ENABLE I2C_OAR2_OA2EN
/**
* @}
*/
/** @defgroup I2C_OWN_ADDRESS2_MASKS I2C Own Address2 Masks
* @{
*/
#define I2C_OA2_NOMASK ((uint8_t)0x00U)
@ -209,50 +287,59 @@ typedef struct
* @}
*/
/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode
/** @defgroup I2C_GENERAL_CALL_ADDRESSING_MODE I2C General Call Addressing Mode
* @{
*/
#define I2C_GENERALCALL_DISABLE ((uint32_t)0x00000000U)
#define I2C_GENERALCALL_ENABLE I2C_CR1_GCEN
#define I2C_GENERALCALL_DISABLE (0x00000000U)
#define I2C_GENERALCALL_ENABLE I2C_CR1_GCEN
/**
* @}
*/
/** @defgroup I2C_nostretch_mode I2C nostretch mode
/** @defgroup I2C_NOSTRETCH_MODE I2C No-Stretch Mode
* @{
*/
#define I2C_NOSTRETCH_DISABLE ((uint32_t)0x00000000U)
#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
#define I2C_NOSTRETCH_DISABLE (0x00000000U)
#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
/**
* @}
*/
/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size
/** @defgroup I2C_MEMORY_ADDRESS_SIZE I2C Memory Address Size
* @{
*/
#define I2C_MEMADD_SIZE_8BIT ((uint32_t)0x00000001U)
#define I2C_MEMADD_SIZE_16BIT ((uint32_t)0x00000002U)
#define I2C_MEMADD_SIZE_8BIT (0x00000001U)
#define I2C_MEMADD_SIZE_16BIT (0x00000002U)
/**
* @}
*/
*/
/** @defgroup I2C_ReloadEndMode_definition I2C ReloadEndMode definition
/** @defgroup I2C_XFERDIRECTION I2C Transfer Direction Master Point of View
* @{
*/
#define I2C_DIRECTION_TRANSMIT (0x00000000U)
#define I2C_DIRECTION_RECEIVE (0x00000001U)
/**
* @}
*/
/** @defgroup I2C_RELOAD_END_MODE I2C Reload End Mode
* @{
*/
#define I2C_RELOAD_MODE I2C_CR2_RELOAD
#define I2C_AUTOEND_MODE I2C_CR2_AUTOEND
#define I2C_SOFTEND_MODE ((uint32_t)0x00000000U)
#define I2C_SOFTEND_MODE (0x00000000U)
/**
* @}
*/
/** @defgroup I2C_StartStopMode_definition I2C StartStopMode definition
/** @defgroup I2C_START_STOP_MODE I2C Start or Stop Mode
* @{
*/
#define I2C_NO_STARTSTOP ((uint32_t)0x00000000U)
#define I2C_GENERATE_STOP I2C_CR2_STOP
#define I2C_GENERATE_START_READ (uint32_t)(I2C_CR2_START | I2C_CR2_RD_WRN)
#define I2C_GENERATE_START_WRITE I2C_CR2_START
#define I2C_NO_STARTSTOP (0x00000000U)
#define I2C_GENERATE_STOP I2C_CR2_STOP
#define I2C_GENERATE_START_READ (uint32_t)(I2C_CR2_START | I2C_CR2_RD_WRN)
#define I2C_GENERATE_START_WRITE I2C_CR2_START
/**
* @}
*/
@ -263,38 +350,40 @@ typedef struct
* - XXXXXXXX : Interrupt control mask
* @{
*/
#define I2C_IT_ERRI I2C_CR1_ERRIE
#define I2C_IT_TCI I2C_CR1_TCIE
#define I2C_IT_STOPI I2C_CR1_STOPIE
#define I2C_IT_NACKI I2C_CR1_NACKIE
#define I2C_IT_ADDRI I2C_CR1_ADDRIE
#define I2C_IT_RXI I2C_CR1_RXIE
#define I2C_IT_TXI I2C_CR1_TXIE
#define I2C_IT_ERRI I2C_CR1_ERRIE
#define I2C_IT_TCI I2C_CR1_TCIE
#define I2C_IT_STOPI I2C_CR1_STOPIE
#define I2C_IT_NACKI I2C_CR1_NACKIE
#define I2C_IT_ADDRI I2C_CR1_ADDRIE
#define I2C_IT_RXI I2C_CR1_RXIE
#define I2C_IT_TXI I2C_CR1_TXIE
/**
* @}
*/
/** @defgroup I2C_Flag_definition I2C Flag definition
* @{
*/
#define I2C_FLAG_TXE I2C_ISR_TXE
#define I2C_FLAG_TXIS I2C_ISR_TXIS
#define I2C_FLAG_RXNE I2C_ISR_RXNE
#define I2C_FLAG_ADDR I2C_ISR_ADDR
#define I2C_FLAG_AF I2C_ISR_NACKF
#define I2C_FLAG_STOPF I2C_ISR_STOPF
#define I2C_FLAG_TC I2C_ISR_TC
#define I2C_FLAG_TCR I2C_ISR_TCR
#define I2C_FLAG_BERR I2C_ISR_BERR
#define I2C_FLAG_ARLO I2C_ISR_ARLO
#define I2C_FLAG_OVR I2C_ISR_OVR
#define I2C_FLAG_PECERR I2C_ISR_PECERR
#define I2C_FLAG_TIMEOUT I2C_ISR_TIMEOUT
#define I2C_FLAG_ALERT I2C_ISR_ALERT
#define I2C_FLAG_BUSY I2C_ISR_BUSY
#define I2C_FLAG_DIR I2C_ISR_DIR
*/
#define I2C_FLAG_TXE I2C_ISR_TXE
#define I2C_FLAG_TXIS I2C_ISR_TXIS
#define I2C_FLAG_RXNE I2C_ISR_RXNE
#define I2C_FLAG_ADDR I2C_ISR_ADDR
#define I2C_FLAG_AF I2C_ISR_NACKF
#define I2C_FLAG_STOPF I2C_ISR_STOPF
#define I2C_FLAG_TC I2C_ISR_TC
#define I2C_FLAG_TCR I2C_ISR_TCR
#define I2C_FLAG_BERR I2C_ISR_BERR
#define I2C_FLAG_ARLO I2C_ISR_ARLO
#define I2C_FLAG_OVR I2C_ISR_OVR
#define I2C_FLAG_PECERR I2C_ISR_PECERR
#define I2C_FLAG_TIMEOUT I2C_ISR_TIMEOUT
#define I2C_FLAG_ALERT I2C_ISR_ALERT
#define I2C_FLAG_BUSY I2C_ISR_BUSY
#define I2C_FLAG_DIR I2C_ISR_DIR
/**
* @}
*/
/**
* @}
*/
@ -305,190 +394,135 @@ typedef struct
* @{
*/
/** @brief Reset I2C handle state
* @param __HANDLE__: specifies the I2C Handle.
/** @brief Reset I2C handle state.
* @param __HANDLE__ specifies the I2C Handle.
* @retval None
*/
#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET)
#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET)
/** @brief Enable the specified I2C interrupts.
* @param __HANDLE__: specifies the I2C Handle.
* @param __INTERRUPT__: specifies the interrupt source to enable.
/** @brief Enable the specified I2C interrupt.
* @param __HANDLE__ specifies the I2C Handle.
* @param __INTERRUPT__ specifies the interrupt source to enable.
* This parameter can be one of the following values:
* @arg I2C_IT_ERRI: Errors interrupt enable
* @arg I2C_IT_TCI: Transfer complete interrupt enable
* @arg I2C_IT_STOPI: STOP detection interrupt enable
* @arg I2C_IT_NACKI: NACK received interrupt enable
* @arg I2C_IT_ADDRI: Address match interrupt enable
* @arg I2C_IT_RXI: RX interrupt enable
* @arg I2C_IT_TXI: TX interrupt enable
*
* @retval None
*/
#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 |= (__INTERRUPT__))
/** @brief Disable the specified I2C interrupts.
* @param __HANDLE__: specifies the I2C Handle.
* @param __INTERRUPT__: specifies the interrupt source to disable.
* This parameter can be one of the following values:
* @arg I2C_IT_ERRI: Errors interrupt enable
* @arg I2C_IT_TCI: Transfer complete interrupt enable
* @arg I2C_IT_STOPI: STOP detection interrupt enable
* @arg I2C_IT_NACKI: NACK received interrupt enable
* @arg I2C_IT_ADDRI: Address match interrupt enable
* @arg I2C_IT_RXI: RX interrupt enable
* @arg I2C_IT_TXI: TX interrupt enable
*
* @retval None
*/
#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 &= (~(__INTERRUPT__)))
/** @brief Checks if the specified I2C interrupt source is enabled or disabled.
* @param __HANDLE__: specifies the I2C Handle.
* @param __INTERRUPT__: specifies the I2C interrupt source to check.
* This parameter can be one of the following values:
* @arg I2C_IT_ERRI: Errors interrupt enable
* @arg I2C_IT_TCI: Transfer complete interrupt enable
* @arg I2C_IT_STOPI: STOP detection interrupt enable
* @arg I2C_IT_NACKI: NACK received interrupt enable
* @arg I2C_IT_ADDRI: Address match interrupt enable
* @arg I2C_IT_RXI: RX interrupt enable
* @arg I2C_IT_TXI: TX interrupt enable
*
* @retval The new state of __INTERRUPT__ (TRUE or FALSE).
*/
#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
/** @brief Checks whether the specified I2C flag is set or not.
* @param __HANDLE__: specifies the I2C Handle.
* @param __FLAG__: specifies the flag to check.
* This parameter can be one of the following values:
* @arg I2C_FLAG_TXE: Transmit data register empty
* @arg I2C_FLAG_TXIS: Transmit interrupt status
* @arg I2C_FLAG_RXNE: Receive data register not empty
* @arg I2C_FLAG_ADDR: Address matched (slave mode)
* @arg I2C_FLAG_AF: Acknowledge failure received flag
* @arg I2C_FLAG_STOPF: STOP detection flag
* @arg I2C_FLAG_TC: Transfer complete (master mode)
* @arg I2C_FLAG_TCR: Transfer complete reload
* @arg I2C_FLAG_BERR: Bus error
* @arg I2C_FLAG_ARLO: Arbitration lost
* @arg I2C_FLAG_OVR: Overrun/Underrun
* @arg I2C_FLAG_PECERR: PEC error in reception
* @arg I2C_FLAG_TIMEOUT: Timeout or Tlow detection flag
* @arg I2C_FLAG_ALERT: SMBus alert
* @arg I2C_FLAG_BUSY: Bus busy
* @arg I2C_FLAG_DIR: Transfer direction (slave mode)
* @arg @ref I2C_IT_ERRI Errors interrupt enable
* @arg @ref I2C_IT_TCI Transfer complete interrupt enable
* @arg @ref I2C_IT_STOPI STOP detection interrupt enable
* @arg @ref I2C_IT_NACKI NACK received interrupt enable
* @arg @ref I2C_IT_ADDRI Address match interrupt enable
* @arg @ref I2C_IT_RXI RX interrupt enable
* @arg @ref I2C_IT_TXI TX interrupt enable
*
* @retval The new state of __FLAG__ (TRUE or FALSE).
*/
#define I2C_FLAG_MASK ((uint32_t)0x0001FFFF)
#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)))
/** @brief Clears the I2C pending flags which are cleared by writing 1 in a specific bit.
* @param __HANDLE__: specifies the I2C Handle.
* @param __FLAG__: specifies the flag to clear.
* This parameter can be any combination of the following values:
* @arg I2C_FLAG_ADDR: Address matched (slave mode)
* @arg I2C_FLAG_AF: Acknowledge failure received flag
* @arg I2C_FLAG_STOPF: STOP detection flag
* @arg I2C_FLAG_BERR: Bus error
* @arg I2C_FLAG_ARLO: Arbitration lost
* @arg I2C_FLAG_OVR: Overrun/Underrun
* @arg I2C_FLAG_PECERR: PEC error in reception
* @arg I2C_FLAG_TIMEOUT: Timeout or Tlow detection flag
* @arg I2C_FLAG_ALERT: SMBus alert
*
* @retval None
*/
#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = ((__FLAG__) & I2C_FLAG_MASK))
#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 |= (__INTERRUPT__))
/** @brief Disable the specified I2C interrupt.
* @param __HANDLE__ specifies the I2C Handle.
* @param __INTERRUPT__ specifies the interrupt source to disable.
* This parameter can be one of the following values:
* @arg @ref I2C_IT_ERRI Errors interrupt enable
* @arg @ref I2C_IT_TCI Transfer complete interrupt enable
* @arg @ref I2C_IT_STOPI STOP detection interrupt enable
* @arg @ref I2C_IT_NACKI NACK received interrupt enable
* @arg @ref I2C_IT_ADDRI Address match interrupt enable
* @arg @ref I2C_IT_RXI RX interrupt enable
* @arg @ref I2C_IT_TXI TX interrupt enable
*
* @retval None
*/
#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 &= (~(__INTERRUPT__)))
/** @brief Check whether the specified I2C interrupt source is enabled or not.
* @param __HANDLE__ specifies the I2C Handle.
* @param __INTERRUPT__ specifies the I2C interrupt source to check.
* This parameter can be one of the following values:
* @arg @ref I2C_IT_ERRI Errors interrupt enable
* @arg @ref I2C_IT_TCI Transfer complete interrupt enable
* @arg @ref I2C_IT_STOPI STOP detection interrupt enable
* @arg @ref I2C_IT_NACKI NACK received interrupt enable
* @arg @ref I2C_IT_ADDRI Address match interrupt enable
* @arg @ref I2C_IT_RXI RX interrupt enable
* @arg @ref I2C_IT_TXI TX interrupt enable
*
* @retval The new state of __INTERRUPT__ (SET or RESET).
*/
#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
/** @brief Check whether the specified I2C flag is set or not.
* @param __HANDLE__ specifies the I2C Handle.
* @param __FLAG__ specifies the flag to check.
* This parameter can be one of the following values:
* @arg @ref I2C_FLAG_TXE Transmit data register empty
* @arg @ref I2C_FLAG_TXIS Transmit interrupt status
* @arg @ref I2C_FLAG_RXNE Receive data register not empty
* @arg @ref I2C_FLAG_ADDR Address matched (slave mode)
* @arg @ref I2C_FLAG_AF Acknowledge failure received flag
* @arg @ref I2C_FLAG_STOPF STOP detection flag
* @arg @ref I2C_FLAG_TC Transfer complete (master mode)
* @arg @ref I2C_FLAG_TCR Transfer complete reload
* @arg @ref I2C_FLAG_BERR Bus error
* @arg @ref I2C_FLAG_ARLO Arbitration lost
* @arg @ref I2C_FLAG_OVR Overrun/Underrun
* @arg @ref I2C_FLAG_PECERR PEC error in reception
* @arg @ref I2C_FLAG_TIMEOUT Timeout or Tlow detection flag
* @arg @ref I2C_FLAG_ALERT SMBus alert
* @arg @ref I2C_FLAG_BUSY Bus busy
* @arg @ref I2C_FLAG_DIR Transfer direction (slave mode)
*
* @retval The new state of __FLAG__ (SET or RESET).
*/
#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & (__FLAG__)) == (__FLAG__)) ? SET : RESET)
/** @brief Clear the I2C pending flags which are cleared by writing 1 in a specific bit.
* @param __HANDLE__ specifies the I2C Handle.
* @param __FLAG__ specifies the flag to clear.
* This parameter can be any combination of the following values:
* @arg @ref I2C_FLAG_TXE Transmit data register empty
* @arg @ref I2C_FLAG_ADDR Address matched (slave mode)
* @arg @ref I2C_FLAG_AF Acknowledge failure received flag
* @arg @ref I2C_FLAG_STOPF STOP detection flag
* @arg @ref I2C_FLAG_BERR Bus error
* @arg @ref I2C_FLAG_ARLO Arbitration lost
* @arg @ref I2C_FLAG_OVR Overrun/Underrun
* @arg @ref I2C_FLAG_PECERR PEC error in reception
* @arg @ref I2C_FLAG_TIMEOUT Timeout or Tlow detection flag
* @arg @ref I2C_FLAG_ALERT SMBus alert
*
* @retval None
*/
#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__FLAG__) == I2C_FLAG_TXE) ? ((__HANDLE__)->Instance->ISR |= (__FLAG__)) \
: ((__HANDLE__)->Instance->ICR = (__FLAG__)))
/** @brief Enable the specified I2C peripheral.
* @param __HANDLE__: specifies the I2C Handle.
* @param __HANDLE__ specifies the I2C Handle.
* @retval None
*/
#define __HAL_I2C_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE))
/** @brief Disable the specified I2C peripheral.
* @param __HANDLE__: specifies the I2C Handle.
* @param __HANDLE__ specifies the I2C Handle.
* @retval None
*/
#define __HAL_I2C_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE))
/**
* @}
*/
/** @brief Generate a Non-Acknowledge I2C peripheral in Slave mode.
* @param __HANDLE__: specifies the I2C Handle.
* @retval None
*/
#define __HAL_I2C_GENERATE_NACK(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR2, I2C_CR2_NACK))
/**
* @}
*/
/* Include I2C HAL Extension module */
/* Include I2C HAL Extended module */
#include "stm32l0xx_hal_i2c_ex.h"
/* Private macros ------------------------------------------------------------*/
/** @addtogroup I2C_Private
* @{
*/
#define IS_I2C_ADDRESSING_MODE(MODE) (((MODE) == I2C_ADDRESSINGMODE_7BIT) || \
((MODE) == I2C_ADDRESSINGMODE_10BIT))
#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \
((ADDRESS) == I2C_DUALADDRESS_ENABLE))
#define IS_I2C_OWN_ADDRESS2_MASK(MASK) (((MASK) == I2C_OA2_NOMASK) || \
((MASK) == I2C_OA2_MASK01) || \
((MASK) == I2C_OA2_MASK02) || \
((MASK) == I2C_OA2_MASK03) || \
((MASK) == I2C_OA2_MASK04) || \
((MASK) == I2C_OA2_MASK05) || \
((MASK) == I2C_OA2_MASK06) || \
((MASK) == I2C_OA2_MASK07))
#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \
((CALL) == I2C_GENERALCALL_ENABLE))
#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \
((STRETCH) == I2C_NOSTRETCH_ENABLE))
#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \
((SIZE) == I2C_MEMADD_SIZE_16BIT))
#define IS_TRANSFER_MODE(MODE) (((MODE) == I2C_RELOAD_MODE) || \
((MODE) == I2C_AUTOEND_MODE) || \
((MODE) == I2C_SOFTEND_MODE))
#define IS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == I2C_GENERATE_STOP) || \
((REQUEST) == I2C_GENERATE_START_READ) || \
((REQUEST) == I2C_GENERATE_START_WRITE) || \
((REQUEST) == I2C_NO_STARTSTOP))
#define __I2C_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN)))
#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= (uint32_t)0x000003FFU)
#define IS_I2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FFU)
#define __I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8)))
#define __I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU))))
#define __I2C_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == I2C_ADDRESSINGMODE_7BIT) ? (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & (~I2C_CR2_RD_WRN)) : \
(uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_ADD10) | (I2C_CR2_START)) & (~I2C_CR2_RD_WRN)))
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup I2C_Exported_Functions I2C Exported Functions
/** @addtogroup I2C_Exported_Functions
* @{
*/
/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions
/** @addtogroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions
* @{
*/
/* Initialization and de-initialization functions******************************/
@ -498,9 +532,9 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c);
/**
* @}
*/
*/
/** @defgroup I2C_Exported_Functions_Group2 Input and Output operation functions
/** @addtogroup I2C_Exported_Functions_Group2 Input and Output operation functions
* @{
*/
/* IO operation functions ****************************************************/
@ -521,6 +555,14 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pDa
HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress);
/******* Non-Blocking mode: DMA */
HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
@ -530,30 +572,34 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
/**
* @}
*/
*/
/** @defgroup IRQ_Handler_and_Callbacks RQ Handler and Callbacks
/** @addtogroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
* @{
*/
/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */
*/
/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */
void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c);
void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode);
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
/**
* @}
*/
*/
/** @defgroup I2C_Exported_Functions_Group3 Peripheral State and Errors functions
/** @addtogroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
* @{
*/
/* Peripheral State and Errors functions *************************************/
/* Peripheral State, Mode and Error functions *********************************/
HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c);
HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c);
uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c);
/**
@ -563,18 +609,85 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c);
/**
* @}
*/
/* Define the private group ***********************************/
/**************************************************************/
/** @defgroup I2C_Private I2C Private
/* Private constants ---------------------------------------------------------*/
/** @defgroup I2C_Private_Constants I2C Private Constants
* @{
*/
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
/** @defgroup I2C_Private_Macro I2C Private Macros
* @{
*/
/**************************************************************/
#define IS_I2C_ADDRESSING_MODE(MODE) (((MODE) == I2C_ADDRESSINGMODE_7BIT) || \
((MODE) == I2C_ADDRESSINGMODE_10BIT))
#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \
((ADDRESS) == I2C_DUALADDRESS_ENABLE))
#define IS_I2C_OWN_ADDRESS2_MASK(MASK) (((MASK) == I2C_OA2_NOMASK) || \
((MASK) == I2C_OA2_MASK01) || \
((MASK) == I2C_OA2_MASK02) || \
((MASK) == I2C_OA2_MASK03) || \
((MASK) == I2C_OA2_MASK04) || \
((MASK) == I2C_OA2_MASK05) || \
((MASK) == I2C_OA2_MASK06) || \
((MASK) == I2C_OA2_MASK07))
#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \
((CALL) == I2C_GENERALCALL_ENABLE))
#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \
((STRETCH) == I2C_NOSTRETCH_ENABLE))
#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \
((SIZE) == I2C_MEMADD_SIZE_16BIT))
#define IS_TRANSFER_MODE(MODE) (((MODE) == I2C_RELOAD_MODE) || \
((MODE) == I2C_AUTOEND_MODE) || \
((MODE) == I2C_SOFTEND_MODE))
#define IS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == I2C_GENERATE_STOP) || \
((REQUEST) == I2C_GENERATE_START_READ) || \
((REQUEST) == I2C_GENERATE_START_WRITE) || \
((REQUEST) == I2C_NO_STARTSTOP))
#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \
((REQUEST) == I2C_FIRST_AND_NEXT_FRAME) || \
((REQUEST) == I2C_NEXT_FRAME) || \
((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \
((REQUEST) == I2C_LAST_FRAME))
#define I2C_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN)))
#define I2C_GET_ADDR_MATCH(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_ADDCODE) >> 16U)
#define I2C_GET_DIR(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_DIR) >> 16U)
#define I2C_GET_STOP_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_AUTOEND)
#define I2C_GET_OWN_ADDRESS1(__HANDLE__) ((__HANDLE__)->Instance->OAR1 & I2C_OAR1_OA1)
#define I2C_GET_OWN_ADDRESS2(__HANDLE__) ((__HANDLE__)->Instance->OAR2 & I2C_OAR2_OA2)
#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x000003FFU)
#define IS_I2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FFU)
#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8U)))
#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU))))
#define I2C_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == I2C_ADDRESSINGMODE_7BIT) ? (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & (~I2C_CR2_RD_WRN)) : \
(uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_ADD10) | (I2C_CR2_START)) & (~I2C_CR2_RD_WRN)))
/**
* @}
*/
/* Private Functions ---------------------------------------------------------*/
/** @defgroup I2C_Private_Functions I2C Private Functions
* @{
*/
/* Private functions are defined in stm32l0xx_hal_i2c.c file */
/**
* @}
*/
@ -582,7 +695,11 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
@ -591,4 +708,3 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c);
#endif /* __STM32L0xx_HAL_I2C_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -2,36 +2,36 @@
******************************************************************************
* @file stm32l0xx_hal_i2c_ex.c
* @author MCD Application Team
* @version V1.7.0
* @date 31-May-2016
* @version $VERSION$
* @date $DATE$
* @brief I2C Extended HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of I2C Extended peripheral:
* + Extended features functions
*
*
@verbatim
==============================================================================
##### I2C peripheral Extended features #####
==============================================================================
[..] Comparing to other previous devices, the I2C interface for STM32L0XX
[..] Comparing to other previous devices, the I2C interface for STM32L0xx
devices contains the following additional features
(+) Possibility to disable or enable Analog Noise Filter
(+) Use of a configured Digital Noise Filter
(+) Disable or enable wakeup from Stop mode
##### How to use this driver #####
==============================================================================
[..] This driver provides functions to configure Noise Filter
[..] This driver provides functions to configure Noise Filter and Wake Up Feature
(#) Configure I2C Analog noise filter using the function HAL_I2CEx_ConfigAnalogFilter()
(#) Configure I2C Digital noise filter using the function HAL_I2CEx_ConfigDigitalFilter()
(#) Configure the enable or disable of I2C Wake Up Mode using the functions :
+ HAL_I2CEx_EnableWakeUp()
+ HAL_I2CEx_DisableWakeUp()
(++) HAL_I2CEx_EnableWakeUp()
(++) HAL_I2CEx_DisableWakeUp()
(#) Configure the enable or disable of fast mode plus driving capability using the functions :
+ HAL_I2CEx_EnableFastModePlus()
+ HAL_I2CEx_DisbleFastModePlus()
(++) HAL_I2CEx_EnableFastModePlus()
(++) HAL_I2CEx_DisableFastModePlus()
@endverbatim
******************************************************************************
* @attention
@ -60,8 +60,8 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32l0xx_hal.h"
@ -69,13 +69,14 @@
/** @addtogroup STM32L0xx_HAL_Driver
* @{
*/
#ifdef HAL_I2C_MODULE_ENABLED
/** @addtogroup I2CEx
/** @defgroup I2CEx I2CEx
* @brief I2C Extended HAL module driver
* @{
*/
#ifdef HAL_I2C_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
@ -83,29 +84,30 @@
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @addtogroup I2CEx_Exported_Functions
/** @defgroup I2CEx_Exported_Functions I2C Extended Exported Functions
* @{
*/
/** @addtogroup I2CEx_Exported_Functions_Group1
/** @defgroup I2CEx_Exported_Functions_Group1 Extended features functions
* @brief Extended features functions
*
@verbatim
@verbatim
===============================================================================
##### Extended features functions #####
===============================================================================
===============================================================================
[..] This section provides functions allowing to:
(+) Configure Noise Filters
(+) Configure Wake Up Feature
@endverbatim
* @{
*/
/**
* @brief Configures I2C Analog noise filter.
* @param hi2c : pointer to a I2C_HandleTypeDef structure that contains
* @brief Configure I2C Analog noise filter.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2Cx peripheral.
* @param AnalogFilter : new state of the Analog filter.
* @param AnalogFilter New state of the Analog filter.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter)
@ -113,91 +115,93 @@ HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t
/* Check the parameters */
assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter));
if((hi2c->State == HAL_I2C_STATE_BUSY) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_RX)
|| (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_RX))
if(hi2c->State == HAL_I2C_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Reset I2Cx ANOFF bit */
hi2c->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
/* Set analog filter bit*/
hi2c->Instance->CR1 |= AnalogFilter;
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Reset I2Cx ANOFF bit */
hi2c->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
/* Set analog filter bit*/
hi2c->Instance->CR1 |= AnalogFilter;
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
/**
* @brief Configures I2C Digital noise filter.
* @param hi2c : pointer to a I2C_HandleTypeDef structure that contains
* @brief Configure I2C Digital noise filter.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2Cx peripheral.
* @param DigitalFilter : Coefficient of digital noise filter between 0x00 and 0x0F.
* @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter)
{
uint32_t tmpreg = 0U;
/* Check the parameters */
assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter));
if((hi2c->State == HAL_I2C_STATE_BUSY) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_RX)
|| (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_RX))
if(hi2c->State == HAL_I2C_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Get the old register value */
tmpreg = hi2c->Instance->CR1;
/* Reset I2Cx DNF bits [11:8] */
tmpreg &= ~(I2C_CR1_DNF);
/* Set I2Cx DNF coefficient */
tmpreg |= DigitalFilter << 8U;
/* Store the new register value */
hi2c->Instance->CR1 = tmpreg;
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Get the old register value */
tmpreg = hi2c->Instance->CR1;
/* Reset I2Cx DNF bits [11:8] */
tmpreg &= ~(I2C_CR1_DNF);
/* Set I2Cx DNF coefficient */
tmpreg |= DigitalFilter << 8U;
/* Store the new register value */
hi2c->Instance->CR1 = tmpreg;
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
}
/**
* @brief Enables I2C wakeup from stop mode.
* @param hi2c : pointer to a I2C_HandleTypeDef structure that contains
* @brief Enable I2C wakeup from stop mode.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2Cx peripheral.
* @retval HAL status
*/
@ -205,38 +209,38 @@ HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp (I2C_HandleTypeDef *hi2c)
{
/* Check the parameters */
assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
if((hi2c->State == HAL_I2C_STATE_BUSY) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_RX)
|| (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_RX))
if(hi2c->State == HAL_I2C_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Enable wakeup from stop mode */
hi2c->Instance->CR1 |= I2C_CR1_WUPEN;
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Enable wakeup from stop mode */
hi2c->Instance->CR1 |= I2C_CR1_WUPEN;
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
}
/**
* @brief Disables I2C wakeup from stop mode.
* @param hi2c : pointer to a I2C_HandleTypeDef structure that contains
* @brief Disable I2C wakeup from stop mode.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2Cx peripheral.
* @retval HAL status
*/
@ -244,37 +248,38 @@ HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp (I2C_HandleTypeDef *hi2c)
{
/* Check the parameters */
assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
if((hi2c->State == HAL_I2C_STATE_BUSY) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MASTER_BUSY_RX)
|| (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_RX))
if(hi2c->State == HAL_I2C_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Enable wakeup from stop mode */
hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN);
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
/* Disable the selected I2C peripheral */
__HAL_I2C_DISABLE(hi2c);
/* Enable wakeup from stop mode */
hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN);
__HAL_I2C_ENABLE(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
}
/**
* @brief Enable the I2C fast mode plus driving capability.
* @param ConfigFastModePlus: selects the pin.
* @param ConfigFastModePlus Selects the pin.
* This parameter can be one of the @ref I2CEx_FastModePlus values
* @note For I2C1, fast mode plus driving capability can be enabled on all selected
* I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently
@ -291,17 +296,17 @@ void HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus)
{
/* Check the parameter */
assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus));
/* Enable SYSCFG clock */
__HAL_RCC_SYSCFG_CLK_ENABLE();
/* Enable fast mode plus driving capability for selected pin */
SET_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus);
SET_BIT(SYSCFG->CFGR2, (uint32_t)ConfigFastModePlus);
}
/**
* @brief Disable the I2C fast mode plus driving capability.
* @param ConfigFastModePlus: selects the pin.
* @param ConfigFastModePlus Selects the pin.
* This parameter can be one of the @ref I2CEx_FastModePlus values
* @note For I2C1, fast mode plus driving capability can be disabled on all selected
* I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently
@ -318,31 +323,29 @@ void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus)
{
/* Check the parameter */
assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus));
/* Enable SYSCFG clock */
__HAL_RCC_SYSCFG_CLK_ENABLE();
/* Disable fast mode plus driving capability for selected pin */
CLEAR_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus);
CLEAR_BIT(SYSCFG->CFGR2, (uint32_t)ConfigFastModePlus);
}
/**
* @}
*/
/**
* @}
*/
*/
/**
* @}
*/
#endif /* HAL_I2C_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -2,9 +2,9 @@
******************************************************************************
* @file stm32l0xx_hal_i2c_ex.h
* @author MCD Application Team
* @version V1.7.0
* @date 31-May-2016
* @brief Header file of I2C HAL Extension module.
* @version $VERSION$
* @date $DATE$
* @brief Header file of I2C HAL Extended module.
******************************************************************************
* @attention
*
@ -33,7 +33,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32L0xx_HAL_I2C_EX_H
@ -44,124 +44,114 @@
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32l0xx_hal_def.h"
#include "stm32l0xx_hal_def.h"
/** @addtogroup STM32L0xx_HAL_Driver
* @{
*/
/** @defgroup I2CEx I2CEx
/** @addtogroup I2CEx
* @{
*/
/* Exported types ------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/** @defgroup I2CEx_Exported_Constants I2CEx Exported Constants
/** @defgroup I2CEx_Exported_Constants I2C Extended Exported Constants
* @{
*/
/** @defgroup I2CEx_Analog_Filter I2C Analog Filter Enabling
/** @defgroup I2CEx_Analog_Filter I2C Extended Analog Filter
* @{
*/
#define I2C_ANALOGFILTER_ENABLE ((uint32_t)0x00000000U)
#define I2C_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF
#define I2C_ANALOGFILTER_ENABLE 0x00000000U
#define I2C_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF
/**
* @}
*/
/** @defgroup I2CEx_FastModePlus I2C Fast Mode Plus
/** @defgroup I2CEx_FastModePlus I2C Extended Fast Mode Plus
* @{
*/
#define I2C_FASTMODEPLUS_PB6 SYSCFG_CFGR2_I2C_PB6_FMP /*!< Enable Fast Mode Plus on PB6 */
#define I2C_FASTMODEPLUS_PB7 SYSCFG_CFGR2_I2C_PB7_FMP /*!< Enable Fast Mode Plus on PB7 */
#define I2C_FASTMODEPLUS_PB8 SYSCFG_CFGR2_I2C_PB8_FMP /*!< Enable Fast Mode Plus on PB8 */
#define I2C_FASTMODEPLUS_PB9 SYSCFG_CFGR2_I2C_PB9_FMP /*!< Enable Fast Mode Plus on PB9 */
#define I2C_FASTMODEPLUS_I2C1 SYSCFG_CFGR2_I2C1_FMP /*!< Enable Fast Mode Plus on I2C1 pins */
#if !defined(STM32L011xx) && !defined(STM32L021xx) && !defined(STM32L031xx) && !defined(STM32L041xx)
#define I2C_FASTMODEPLUS_I2C2 SYSCFG_CFGR2_I2C2_FMP /*!< Enable Fast Mode Plus on I2C2 pins */
#define I2C_FMP_NOT_SUPPORTED 0xAAAA0000U /*!< Fast Mode Plus not supported */
#define I2C_FASTMODEPLUS_PB6 SYSCFG_CFGR2_I2C_PB6_FMP /*!< Enable Fast Mode Plus on PB6 */
#define I2C_FASTMODEPLUS_PB7 SYSCFG_CFGR2_I2C_PB7_FMP /*!< Enable Fast Mode Plus on PB7 */
#define I2C_FASTMODEPLUS_PB8 SYSCFG_CFGR2_I2C_PB8_FMP /*!< Enable Fast Mode Plus on PB8 */
#define I2C_FASTMODEPLUS_PB9 SYSCFG_CFGR2_I2C_PB9_FMP /*!< Enable Fast Mode Plus on PB9 */
#define I2C_FASTMODEPLUS_I2C1 SYSCFG_CFGR2_I2C1_FMP /*!< Enable Fast Mode Plus on I2C1 pins */
#if defined(SYSCFG_CFGR2_I2C2_FMP)
#define I2C_FASTMODEPLUS_I2C2 SYSCFG_CFGR2_I2C2_FMP /*!< Enable Fast Mode Plus on I2C2 pins */
#else
#define I2C_FASTMODEPLUS_I2C2 (uint32_t)(0x00000200U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus I2C2 not supported */
#endif
#if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
#define I2C_FASTMODEPLUS_I2C3 SYSCFG_CFGR2_I2C3_FMP /*!< Enable Fast Mode Plus on I2C3 pins */
#if defined(SYSCFG_CFGR2_I2C3_FMP)
#define I2C_FASTMODEPLUS_I2C3 SYSCFG_CFGR2_I2C3_FMP /*!< Enable Fast Mode Plus on I2C3 pins */
#else
#define I2C_FASTMODEPLUS_I2C3 (uint32_t)(0x00000400U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus I2C3 not supported */
#endif
/**
* @}
*/
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup I2CEx_Exported_Functions I2CEx Exported Functions
/** @addtogroup I2CEx_Exported_Functions I2C Extended Exported Functions
* @{
*/
/* Peripheral Control methods ************************************************/
/** @addtogroup I2CEx_Exported_Functions_Group1 Extended Features Functions
/** @addtogroup I2CEx_Exported_Functions_Group1 Extended features functions
* @brief Extended features functions
* @{
*/
/* Peripheral Control functions ************************************************/
HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter);
HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter);
HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c);
void HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus);
void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus);
/**
* @}
*/
/* Private constants ---------------------------------------------------------*/
/** @defgroup I2CEx_Private_Constants I2C Extended Private Constants
* @{
*/
/**
* @}
*/
*/
/* Private macros ------------------------------------------------------------*/
/** @defgroup I2CEx_Private I2CEx Private
/** @defgroup I2CEx_Private_Macro I2C Extended Private Macros
* @{
*/
#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \
((FILTER) == I2C_ANALOGFILTER_DISABLE))
#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU)
#if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L011xx) || defined(STM32L021xx)
#define IS_I2C_FASTMODEPLUS(__CONFIG__) ((((__CONFIG__) & (I2C_FASTMODEPLUS_PB6)) == I2C_FASTMODEPLUS_PB6) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB7)) == I2C_FASTMODEPLUS_PB7) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB8)) == I2C_FASTMODEPLUS_PB8) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB9)) == I2C_FASTMODEPLUS_PB9) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_I2C1)) == I2C_FASTMODEPLUS_I2C1))
#elif defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
#define IS_I2C_FASTMODEPLUS(__CONFIG__) ((((__CONFIG__) & (I2C_FASTMODEPLUS_PB6)) == I2C_FASTMODEPLUS_PB6) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB7)) == I2C_FASTMODEPLUS_PB7) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB8)) == I2C_FASTMODEPLUS_PB8) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB9)) == I2C_FASTMODEPLUS_PB9) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_I2C1)) == I2C_FASTMODEPLUS_I2C1) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_I2C2)) == I2C_FASTMODEPLUS_I2C2) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_I2C3)) == I2C_FASTMODEPLUS_I2C3))
#else
#define IS_I2C_FASTMODEPLUS(__CONFIG__) ((((__CONFIG__) & (I2C_FASTMODEPLUS_PB6)) == I2C_FASTMODEPLUS_PB6) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB7)) == I2C_FASTMODEPLUS_PB7) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB8)) == I2C_FASTMODEPLUS_PB8) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB9)) == I2C_FASTMODEPLUS_PB9) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_I2C1)) == I2C_FASTMODEPLUS_I2C1) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_I2C2)) == I2C_FASTMODEPLUS_I2C2))
#endif
#define IS_I2C_FASTMODEPLUS(__CONFIG__) ((((__CONFIG__) & I2C_FMP_NOT_SUPPORTED) != I2C_FMP_NOT_SUPPORTED) && \
((((__CONFIG__) & (I2C_FASTMODEPLUS_PB6)) == I2C_FASTMODEPLUS_PB6) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB7)) == I2C_FASTMODEPLUS_PB7) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB8)) == I2C_FASTMODEPLUS_PB8) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_PB9)) == I2C_FASTMODEPLUS_PB9) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_I2C1)) == I2C_FASTMODEPLUS_I2C1) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_I2C2)) == I2C_FASTMODEPLUS_I2C2) || \
(((__CONFIG__) & (I2C_FASTMODEPLUS_I2C3)) == I2C_FASTMODEPLUS_I2C3)))
/**
* @}
*/
/* Define the private group ***********************************/
/**************************************************************/
/** @defgroup I2CEx_Private I2CEx Private
/* Private Functions ---------------------------------------------------------*/
/** @defgroup I2CEx_Private_Functions I2C Extended Private Functions
* @{
*/
/**
* @}
*/
/**************************************************************/
/* Private functions are defined in stm32l0xx_hal_i2c_ex.c file */
/**
* @}
*/
@ -169,13 +159,23 @@ void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32L0xx_HAL_I2C_EX_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -1,427 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#if DEVICE_I2C
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x1000)
#define LONG_TIMEOUT ((int)0x8000)
I2C_HandleTypeDef I2cHandle;
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
static int i2c1_inited = 0;
#if defined(I2C2_BASE)
static int i2c2_inited = 0;
#endif
#if defined(I2C3_BASE)
static int i2c3_inited = 0;
#endif
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C1 clock and pinout if not done
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
__I2C1_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#if defined(I2C2_BASE)
// Enable I2C2 clock and pinout if not done
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__I2C2_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
#if defined(I2C3_BASE)
// Enable I2C3 clock and pinout if not done
if ((obj->i2c == I2C_3) && !i2c3_inited) {
i2c3_inited = 1;
__I2C3_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
// Reset to clear pending flags if any
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
}
void i2c_frequency(i2c_t *obj, int hz)
{
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
// wait before init
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Common settings: I2C clock = 32 MHz, Analog filter = ON, Digital filter coefficient = 0
switch (hz) {
case 100000:
I2cHandle.Init.Timing = 0x20602938; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
break;
case 400000:
I2cHandle.Init.Timing = 0x00B0122A; // Fast mode with Rise Time = 250ns and Fall Time = 100ns
break;
case 1000000:
I2cHandle.Init.Timing = 0x0030040E; // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
break;
default:
break;
}
// I2C configuration
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0;
I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
if (HAL_I2C_Init(&I2cHandle) != HAL_OK) {
error("Cannot initialize I2C");
}
}
inline int i2c_start(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Wait the STOP condition has been previously correctly sent
timeout = FLAG_TIMEOUT;
while ((i2c->CR2 & I2C_CR2_STOP) == I2C_CR2_STOP){
if ((timeout--) == 0) {
return 1;
}
}
// Generate the START condition
i2c->CR2 |= I2C_CR2_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
inline int i2c_stop(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
i2c->CR2 |= I2C_CR2_STOP;
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
int value;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ);
// Read all bytes
for (count = 0; count < length; count++) {
value = i2c_byte_read(obj, 0);
data[count] = (char)value;
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE);
for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]);
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return count;
}
int i2c_byte_read(i2c_t *obj, int last)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->RXDR;
}
int i2c_byte_write(i2c_t *obj, int data)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the previous byte is transmitted
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) {
if ((timeout--) == 0) {
return 0;
}
}
i2c->TXDR = (uint8_t)data;
return 1;
}
void i2c_reset(i2c_t *obj)
{
int timeout;
// wait before reset
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
#if defined(I2C2_BASE)
if (obj->i2c == I2C_2) {
__I2C2_FORCE_RESET();
__I2C2_RELEASE_RESET();
}
#endif
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// disable
i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
// Get the old register value
tmpreg = i2c->OAR1;
// Reset address bits
tmpreg &= 0xFC00;
// Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value
i2c->OAR1 = tmpreg;
// enable
i2c->OAR1 |= I2C_OAR1_OA1EN;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// Get the old register value
tmpreg = i2c->OAR1;
// Enable / disable slave
if (enable_slave == 1) {
tmpreg |= I2C_OAR1_OA1EN;
} else {
tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
}
// Set new mode
i2c->OAR1 = tmpreg;
}
// See I2CSlave.h
#define NoData 0 // the slave has not been addressed
#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj)
{
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int retValue = NoData;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_DIR) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
char size = 0;
while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
char size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
do {
i2c_byte_write(obj, data[size]);
size++;
} while (size < length);
return size;
}
#endif // DEVICE_I2CSLAVE
#endif // DEVICE_I2C

View File

@ -0,0 +1,90 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_I2C_DEVICE_H
#define MBED_I2C_DEVICE_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEVICE_I2C
#define I2C_IP_VERSION_V2
#if defined I2C1_BASE
#define I2C1_EV_IRQn I2C1_IRQn
#define I2C1_ER_IRQn I2C1_IRQn
#endif
#if defined I2C2_BASE
#define I2C2_EV_IRQn I2C2_IRQn
#define I2C2_ER_IRQn I2C2_IRQn
#endif
#if defined I2C3_BASE
#define I2C3_EV_IRQn I2C3_IRQn
#define I2C3_ER_IRQn I2C3_IRQn
#endif
#define I2C_IT_ALL (I2C_IT_ERRI|I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_NACKI|I2C_IT_ADDRI|I2C_IT_RXI|I2C_IT_TXI)
/* Family specifc settings for clock source */
#define I2CAPI_I2C1_CLKSRC RCC_I2C1CLKSOURCE_SYSCLK
#define I2CAPI_I2C3_CLKSRC RCC_I2C3CLKSOURCE_SYSCLK
#define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_SYSCLK
/* Provide the suitable timing depending on requested frequencie */
inline uint32_t get_i2c_timing(int hz)
{
uint32_t tim = 0;
switch (hz) {
case 100000:
tim = 0x20602938; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
break;
case 400000:
tim = 0x00B0122A; // Fast mode with Rise Time = 250ns and Fall Time = 100ns
break;
case 1000000:
tim = 0x0030040E; // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
break;
default:
break;
}
return tim;
}
#ifdef __cplusplus
}
#endif
#endif // DEVICE_I2C
#endif

View File

@ -65,11 +65,6 @@ struct dac_s {
PinName pin;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -65,11 +65,6 @@ struct dac_s {
PinName pin;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -65,11 +65,6 @@ struct dac_s {
PinName pin;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -65,11 +65,6 @@ struct dac_s {
PinName pin;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
#include "common_objects.h"
#include "gpio_object.h"

View File

@ -80,6 +80,34 @@ struct spi_s {
#endif
};
struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
* be kept as the first members of this struct
* to ensure i2c_get_obj to work as expected
*/
I2CName i2c;
I2C_HandleTypeDef handle;
uint8_t index;
int hz;
PinName sda;
PinName scl;
IRQn_Type event_i2cIRQ;
IRQn_Type error_i2cIRQ;
uint32_t XferOperation;
volatile uint8_t event;
#if DEVICE_I2CSLAVE
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
uint8_t stop;
uint8_t available_events;
#endif
};
#include "gpio_object.h"
#ifdef __cplusplus

View File

@ -3799,44 +3799,38 @@ static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c)
*/
static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
{
if(hi2c->State == HAL_I2C_STATE_BUSY_RX)
{
if(hi2c->XferCount > 3U)
uint32_t tmp = 0U;
tmp = hi2c->XferCount;
if(tmp > 3U)
{
/* Read data from DR */
(*hi2c->pBuffPtr++) = hi2c->Instance->DR;
hi2c->XferCount--;
}
else if((hi2c->XferCount == 2U) || (hi2c->XferCount == 3U))
else if((tmp == 2U) || (tmp == 3U))
{
if(hi2c->XferOptions != I2C_NEXT_FRAME)
{
/* Disable Acknowledge */
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
/* Enable Pos */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
}
else
{
/* Enable Acknowledge */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
}
/* Disable Acknowledge */
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
/* Enable Pos */
hi2c->Instance->CR1 |= I2C_CR1_POS;
/* Disable BUF interrupt */
__HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
}
else
{
if(hi2c->XferOptions != I2C_NEXT_FRAME)
/* Disable Acknowledge */
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
if(hi2c->XferOptions == I2C_NEXT_FRAME)
{
/* Disable Acknowledge */
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
}
else
{
/* Enable Acknowledge */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
/* Enable Pos */
hi2c->Instance->CR1 |= I2C_CR1_POS;
}
/* Disable EVT, BUF and ERR interrupt */
@ -3846,17 +3840,17 @@ static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
(*hi2c->pBuffPtr++) = hi2c->Instance->DR;
hi2c->XferCount--;
tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
hi2c->State = HAL_I2C_STATE_READY;
if(hi2c->Mode == HAL_I2C_MODE_MEM)
{
hi2c->PreviousState = I2C_STATE_NONE;
hi2c->Mode = HAL_I2C_MODE_NONE;
HAL_I2C_MemRxCpltCallback(hi2c);
}
else
{
hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
hi2c->Mode = HAL_I2C_MODE_NONE;
HAL_I2C_MasterRxCpltCallback(hi2c);
}
@ -3873,12 +3867,16 @@ static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
*/
static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c)
{
/* Declaration of temporary variables to prevent undefined behavior of volatile usage */
uint32_t tmp;
uint32_t CurrentXferOptions = hi2c->XferOptions;
if(hi2c->XferCount == 3U)
{
if((hi2c->XferOptions == I2C_FIRST_AND_LAST_FRAME) || (hi2c->XferOptions == I2C_LAST_FRAME) || (hi2c->XferOptions == I2C_NO_OPTION_FRAME))
if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME))
{
/* Disable Acknowledge */
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
}
/* Read data from DR */
@ -3888,23 +3886,25 @@ static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c)
else if(hi2c->XferCount == 2U)
{
/* Prepare next transfer or stop current transfer */
if((hi2c->XferOptions != I2C_FIRST_AND_LAST_FRAME) && (hi2c->XferOptions != I2C_LAST_FRAME) && (hi2c->XferOptions != I2C_NO_OPTION_FRAME))
if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME))
{
if(hi2c->XferOptions != I2C_NEXT_FRAME)
/* Disable Acknowledge */
hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME))
{
/* Disable Acknowledge */
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
}
else
{
/* Enable Acknowledge */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
/* Generate Start */
hi2c->Instance->CR1 |= I2C_CR1_START;
}
tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
}
else
{
hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
/* Generate Stop */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
hi2c->Instance->CR1 |= I2C_CR1_STOP;
}
/* Read data from DR */
@ -3919,17 +3919,18 @@ static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c)
__HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
hi2c->State = HAL_I2C_STATE_READY;
hi2c->PreviousState = I2C_STATE_NONE;
if(hi2c->Mode == HAL_I2C_MODE_MEM)
{
hi2c->PreviousState = I2C_STATE_NONE;
hi2c->Mode = HAL_I2C_MODE_NONE;
HAL_I2C_MemRxCpltCallback(hi2c);
}
else
{
hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
hi2c->Mode = HAL_I2C_MODE_NONE;
HAL_I2C_MasterRxCpltCallback(hi2c);
}
}

View File

@ -1,489 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#if DEVICE_I2C
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x1000)
#define LONG_TIMEOUT ((int)0x8000)
I2C_HandleTypeDef I2cHandle;
int i2c1_inited = 0;
int i2c2_inited = 0;
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C1 clock and pinout if not done
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__I2C1_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
// Enable I2C2 clock and pinout if not done
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__I2C2_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
// Reset to clear pending flags if any
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
// I2C master by default
obj->slave = 0;
}
void i2c_frequency(i2c_t *obj, int hz)
{
MBED_ASSERT((hz != 0) && (hz <= 400000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
// wait before init
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// I2C configuration
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.ClockSpeed = hz;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0;
HAL_I2C_Init(&I2cHandle);
if (obj->slave) {
/* Enable Address Acknowledge */
I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
}
}
inline int i2c_start(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Wait the STOP condition has been previously correctly sent
// This timeout can be avoid in some specific cases by simply clearing the STOP bit
timeout = FLAG_TIMEOUT;
while ((i2c->CR1 & I2C_CR1_STOP) == I2C_CR1_STOP) {
if ((timeout--) == 0) {
return 1;
}
}
// Generate the START condition
i2c->CR1 |= I2C_CR1_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
inline int i2c_stop(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
i2c->CR1 |= I2C_CR1_STOP;
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
int value;
i2c_start(obj);
// Wait until SB flag is set
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
i2c->DR = I2C_7BIT_ADD_READ(address);
// Wait address is acknowledged
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
// Read all bytes except last one
for (count = 0; count < (length - 1); count++) {
value = i2c_byte_read(obj, 0);
data[count] = (char)value;
}
// If not repeated start, send stop.
// Warning: must be done BEFORE the data is read.
if (stop) {
i2c_stop(obj);
}
// Read the last byte
value = i2c_byte_read(obj, 1);
data[count] = (char)value;
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
i2c_start(obj);
// Wait until SB flag is set
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
i2c->DR = I2C_7BIT_ADD_WRITE(address);
// Wait address is acknowledged
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
for (count = 0; count < length; count++) {
if (i2c_byte_write(obj, data[count]) != 1) {
i2c_stop(obj);
return -1;
}
}
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
}
return count;
}
int i2c_byte_read(i2c_t *obj, int last)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
if (last) {
// Don't acknowledge the last byte
i2c->CR1 &= ~I2C_CR1_ACK;
} else {
// Acknowledge the byte
i2c->CR1 |= I2C_CR1_ACK;
}
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->DR;
}
int i2c_byte_write(i2c_t *obj, int data)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
i2c->DR = (uint8_t)data;
// Wait until the byte is transmitted
timeout = FLAG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) &&
(__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == RESET)) {
if ((timeout--) == 0) {
return 0;
}
}
return 1;
}
void i2c_reset(i2c_t *obj)
{
int timeout;
// wait before reset
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
if (obj->i2c == I2C_2) {
__I2C2_FORCE_RESET();
__I2C2_RELEASE_RESET();
}
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg = 0;
// Get the old register value
tmpreg = i2c->OAR1;
// Reset address bits
tmpreg &= 0xFC00;
// Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value
i2c->OAR1 = tmpreg;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
if (enable_slave) {
obj->slave = 1;
/* Enable Address Acknowledge */
I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
}
}
// See I2CSlave.h
#define NoData 0 // the slave has not been addressed
#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj)
{
int retValue = NoData;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TRA) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
uint32_t Timeout;
int size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
while (length > 0) {
/* Wait until RXNE flag is set */
// Wait until the byte is received
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
/* Read data from DR */
(*data++) = I2cHandle.Instance->DR;
length--;
size++;
if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
/* Read data from DR */
(*data++) = I2cHandle.Instance->DR;
length--;
size++;
}
}
/* Wait until STOP flag is set */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
/* Clear STOP flag */
__HAL_I2C_CLEAR_STOPFLAG(&I2cHandle);
/* Wait until BUSY flag is reset */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
uint32_t Timeout;
int size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
while (length > 0) {
/* Wait until TXE flag is set */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
/* Write data to DR */
I2cHandle.Instance->DR = (*data++);
length--;
size++;
if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
/* Write data to DR */
I2cHandle.Instance->DR = (*data++);
length--;
size++;
}
}
/* Wait until AF flag is set */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_AF) == RESET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
/* Clear AF flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
/* Wait until BUSY flag is reset */
Timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
Timeout--;
if (Timeout == 0) {
return -1;
}
}
I2cHandle.State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(&I2cHandle);
return size;
}
#endif // DEVICE_I2CSLAVE
#endif // DEVICE_I2C

View File

@ -0,0 +1,48 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_I2C_DEVICE_H
#define MBED_I2C_DEVICE_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEVICE_I2C
/* Define IP version */
#define I2C_IP_VERSION_V1
#define I2C_IT_ALL (I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR)
#endif // DEVICE_I2C
#endif

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -66,11 +66,6 @@ struct dac_s {
uint32_t channel;
};
struct i2c_s {
I2CName i2c;
uint32_t slave;
};
struct can_s {
CANName can;
int index;

View File

@ -82,6 +82,34 @@ struct serial_s {
#endif
};
struct i2c_s {
/* The 1st 2 members I2CName i2c
* and I2C_HandleTypeDef handle should
* be kept as the first members of this struct
* to ensure i2c_get_obj to work as expected
*/
I2CName i2c;
I2C_HandleTypeDef handle;
uint8_t index;
int hz;
PinName sda;
PinName scl;
IRQn_Type event_i2cIRQ;
IRQn_Type error_i2cIRQ;
uint32_t XferOperation;
volatile uint8_t event;
#if DEVICE_I2CSLAVE
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
uint8_t stop;
uint8_t available_events;
#endif
};
#include "gpio_object.h"
#ifdef __cplusplus

View File

@ -2571,7 +2571,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = XferOptions;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferISR = I2C_Master_ISR_IT;
/* If size > MAX_NBYTE_SIZE, use reload mode */
@ -2584,15 +2584,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c,
{
hi2c->XferSize = hi2c->XferCount;
xfermode = hi2c->XferOptions;
/* If transfer direction not change, do not generate Restart Condition */
/* Mean Previous state is same as current state */
if(hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_TX)
{
xferrequest = I2C_NO_STARTSTOP;
}
}
/* Send Slave Address and set NBYTES to write */
I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, xferrequest);
@ -2644,7 +2636,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = XferOptions;
hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE));
hi2c->XferISR = I2C_Master_ISR_IT;
/* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
@ -2657,13 +2649,6 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c,
{
hi2c->XferSize = hi2c->XferCount;
xfermode = hi2c->XferOptions;
/* If transfer direction not change, do not generate Restart Condition */
/* Mean Previous state is same as current state */
if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX)
{
xferrequest = I2C_NO_STARTSTOP;
}
}
/* Send Slave Address and set NBYTES to read */

View File

@ -1,465 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#if DEVICE_I2C
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x1000)
#define LONG_TIMEOUT ((int)0x8000)
I2C_HandleTypeDef I2cHandle;
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
static int i2c1_inited = 0;
#if defined(I2C2_BASE)
static int i2c2_inited = 0;
#endif
#if defined(I2C3_BASE)
static int i2c3_inited = 0;
#endif
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C1 clock and pinout if not done
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
__HAL_RCC_I2C1_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#if defined(I2C2_BASE)
// Enable I2C2 clock and pinout if not done
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__HAL_RCC_I2C2_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
#if defined(I2C3_BASE)
// Enable I2C3 clock and pinout if not done
if ((obj->i2c == I2C_3) && !i2c3_inited) {
i2c3_inited = 1;
__HAL_RCC_I2C3_CLK_ENABLE();
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
#endif
// Reset to clear pending flags if any
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
}
void i2c_frequency(i2c_t *obj, int hz)
{
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
// wait before init
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Update the SystemCoreClock variable.
SystemCoreClockUpdate();
if (SystemCoreClock == 80000000) {
// Common settings: I2C clock = 80 MHz, Analog filter = ON, Digital filter coefficient = 0
switch (hz) {
case 100000:
I2cHandle.Init.Timing = 0x30C14E6B; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
break;
case 400000:
I2cHandle.Init.Timing = 0x10D1143A; // Fast mode with Rise Time = 250ns and Fall Time = 100ns
break;
case 1000000:
I2cHandle.Init.Timing = 0x00810E27; // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
break;
default:
break;
}
} else if (SystemCoreClock == 48000000) {
// Common settings: I2C clock = 48 MHz, Analog filter = ON, Digital filter coefficient = 0
switch (hz) {
case 100000:
I2cHandle.Init.Timing = 0x20A03E55; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
break;
case 400000:
I2cHandle.Init.Timing = 0x10800C21; // Fast mode with Rise Time = 250ns and Fall Time = 100ns
break;
case 1000000:
I2cHandle.Init.Timing = 0x00500816; // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
break;
default:
break;
}
}
// Enable the Fast Mode Plus capability
if (hz == 1000000) {
if (obj->i2c == I2C_1) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C1);
}
#if defined(I2C2_BASE)
if (obj->i2c == I2C_2) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C2);
}
#endif
#if defined(I2C3_BASE)
if (obj->i2c == I2C_3) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C3);
}
#endif
}
// I2C configuration
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0;
I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
if (HAL_I2C_Init(&I2cHandle) != HAL_OK) {
error("Cannot initialize I2C\n");
}
}
inline int i2c_start(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Wait the STOP condition has been previously correctly sent
timeout = FLAG_TIMEOUT;
while ((i2c->CR2 & I2C_CR2_STOP) == I2C_CR2_STOP){
if ((timeout--) == 0) {
return 1;
}
}
// Generate the START condition
i2c->CR2 |= I2C_CR2_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
inline int i2c_stop(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
i2c->CR2 |= I2C_CR2_STOP;
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
int value;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ);
// Read all bytes
for (count = 0; count < length; count++) {
value = i2c_byte_read(obj, 0);
data[count] = (char)value;
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE);
for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]);
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return count;
}
int i2c_byte_read(i2c_t *obj, int last)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->RXDR;
}
int i2c_byte_write(i2c_t *obj, int data)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the previous byte is transmitted
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) {
if ((timeout--) == 0) {
return 0;
}
}
i2c->TXDR = (uint8_t)data;
return 1;
}
void i2c_reset(i2c_t *obj)
{
int timeout;
// wait before reset
timeout = LONG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
if (obj->i2c == I2C_1) {
__HAL_RCC_I2C1_FORCE_RESET();
__HAL_RCC_I2C1_RELEASE_RESET();
}
#if defined(I2C2_BASE)
if (obj->i2c == I2C_2) {
__HAL_RCC_I2C2_FORCE_RESET();
__HAL_RCC_I2C2_RELEASE_RESET();
}
#endif
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// disable
i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
// Get the old register value
tmpreg = i2c->OAR1;
// Reset address bits
tmpreg &= 0xFC00;
// Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value
i2c->OAR1 = tmpreg;
// enable
i2c->OAR1 |= I2C_OAR1_OA1EN;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// Get the old register value
tmpreg = i2c->OAR1;
// Enable / disable slave
if (enable_slave == 1) {
tmpreg |= I2C_OAR1_OA1EN;
} else {
tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
}
// Set new mode
i2c->OAR1 = tmpreg;
}
// See I2CSlave.h
#define NoData 0 // the slave has not been addressed
#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj)
{
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int retValue = NoData;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_DIR) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
char size = 0;
while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
char size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
do {
i2c_byte_write(obj, data[size]);
size++;
} while (size < length);
return size;
}
#endif // DEVICE_I2CSLAVE
#endif // DEVICE_I2C

View File

@ -0,0 +1,95 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_I2C_DEVICE_H
#define MBED_I2C_DEVICE_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEVICE_I2C
#define I2C_IP_VERSION_V2
#define I2C_IT_ALL (I2C_IT_ERRI|I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_NACKI|I2C_IT_ADDRI|I2C_IT_RXI|I2C_IT_TXI)
/* Family specifc settings for clock source */
#define I2CAPI_I2C1_CLKSRC RCC_I2C1CLKSOURCE_SYSCLK
#define I2CAPI_I2C2_CLKSRC RCC_I2C2CLKSOURCE_SYSCLK
#define I2CAPI_I2C3_CLKSRC RCC_I2C3CLKSOURCE_SYSCLK
#define I2CAPI_I2C4_CLKSRC RCC_I2C4CLKSOURCE_SYSCLK
/* Provide the suitable timing depending on requested frequencie */
inline uint32_t get_i2c_timing(int hz)
{
uint32_t tim = 0;
if (SystemCoreClock == 80000000) {
// Common settings: I2C clock = 80 MHz, Analog filter = ON, Digital filter coefficient = 0
switch (hz) {
case 100000:
tim = 0x30C14E6B; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
break;
case 400000:
tim = 0x10D1143A; // Fast mode with Rise Time = 250ns and Fall Time = 100ns
break;
case 1000000:
tim = 0x00810E27; // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
break;
default:
break;
}
} else if (SystemCoreClock == 48000000) {
// Common settings: I2C clock = 48 MHz, Analog filter = ON, Digital filter coefficient = 0
switch (hz) {
case 100000:
tim = 0x20A03E55; // Standard mode with Rise Time = 400ns and Fall Time = 100ns
break;
case 400000:
tim = 0x10800C21; // Fast mode with Rise Time = 250ns and Fall Time = 100ns
break;
case 1000000:
tim = 0x00500816; // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns
break;
default:
break;
}
}
return tim;
}
#ifdef __cplusplus
}
#endif
#endif // DEVICE_I2C
#endif

View File

@ -27,6 +27,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#include "platform/wait_api.h"
@ -36,6 +38,9 @@
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
/* F1 HAL not ready to move to I2C common code - this is ongoing */
#if !defined(__STM32F1xx_HAL_H)
#include "i2c_device.h" // family specific defines
#ifndef DEBUG_STDIO
# define DEBUG_STDIO 0
@ -48,43 +53,52 @@
# define DEBUG_PRINTF(...) {}
#endif
/* Timeout values are based on core clock and I2C clock.
The BYTE_TIMEOUT is computed as twice the number of cycles it would
take to send 10 bits over I2C. Most Flags should take less than that.
This is for immediate FLAG or ACK check.
*/
#define BYTE_TIMEOUT ((SystemCoreClock / handle->Init.ClockSpeed) * 2 * 10)
/* Timeout values based on I2C clock.
The BYTE_TIMEOUT_US is computed as 3x the time in us it would
take to send 10 bits over I2C. Most Flags should take less than that.
This is for complete transfers check.
*/
#define BYTE_TIMEOUT_US ((SystemCoreClock / handle->Init.ClockSpeed) * 3 * 10)
#if DEVICE_I2C_ASYNCH
#define I2C_S(obj) (struct i2c_s *) (&((obj)->i2c))
#else
#define I2C_S(obj) (struct i2c_s *) (obj)
#endif
/* could be defined at family level */
/* Family specific description for I2C */
#define I2C_NUM (5)
static I2C_HandleTypeDef* i2c_handles[I2C_NUM];
/* Timeout values are based on core clock and I2C clock.
The BYTE_TIMEOUT is computed as twice the number of cycles it would
take to send 10 bits over I2C. Most Flags should take less than that.
This is for immediate FLAG or ACK check.
*/
#define BYTE_TIMEOUT ((SystemCoreClock / obj_s->hz) * 2 * 10)
/* Timeout values based on I2C clock.
The BYTE_TIMEOUT_US is computed as 3x the time in us it would
take to send 10 bits over I2C. Most Flags should take less than that.
This is for complete transfers check.
*/
#define BYTE_TIMEOUT_US ((SystemCoreClock / obj_s->hz) * 3 * 10)
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted.
*/
#define FLAG_TIMEOUT ((int)0x1000)
/* GENERIC INIT and HELPERS FUNCTIONS */
#if defined(I2C1_BASE)
static void i2c1_irq(void)
{
I2C_HandleTypeDef * handle = i2c_handles[0];
HAL_I2C_EV_IRQHandler(handle);
HAL_I2C_ER_IRQHandler(handle);
}
#endif
#if defined(I2C2_BASE)
static void i2c2_irq(void)
{
I2C_HandleTypeDef * handle = i2c_handles[1];
HAL_I2C_EV_IRQHandler(handle);
HAL_I2C_ER_IRQHandler(handle);
}
#endif
#if defined(I2C3_BASE)
static void i2c3_irq(void)
{
@ -94,12 +108,12 @@ static void i2c3_irq(void)
}
#endif
#if defined(I2C4_BASE)
static void i2c4_irq(void)
{
I2C_HandleTypeDef * handle = i2c_handles[3];
HAL_I2C_EV_IRQHandler(handle);
HAL_I2C_ER_IRQHandler(handle);
}
static void i2c4_irq(void)
{
I2C_HandleTypeDef * handle = i2c_handles[3];
HAL_I2C_EV_IRQHandler(handle);
HAL_I2C_ER_IRQHandler(handle);
}
#endif
#if defined(FMPI2C1_BASE)
static void i2c5_irq(void)
@ -134,19 +148,23 @@ void i2c_ev_err_disable(i2c_t *obj) {
HAL_NVIC_DisableIRQ(irq_error_n);
}
void i2c_irq_set(i2c_t *obj, uint32_t enable)
uint32_t i2c_get_irq_handler(i2c_t *obj)
{
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
uint32_t handler = 0;
switch (obj_s->index) {
#if defined(I2C1_BASE)
case 0:
handler = (uint32_t)&i2c1_irq;
break;
#endif
#if defined(I2C2_BASE)
case 1:
handler = (uint32_t)&i2c2_irq;
break;
#endif
#if defined(I2C3_BASE)
case 2:
handler = (uint32_t)&i2c3_irq;
@ -164,13 +182,8 @@ void i2c_irq_set(i2c_t *obj, uint32_t enable)
#endif
}
if (enable) {
i2c_handles[obj_s->index] = handle;
i2c_ev_err_enable(obj, handler);
} else { // disable
i2c_ev_err_disable(obj);
i2c_handles[obj_s->index] = 0;
}
i2c_handles[obj_s->index] = handle;
return handler;
}
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
@ -186,6 +199,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
obj_s->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj_s->i2c != (I2CName)NC);
#if defined I2C1_BASE
// Enable I2C1 clock and pinout if not done
if (obj_s->i2c == I2C_1) {
obj_s->index = 0;
@ -196,8 +210,10 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
pin_mode(scl, PullUp);
obj_s->event_i2cIRQ = I2C1_EV_IRQn;
obj_s->error_i2cIRQ = I2C1_ER_IRQn;
__I2C1_CLK_ENABLE();
__HAL_RCC_I2C1_CLK_ENABLE();
}
#endif
#if defined I2C2_BASE
// Enable I2C2 clock and pinout if not done
if (obj_s->i2c == I2C_2) {
obj_s->index = 1;
@ -208,8 +224,9 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
pin_mode(scl, PullUp);
obj_s->event_i2cIRQ = I2C2_EV_IRQn;
obj_s->error_i2cIRQ = I2C2_ER_IRQn;
__I2C2_CLK_ENABLE();
__HAL_RCC_I2C2_CLK_ENABLE();
}
#endif
#if defined I2C3_BASE
// Enable I2C3 clock and pinout if not done
if (obj_s->i2c == I2C_3) {
@ -221,11 +238,11 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
pin_mode(scl, PullUp);
obj_s->event_i2cIRQ = I2C3_EV_IRQn;
obj_s->error_i2cIRQ = I2C3_ER_IRQn;
__I2C3_CLK_ENABLE();
__HAL_RCC_I2C3_CLK_ENABLE();
}
#endif
#if defined I2C4_BASE
// Enable clock and pinout if not done
// Enable I2C3 clock and pinout if not done
if (obj_s->i2c == I2C_4) {
obj_s->index = 3;
// Configure I2C pins
@ -235,13 +252,13 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
pin_mode(scl, PullUp);
obj_s->event_i2cIRQ = I2C4_EV_IRQn;
obj_s->error_i2cIRQ = I2C4_ER_IRQn;
__I2C4_CLK_ENABLE();
__HAL_RCC_I2C4_CLK_ENABLE();
}
#endif
#if defined FMPI2C1_BASE
// Enable clock and pinout if not done
// Enable I2C3 clock and pinout if not done
if (obj_s->i2c == FMPI2C_1) {
obj_s->index = 3;
obj_s->index = 4;
// Configure I2C pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
@ -257,7 +274,9 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
if(!obj_s->hz)
obj_s->hz = 100000; // 100 kHz per default
i2c_frequency(obj, obj_s->hz );
#if DEVICE_I2CSLAVE
// I2C master by default
@ -269,41 +288,93 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// I2C Xfer operation init
obj_s->event = 0;
obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME;
/* Activate default IRQ handlers for sync mode
* which would be overwritten in async mode
*/
i2c_irq_set(obj, 1);
}
void i2c_frequency(i2c_t *obj, int hz)
{
int timeout;
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
MBED_ASSERT((hz > 0) && (hz <= 400000));
// wait before init
timeout = BYTE_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BUSY)) && (--timeout != 0));
#ifdef I2C_IP_VERSION_V1
handle->Init.ClockSpeed = hz;
handle->Init.DutyCycle = I2C_DUTYCYCLE_2;
#endif
#ifdef I2C_IP_VERSION_V2
/* Only predefined timing for below frequencies are supported */
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
handle->Init.Timing = get_i2c_timing(hz);
// Enable the Fast Mode Plus capability
if (hz == 1000000) {
#if defined(I2C1_BASE) && defined(__HAL_SYSCFG_FASTMODEPLUS_ENABLE) && defined (I2C_FASTMODEPLUS_I2C1)
if (obj_s->i2c == I2C_1) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(I2C_FASTMODEPLUS_I2C1);
}
#endif
#if defined(I2C2_BASE) && defined(__HAL_SYSCFG_FASTMODEPLUS_ENABLE) && defined (I2C_FASTMODEPLUS_I2C2)
if (obj_s->i2c == I2C_2) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(I2C_FASTMODEPLUS_I2C2);
}
#endif
#if defined(I2C3_BASE) && defined(__HAL_SYSCFG_FASTMODEPLUS_ENABLE) && defined (I2C_FASTMODEPLUS_I2C3)
if (obj_s->i2c == I2C_3) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(I2C_FASTMODEPLUS_I2C3);
}
#endif
#if defined(I2C4_BASE) && defined(__HAL_SYSCFG_FASTMODEPLUS_ENABLE) && defined (I2C_FASTMODEPLUS_I2C4)
if (obj_s->i2c == I2C_4) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(I2C_FASTMODEPLUS_I2C4);
}
#endif
}
#endif //I2C_IP_VERSION_V2
/*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
#if defined(I2C1_BASE) && defined (__HAL_RCC_I2C1_CONFIG)
if (obj_s->i2c == I2C_1) {
__HAL_RCC_I2C1_CONFIG(I2CAPI_I2C1_CLKSRC);
}
#endif
#if defined(I2C2_BASE) && defined(__HAL_RCC_I2C2_CONFIG)
if (obj_s->i2c == I2C_2) {
__HAL_RCC_I2C2_CONFIG(I2CAPI_I2C2_CLKSRC);
}
#endif
#if defined(I2C3_BASE) && defined(__HAL_RCC_I2C3_CONFIG)
if (obj_s->i2c == I2C_3) {
__HAL_RCC_I2C3_CONFIG(I2CAPI_I2C3_CLKSRC);
}
#endif
#if defined(I2C4_BASE) && defined(__HAL_RCC_I2C4_CONFIG)
if (obj_s->i2c == I2C_4) {
__HAL_RCC_I2C4_CONFIG(I2CAPI_I2C4_CLKSRC);
}
#endif
#ifdef I2C_ANALOGFILTER_ENABLE
/* Enable the Analog I2C Filter */
HAL_I2CEx_AnalogFilter_Config(handle,I2C_ANALOGFILTER_ENABLE);
#endif
// I2C configuration
handle->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
handle->Init.ClockSpeed = hz;
handle->Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
handle->Init.DutyCycle = I2C_DUTYCYCLE_2;
handle->Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
handle->Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
handle->Init.OwnAddress1 = 0;
handle->Init.OwnAddress2 = 0;
HAL_I2C_Init(handle);
/* store frequency for timeout computation */
obj_s->hz = hz;
}
i2c_t *get_i2c_obj(I2C_HandleTypeDef *hi2c){
/* Aim of the function is to get i2c_s pointer using hi2c pointer */
/* Highly inspired from magical linux kernel's "container_of" */
/* (which was not directly used since not compatible with IAR toolchain) */
@ -316,47 +387,50 @@ i2c_t *get_i2c_obj(I2C_HandleTypeDef *hi2c){
return (obj);
}
inline int i2c_start(i2c_t *obj) {
void i2c_reset(i2c_t *obj) {
int timeout;
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(handle, I2C_FLAG_AF);
handle->Instance = (I2C_TypeDef *)(obj_s->i2c);
// Wait the STOP condition has been previously correctly sent
// This timeout can be avoid in some specific cases by simply clearing the STOP bit
// wait before reset
timeout = BYTE_TIMEOUT;
while ((handle->Instance->CR1 & I2C_CR1_STOP) == I2C_CR1_STOP) {
if ((timeout--) == 0) {
return 1;
}
while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BUSY)) && (--timeout != 0));
#if defined I2C1_BASE
if (obj_s->i2c == I2C_1) {
__HAL_RCC_I2C1_FORCE_RESET();
__HAL_RCC_I2C1_RELEASE_RESET();
}
// Generate the START condition
handle->Instance->CR1 |= I2C_CR1_START;
// Wait the START condition has been correctly sent
timeout = BYTE_TIMEOUT;
while (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_SB) == RESET) {
if ((timeout--) == 0) {
return 1;
}
#endif
#if defined I2C2_BASE
if (obj_s->i2c == I2C_2) {
__HAL_RCC_I2C2_FORCE_RESET();
__HAL_RCC_I2C2_RELEASE_RESET();
}
return 0;
#endif
#if defined I2C3_BASE
if (obj_s->i2c == I2C_3) {
__HAL_RCC_I2C3_FORCE_RESET();
__HAL_RCC_I2C3_RELEASE_RESET();
}
#endif
#if defined I2C4_BASE
if (obj_s->i2c == I2C_4) {
__HAL_RCC_I2C4_FORCE_RESET();
__HAL_RCC_I2C4_RELEASE_RESET();
}
#endif
#if defined FMPI2C1_BASE
if (obj_s->i2c == FMPI2C_1) {
__HAL_RCC_FMPI2C1_FORCE_RESET();
__HAL_RCC_FMPI2C1_RELEASE_RESET();
}
#endif
}
inline int i2c_stop(i2c_t *obj) {
struct i2c_s *obj_s = I2C_S(obj);
I2C_TypeDef *i2c = (I2C_TypeDef *)obj_s->i2c;
// Generate the STOP condition
i2c->CR1 |= I2C_CR1_STOP;
return 0;
}
/* SYNCHRONOUS API FUNCTIONS */
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
struct i2c_s *obj_s = I2C_S(obj);
@ -379,6 +453,12 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
}
obj_s->event = 0;
/* Activate default IRQ handlers for sync mode
* which would be overwritten in async mode
*/
i2c_ev_err_enable(obj, i2c_get_irq_handler(obj));
ret = HAL_I2C_Master_Sequential_Receive_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation);
if(ret == HAL_OK) {
@ -388,6 +468,8 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
wait_us(1);
}
i2c_ev_err_disable(obj);
if((timeout == 0) || (obj_s->event != I2C_EVENT_TRANSFER_COMPLETE)) {
DEBUG_PRINTF(" TIMEOUT or error in i2c_read\r\n");
/* re-init IP to try and get back in a working state */
@ -402,6 +484,187 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
return count;
}
/*
* UNITARY APIS.
* For very basic operations, direct registers access is needed
* There are 2 different IPs version that need to be supported
*/
#ifdef I2C_IP_VERSION_V1
int i2c_start(i2c_t *obj) {
int timeout;
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(handle, I2C_FLAG_AF);
// Wait the STOP condition has been previously correctly sent
// This timeout can be avoid in some specific cases by simply clearing the STOP bit
timeout = FLAG_TIMEOUT;
while ((handle->Instance->CR1 & I2C_CR1_STOP) == I2C_CR1_STOP) {
if ((timeout--) == 0) {
return 1;
}
}
// Generate the START condition
handle->Instance->CR1 |= I2C_CR1_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_SB) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
int i2c_stop(i2c_t *obj) {
struct i2c_s *obj_s = I2C_S(obj);
I2C_TypeDef *i2c = (I2C_TypeDef *)obj_s->i2c;
// Generate the STOP condition
i2c->CR1 |= I2C_CR1_STOP;
return 0;
}
int i2c_byte_read(i2c_t *obj, int last) {
int timeout;
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
if (last) {
// Don't acknowledge the last byte
handle->Instance->CR1 &= ~I2C_CR1_ACK;
} else {
// Acknowledge the byte
handle->Instance->CR1 |= I2C_CR1_ACK;
}
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)handle->Instance->DR;
}
int i2c_byte_write(i2c_t *obj, int data) {
int timeout;
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
handle->Instance->DR = (uint8_t)data;
// Wait until the byte (might be the address) is transmitted
timeout = FLAG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_TXE) == RESET) &&
(__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BTF) == RESET) &&
(__HAL_I2C_GET_FLAG(handle, I2C_FLAG_ADDR) == RESET)) {
if ((timeout--) == 0) {
return 0;
}
}
if (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_ADDR) != RESET)
{
__HAL_I2C_CLEAR_ADDRFLAG(handle);
}
return 1;
}
#endif //I2C_IP_VERSION_V1
#ifdef I2C_IP_VERSION_V2
int i2c_start(i2c_t *obj) {
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
I2C_TypeDef *i2c = (I2C_TypeDef *)obj_s->i2c;
int timeout;
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(handle, I2C_FLAG_AF);
// Wait the STOP condition has been previously correctly sent
timeout = FLAG_TIMEOUT;
while ((i2c->CR2 & I2C_CR2_STOP) == I2C_CR2_STOP){
if ((timeout--) == 0) {
return 1;
}
}
// Generate the START condition
i2c->CR2 |= I2C_CR2_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BUSY) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
int i2c_stop(i2c_t *obj) {
struct i2c_s *obj_s = I2C_S(obj);
I2C_TypeDef *i2c = (I2C_TypeDef *)obj_s->i2c;
// Generate the STOP condition
i2c->CR2 |= I2C_CR2_STOP;
return 0;
}
int i2c_byte_read(i2c_t *obj, int last) {
struct i2c_s *obj_s = I2C_S(obj);
I2C_TypeDef *i2c = (I2C_TypeDef *)obj_s->i2c;
I2C_HandleTypeDef *handle = &(obj_s->handle);
int timeout;
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->RXDR;
}
int i2c_byte_write(i2c_t *obj, int data) {
struct i2c_s *obj_s = I2C_S(obj);
I2C_TypeDef *i2c = (I2C_TypeDef *)obj_s->i2c;
I2C_HandleTypeDef *handle = &(obj_s->handle);
int timeout;
// Wait until the previous byte is transmitted
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_TXIS) == RESET) {
if ((timeout--) == 0) {
return 0;
}
}
i2c->TXDR = (uint8_t)data;
return 1;
}
#endif //I2C_IP_VERSION_V2
/*
* SYNC APIS
*/
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
@ -424,6 +687,8 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
obj_s->event = 0;
i2c_ev_err_enable(obj, i2c_get_irq_handler(obj));
ret = HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *) data, length, obj_s->XferOperation);
if(ret == HAL_OK) {
@ -433,6 +698,8 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
wait_us(1);
}
i2c_ev_err_disable(obj);
if((timeout == 0) || (obj_s->event != I2C_EVENT_TRANSFER_COMPLETE)) {
DEBUG_PRINTF(" TIMEOUT or error in i2c_write\r\n");
/* re-init IP to try and get back in a working state */
@ -447,100 +714,55 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
return count;
}
int i2c_byte_read(i2c_t *obj, int last) {
int timeout;
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c){
/* Get object ptr based on handler ptr */
i2c_t *obj = get_i2c_obj(hi2c);
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
if (last) {
// Don't acknowledge the last byte
handle->Instance->CR1 &= ~I2C_CR1_ACK;
} else {
// Acknowledge the byte
handle->Instance->CR1 |= I2C_CR1_ACK;
}
// Wait until the byte is received
timeout = BYTE_TIMEOUT;
while (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
#if DEVICE_I2C_ASYNCH
/* Handle potential Tx/Rx use case */
if ((obj->tx_buff.length) && (obj->rx_buff.length)) {
if (obj_s->stop) {
obj_s->XferOperation = I2C_LAST_FRAME;
} else {
obj_s->XferOperation = I2C_NEXT_FRAME;
}
}
return (int)handle->Instance->DR;
HAL_I2C_Master_Sequential_Receive_IT(hi2c, obj_s->address, (uint8_t*)obj->rx_buff.buffer , obj->rx_buff.length, obj_s->XferOperation);
}
else
#endif
{
/* Set event flag */
obj_s->event = I2C_EVENT_TRANSFER_COMPLETE;
}
}
int i2c_byte_write(i2c_t *obj, int data) {
int timeout;
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c){
/* Get object ptr based on handler ptr */
i2c_t *obj = get_i2c_obj(hi2c);
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
handle->Instance->DR = (uint8_t)data;
// Wait until the byte (might be the address) is transmitted
timeout = BYTE_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_TXE) == RESET) &&
(__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BTF) == RESET) &&
(__HAL_I2C_GET_FLAG(handle, I2C_FLAG_ADDR) == RESET)) {
if ((timeout--) == 0) {
return 0;
}
}
if (__HAL_I2C_GET_FLAG(handle, I2C_FLAG_ADDR) != RESET)
{
__HAL_I2C_CLEAR_ADDRFLAG(handle);
}
return 1;
/* Set event flag */
obj_s->event = I2C_EVENT_TRANSFER_COMPLETE;
}
void i2c_reset(i2c_t *obj) {
int timeout;
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c){
/* Get object ptr based on handler ptr */
i2c_t *obj = get_i2c_obj(hi2c);
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
handle->Instance = (I2C_TypeDef *)(obj_s->i2c);
DEBUG_PRINTF("HAL_I2C_ErrorCallback:%d, index=%d\r\n", (int) hi2c->ErrorCode, obj_s->index);
// wait before reset
timeout = BYTE_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(handle, I2C_FLAG_BUSY)) && (--timeout != 0));
/* re-init IP to try and get back in a working state */
i2c_init(obj, obj_s->sda, obj_s->scl);
if (obj_s->i2c == I2C_1) {
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
if (obj_s->i2c == I2C_2) {
__I2C2_FORCE_RESET();
__I2C2_RELEASE_RESET();
}
#if defined I2C3_BASE
if (obj_s->i2c == I2C_3) {
__I2C3_FORCE_RESET();
__I2C3_RELEASE_RESET();
}
#endif
#if defined I2C4_BASE
if (obj_s->i2c == I2C_4) {
__I2C4_FORCE_RESET();
__I2C4_RELEASE_RESET();
}
#endif
#if defined FMPI2C1_BASE
if (obj_s->i2c == FMPI2C_1) {
__HAL_RCC_FMPI2C1_FORCE_RESET();
__HAL_RCC_FMPI2C1_RELEASE_RESET();
}
#endif
/* Keep Set event flag */
obj_s->event = I2C_EVENT_ERROR;
}
#if DEVICE_I2CSLAVE
/* SLAVE API FUNCTIONS */
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
struct i2c_s *obj_s = I2C_S(obj);
I2C_HandleTypeDef *handle = &(obj_s->handle);
@ -549,6 +771,8 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
handle->Init.OwnAddress1 = address;
HAL_I2C_Init(handle);
i2c_ev_err_enable(obj, i2c_get_irq_handler(obj));
HAL_I2C_EnableListen_IT(handle);
}
@ -646,7 +870,6 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) {
DEBUG_PRINTF("TIMEOUT or error in i2c_slave_read\r\n");
}
}
return count;
}
@ -675,58 +898,10 @@ int i2c_slave_write(i2c_t *obj, const char *data, int length) {
return count;
}
#endif // DEVICE_I2CSLAVE
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c){
/* Get object ptr based on handler ptr */
i2c_t *obj = get_i2c_obj(hi2c);
struct i2c_s *obj_s = I2C_S(obj);
#if DEVICE_I2C_ASYNCH
/* Handle potential Tx/Rx use case */
if ((obj->tx_buff.length) && (obj->rx_buff.length)) {
if (obj_s->stop) {
obj_s->XferOperation = I2C_LAST_FRAME;
} else {
obj_s->XferOperation = I2C_NEXT_FRAME;
}
HAL_I2C_Master_Sequential_Receive_IT(hi2c, obj_s->address, (uint8_t*)obj->rx_buff.buffer , obj->rx_buff.length, obj_s->XferOperation);
}
else
#endif
{
/* Set event flag */
obj_s->event = I2C_EVENT_TRANSFER_COMPLETE;
}
}
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c){
/* Get object ptr based on handler ptr */
i2c_t *obj = get_i2c_obj(hi2c);
struct i2c_s *obj_s = I2C_S(obj);
/* Set event flag */
obj_s->event = I2C_EVENT_TRANSFER_COMPLETE;
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c){
/* Get object ptr based on handler ptr */
i2c_t *obj = get_i2c_obj(hi2c);
struct i2c_s *obj_s = I2C_S(obj);
DEBUG_PRINTF("HAL_I2C_ErrorCallback:%d, index=%d\r\n", (int) hi2c->ErrorCode, obj_s->index);
/* re-init IP to try and get back in a working state */
i2c_init(obj, obj_s->sda, obj_s->scl);
/* Keep Set event flag */
obj_s->event = I2C_EVENT_ERROR;
}
#if DEVICE_I2C_ASYNCH
/* ASYNCH MASTER API FUNCTIONS */
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c){
/* Get object ptr based on handler ptr */
i2c_t *obj = get_i2c_obj(hi2c);
@ -734,14 +909,13 @@ void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c){
I2C_HandleTypeDef *handle = &(obj_s->handle);
/* Disable IT. Not always done before calling macro */
__HAL_I2C_DISABLE_IT(handle, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
__HAL_I2C_DISABLE_IT(handle, I2C_IT_ALL);
i2c_ev_err_disable(obj);
/* Set event flag */
obj_s->event = I2C_EVENT_ERROR;
}
void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint) {
// TODO: DMA usage is currently ignored by this way
@ -840,7 +1014,8 @@ void i2c_abort_asynch(i2c_t *obj) {
HAL_I2C_Master_Abort_IT(handle, Dummy_DevAddress);
}
#endif // DEVICE_I2C_ASYNCH
#endif // STM32F1
#endif // DEVICE_I2C

View File

@ -640,7 +640,7 @@
"inherits": ["Target"],
"detect_code": ["0725"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"default_lib": "small",
"release_versions": ["2"],
"device_name": "STM32F030R8"
@ -654,7 +654,7 @@
"inherits": ["Target"],
"detect_code": ["0791"],
"macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"default_lib": "small",
"release_versions": ["2"],
"device_name": "STM32F031K6"
@ -668,7 +668,7 @@
"inherits": ["Target"],
"detect_code": ["0785"],
"macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"default_lib": "small",
"release_versions": ["2"],
"device_name": "STM32F042K6"
@ -682,7 +682,7 @@
"inherits": ["Target"],
"detect_code": ["0755"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"release_versions": ["2", "5"],
"device_name": "STM32F070RB"
},
@ -695,7 +695,7 @@
"inherits": ["Target"],
"detect_code": ["0730"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"release_versions": ["2", "5"],
"device_name": "STM32F072RB"
},
@ -708,7 +708,7 @@
"inherits": ["Target"],
"detect_code": ["0750"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"release_versions": ["2", "5"],
"device_name": "STM32F091RC"
},
@ -734,7 +734,7 @@
"inherits": ["Target"],
"detect_code": ["0835"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"features": ["LWIP"],
"release_versions": ["2", "5"],
"device_name" : "STM32F207ZG"
@ -748,7 +748,7 @@
"inherits": ["Target"],
"detect_code": ["0705"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"default_lib": "small",
"release_versions": ["2"],
"device_name": "STM32F302R8"
@ -763,7 +763,7 @@
"inherits": ["Target"],
"detect_code": ["0775"],
"default_lib": "small",
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"release_versions": ["2"],
"device_name": "STM32F303K8"
},
@ -776,7 +776,7 @@
"inherits": ["Target"],
"detect_code": ["0745"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"release_versions": ["2", "5"],
"device_name": "STM32F303RE"
},
@ -789,7 +789,7 @@
"inherits": ["Target"],
"detect_code": ["0747"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "LOWPOWERTIMER"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "LOWPOWERTIMER"],
"release_versions": ["2", "5"],
"device_name": "STM32F303ZE"
},
@ -802,7 +802,7 @@
"inherits": ["Target"],
"detect_code": ["0735"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"default_lib": "small",
"release_versions": ["2"],
"device_name": "STM32F334R8"
@ -938,7 +938,7 @@
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"supported_form_factors": ["ARDUINO"],
"detect_code": ["0816"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"features": ["LWIP"],
"release_versions": ["2", "5"],
"device_name": "STM32F746ZG"
@ -951,7 +951,7 @@
"default_toolchain": "ARM",
"supported_form_factors": ["ARDUINO"],
"detect_code": ["0819"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"],
"features": ["LWIP"],
"release_versions": ["2", "5"],
"device_name": "STM32F756ZG"
@ -965,7 +965,7 @@
"supported_form_factors": ["ARDUINO"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"detect_code": ["0818"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"features": ["LWIP"],
"release_versions": ["2", "5"],
"device_name" : "STM32F767ZI"
@ -978,7 +978,7 @@
"default_toolchain": "uARM",
"supported_form_factors": ["ARDUINO"],
"detect_code": ["0780"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"default_lib": "small",
"release_versions": ["2"],
"device_name": "STM32L011K4"
@ -991,7 +991,7 @@
"default_toolchain": "uARM",
"supported_form_factors": ["ARDUINO"],
"detect_code": ["0790"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"default_lib": "small",
"release_versions": ["2"],
"device_name": "STM32L031K6"
@ -1004,7 +1004,7 @@
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"],
"inherits": ["Target"],
"detect_code": ["0715"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"default_lib": "small",
"release_versions": ["2"],
"device_name": "STM32L053R8"
@ -1017,7 +1017,7 @@
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"],
"inherits": ["Target"],
"detect_code": ["0760"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"release_versions": ["2", "5"],
"device_name": "STM32L073RZ"
},
@ -1029,7 +1029,7 @@
"supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"],
"inherits": ["Target"],
"detect_code": ["0710"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"release_versions": ["2", "5"],
"device_name": "STM32L152RE"
},
@ -1042,7 +1042,7 @@
"inherits": ["Target"],
"detect_code": ["0770"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "CAN", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "CAN", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"release_versions": ["2", "5"],
"device_name" : "STM32L432KC"
},
@ -1055,7 +1055,7 @@
"inherits": ["Target"],
"detect_code": ["0765"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"release_versions": ["2", "5"],
"device_name": "stm32l476rg"
},
@ -1067,7 +1067,7 @@
"supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"],
"inherits": ["Target"],
"detect_code": ["0827"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"release_versions": ["2", "5"],
"device_name": "stm32l486rg"
},
@ -1104,7 +1104,7 @@
"extra_labels": ["STM", "STM32F0", "STM32F051", "STM32F051R8"],
"supported_toolchains": ["GCC_ARM"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_name": "STM32F051R8"
},
"DISCO_F100RB": {
@ -1114,7 +1114,7 @@
"extra_labels": ["STM", "STM32F1", "STM32F100RB"],
"supported_toolchains": ["GCC_ARM"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_name": "STM32F100RB"
},
"DISCO_F303VC": {
@ -1124,7 +1124,7 @@
"extra_labels": ["STM", "STM32F3", "STM32F303", "STM32F303VC"],
"macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"],
"supported_toolchains": ["GCC_ARM"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_name": "STM32F303VC"
},
"DISCO_F334C8": {
@ -1135,7 +1135,7 @@
"macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"],
"supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"],
"detect_code": ["0810"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"default_lib": "small",
"release_versions": ["2"],
"device_name": "STM32F334C8"
@ -1146,7 +1146,7 @@
"extra_labels": ["STM", "STM32F4", "STM32F407", "STM32F407VG"],
"supported_toolchains": ["ARM", "uARM", "GCC_ARM"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2", "USB_STM_HAL"],
"device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_name": "STM32F407VG"
},
"DISCO_F429ZI": {
@ -1194,7 +1194,7 @@
"supported_form_factors": ["ARDUINO"],
"detect_code": ["0815"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"features": ["LWIP"],
"release_versions": ["2", "5"],
"device_name": "STM32F746NG"
@ -1207,7 +1207,7 @@
"default_toolchain": "ARM",
"detect_code": ["0817"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"features": ["LWIP"],
"release_versions": ["2"],
"device_name": "STM32F769NI"
@ -1220,7 +1220,7 @@
"supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"],
"detect_code": ["0820"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"],
"release_versions": ["2", "5"],
"device_name": "stm32l476vg"
},
@ -1295,7 +1295,7 @@
"extra_labels": ["STM", "STM32F4", "STM32F401", "STM32F401VC"],
"supported_toolchains": ["GCC_ARM"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"device_has": ["ANALOGIN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
"device_name": "STM32F401VC"
},
"UBLOX_EVK_ODIN_W2": {