1 /*!
2 * \file i2c-board.c
3 *
4 * \brief Target board I2C driver implementation
5 *
6 * \copyright Revised BSD License, see section \ref LICENSE.
7 *
8 * \code
9 * ______ _
10 * / _____) _ | |
11 * ( (____ _____ ____ _| |_ _____ ____| |__
12 * \____ \| ___ | (_ _) ___ |/ ___) _ \
13 * _____) ) ____| | | || |_| ____( (___| | | |
14 * (______/|_____)_|_|_| \__)_____)\____)_| |_|
15 * (C)2013-2017 Semtech
16 *
17 * \endcode
18 *
19 * \author Miguel Luis ( Semtech )
20 *
21 * \author Gregory Cristian ( Semtech )
22 */
23 #include "stm32l1xx.h"
24 #include "utilities.h"
25 #include "board-config.h"
26 #include "i2c-board.h"
27
28 /*!
29 * The value of the maximal timeout for I2C waiting loops
30 */
31 #define TIMEOUT_MAX 0x8000
32
33 static I2C_HandleTypeDef I2cHandle = { 0 };
34
35 static I2cAddrSize I2cInternalAddrSize = I2C_ADDR_SIZE_8;
36
I2cMcuInit(I2c_t * obj,I2cId_t i2cId,PinNames scl,PinNames sda)37 void I2cMcuInit( I2c_t *obj, I2cId_t i2cId, PinNames scl, PinNames sda )
38 {
39 __HAL_RCC_I2C1_CLK_DISABLE( );
40 __HAL_RCC_I2C1_CLK_ENABLE( );
41 __HAL_RCC_I2C1_FORCE_RESET( );
42 __HAL_RCC_I2C1_RELEASE_RESET( );
43
44 obj->I2cId = i2cId;
45
46 I2cHandle.Instance = ( I2C_TypeDef * )I2C1_BASE;
47
48 GpioInit( &obj->Scl, scl, PIN_ALTERNATE_FCT, PIN_OPEN_DRAIN, PIN_NO_PULL, GPIO_AF4_I2C1 );
49 GpioInit( &obj->Sda, sda, PIN_ALTERNATE_FCT, PIN_OPEN_DRAIN, PIN_NO_PULL, GPIO_AF4_I2C1 );
50 }
51
I2cMcuFormat(I2c_t * obj,I2cMode mode,I2cDutyCycle dutyCycle,bool I2cAckEnable,I2cAckAddrMode AckAddrMode,uint32_t I2cFrequency)52 void I2cMcuFormat( I2c_t *obj, I2cMode mode, I2cDutyCycle dutyCycle, bool I2cAckEnable, I2cAckAddrMode AckAddrMode, uint32_t I2cFrequency )
53 {
54 __HAL_RCC_I2C1_CLK_ENABLE( );
55
56 I2cHandle.Init.ClockSpeed = I2cFrequency;
57
58 if( dutyCycle == I2C_DUTY_CYCLE_2 )
59 {
60 I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
61 }
62 else
63 {
64 I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_16_9;
65 }
66
67 I2cHandle.Init.OwnAddress1 = 0;
68 I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
69 I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
70 I2cHandle.Init.OwnAddress2 = 0;
71 I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
72 I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
73
74 HAL_I2C_Init( &I2cHandle );
75 }
76
I2cMcuResetBus(I2c_t * obj)77 void I2cMcuResetBus( I2c_t *obj )
78 {
79 __HAL_RCC_I2C1_CLK_DISABLE( );
80 __HAL_RCC_I2C1_CLK_ENABLE( );
81 __HAL_RCC_I2C1_FORCE_RESET( );
82 __HAL_RCC_I2C1_RELEASE_RESET( );
83
84 GpioInit( &obj->Scl, I2C_SCL, PIN_ALTERNATE_FCT, PIN_OPEN_DRAIN, PIN_NO_PULL, GPIO_AF4_I2C1 );
85 GpioInit( &obj->Sda, I2C_SDA, PIN_ALTERNATE_FCT, PIN_OPEN_DRAIN, PIN_NO_PULL, GPIO_AF4_I2C1 );
86
87 I2cMcuFormat( obj, MODE_I2C, I2C_DUTY_CYCLE_2, true, I2C_ACK_ADD_7_BIT, 400000 );
88 }
89
I2cMcuDeInit(I2c_t * obj)90 void I2cMcuDeInit( I2c_t *obj )
91 {
92
93 HAL_I2C_DeInit( &I2cHandle );
94
95 __HAL_RCC_I2C1_FORCE_RESET();
96 __HAL_RCC_I2C1_RELEASE_RESET();
97 __HAL_RCC_I2C1_CLK_DISABLE( );
98
99 GpioInit( &obj->Scl, obj->Scl.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
100 GpioInit( &obj->Sda, obj->Sda.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
101 }
102
I2cSetAddrSize(I2c_t * obj,I2cAddrSize addrSize)103 void I2cSetAddrSize( I2c_t *obj, I2cAddrSize addrSize )
104 {
105 I2cInternalAddrSize = addrSize;
106 }
107
I2cMcuWriteBuffer(I2c_t * obj,uint8_t deviceAddr,uint8_t * buffer,uint16_t size)108 LmnStatus_t I2cMcuWriteBuffer( I2c_t *obj, uint8_t deviceAddr, uint8_t *buffer, uint16_t size )
109 {
110 LmnStatus_t status = LMN_STATUS_ERROR;
111
112 status = ( HAL_I2C_Master_Transmit( &I2cHandle, deviceAddr, buffer, size, 2000 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
113
114 return status;
115 }
116
I2cMcuReadBuffer(I2c_t * obj,uint8_t deviceAddr,uint8_t * buffer,uint16_t size)117 LmnStatus_t I2cMcuReadBuffer( I2c_t *obj, uint8_t deviceAddr, uint8_t *buffer, uint16_t size )
118 {
119 LmnStatus_t status = LMN_STATUS_ERROR;
120
121 status = ( HAL_I2C_Master_Receive( &I2cHandle, deviceAddr, buffer, size, 2000 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
122
123 return status;
124 }
125
I2cMcuWriteMemBuffer(I2c_t * obj,uint8_t deviceAddr,uint16_t addr,uint8_t * buffer,uint16_t size)126 LmnStatus_t I2cMcuWriteMemBuffer( I2c_t *obj, uint8_t deviceAddr, uint16_t addr, uint8_t *buffer, uint16_t size )
127 {
128 LmnStatus_t status = LMN_STATUS_ERROR;
129 uint16_t memAddSize = 0;
130
131 if( I2cInternalAddrSize == I2C_ADDR_SIZE_8 )
132 {
133 memAddSize = I2C_MEMADD_SIZE_8BIT;
134 }
135 else
136 {
137 memAddSize = I2C_MEMADD_SIZE_16BIT;
138 }
139 status = ( HAL_I2C_Mem_Write( &I2cHandle, deviceAddr, addr, memAddSize, buffer, size, 2000 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
140
141 return status;
142 }
143
I2cMcuReadMemBuffer(I2c_t * obj,uint8_t deviceAddr,uint16_t addr,uint8_t * buffer,uint16_t size)144 LmnStatus_t I2cMcuReadMemBuffer( I2c_t *obj, uint8_t deviceAddr, uint16_t addr, uint8_t *buffer, uint16_t size )
145 {
146 LmnStatus_t status = LMN_STATUS_ERROR;
147 uint16_t memAddSize = 0;
148
149 if( I2cInternalAddrSize == I2C_ADDR_SIZE_8 )
150 {
151 memAddSize = I2C_MEMADD_SIZE_8BIT;
152 }
153 else
154 {
155 memAddSize = I2C_MEMADD_SIZE_16BIT;
156 }
157 status = ( HAL_I2C_Mem_Read( &I2cHandle, deviceAddr, addr, memAddSize, buffer, size, 2000 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
158
159 return status;
160 }
161
I2cMcuWaitStandbyState(I2c_t * obj,uint8_t deviceAddr)162 LmnStatus_t I2cMcuWaitStandbyState( I2c_t *obj, uint8_t deviceAddr )
163 {
164 LmnStatus_t status = LMN_STATUS_ERROR;
165
166 status = ( HAL_I2C_IsDeviceReady( &I2cHandle, deviceAddr, 300, 4096 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
167
168 return status;
169 }
170