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 "stm32l0xx.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 if( I2cFrequency == 100000 )
57 {
58 I2cHandle.Init.Timing = 0x00707CBB;
59 }
60 else if( I2cFrequency == 400000 )
61 {
62 I2cHandle.Init.Timing = 0x00300F38;
63 }
64
65 I2cHandle.Init.OwnAddress1 = 0;
66 I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
67 I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
68 I2cHandle.Init.OwnAddress2 = 0;
69 I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
70 I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
71 I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
72
73 HAL_I2C_Init( &I2cHandle );
74
75 HAL_I2CEx_ConfigAnalogFilter( &I2cHandle, I2C_ANALOGFILTER_ENABLE );
76 HAL_I2CEx_ConfigDigitalFilter( &I2cHandle, 0 );
77 }
78
I2cMcuResetBus(I2c_t * obj)79 void I2cMcuResetBus( I2c_t *obj )
80 {
81 __HAL_RCC_I2C1_CLK_DISABLE( );
82 __HAL_RCC_I2C1_CLK_ENABLE( );
83 __HAL_RCC_I2C1_FORCE_RESET( );
84 __HAL_RCC_I2C1_RELEASE_RESET( );
85
86 GpioInit( &obj->Scl, I2C_SCL, PIN_ALTERNATE_FCT, PIN_OPEN_DRAIN, PIN_NO_PULL, GPIO_AF4_I2C1 );
87 GpioInit( &obj->Sda, I2C_SDA, PIN_ALTERNATE_FCT, PIN_OPEN_DRAIN, PIN_NO_PULL, GPIO_AF4_I2C1 );
88
89 I2cMcuFormat( obj, MODE_I2C, I2C_DUTY_CYCLE_2, true, I2C_ACK_ADD_7_BIT, 400000 );
90 }
91
I2cMcuDeInit(I2c_t * obj)92 void I2cMcuDeInit( I2c_t *obj )
93 {
94
95 HAL_I2C_DeInit( &I2cHandle );
96
97 __HAL_RCC_I2C1_FORCE_RESET();
98 __HAL_RCC_I2C1_RELEASE_RESET();
99 __HAL_RCC_I2C1_CLK_DISABLE( );
100
101 GpioInit( &obj->Scl, obj->Scl.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
102 GpioInit( &obj->Sda, obj->Sda.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
103 }
104
I2cSetAddrSize(I2c_t * obj,I2cAddrSize addrSize)105 void I2cSetAddrSize( I2c_t *obj, I2cAddrSize addrSize )
106 {
107 I2cInternalAddrSize = addrSize;
108 }
109
I2cMcuWriteBuffer(I2c_t * obj,uint8_t deviceAddr,uint8_t * buffer,uint16_t size)110 LmnStatus_t I2cMcuWriteBuffer( I2c_t *obj, uint8_t deviceAddr, uint8_t *buffer, uint16_t size )
111 {
112 LmnStatus_t status = LMN_STATUS_ERROR;
113
114 status = ( HAL_I2C_Master_Transmit( &I2cHandle, deviceAddr, buffer, size, 2000 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
115
116 return status;
117 }
118
I2cMcuReadBuffer(I2c_t * obj,uint8_t deviceAddr,uint8_t * buffer,uint16_t size)119 LmnStatus_t I2cMcuReadBuffer( I2c_t *obj, uint8_t deviceAddr, uint8_t *buffer, uint16_t size )
120 {
121 LmnStatus_t status = LMN_STATUS_ERROR;
122
123 status = ( HAL_I2C_Master_Receive( &I2cHandle, deviceAddr, buffer, size, 2000 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
124
125 return status;
126 }
127
I2cMcuWriteMemBuffer(I2c_t * obj,uint8_t deviceAddr,uint16_t addr,uint8_t * buffer,uint16_t size)128 LmnStatus_t I2cMcuWriteMemBuffer( I2c_t *obj, uint8_t deviceAddr, uint16_t addr, uint8_t *buffer, uint16_t size )
129 {
130 LmnStatus_t status = LMN_STATUS_ERROR;
131 uint16_t memAddSize = 0;
132
133 if( I2cInternalAddrSize == I2C_ADDR_SIZE_8 )
134 {
135 memAddSize = I2C_MEMADD_SIZE_8BIT;
136 }
137 else
138 {
139 memAddSize = I2C_MEMADD_SIZE_16BIT;
140 }
141 status = ( HAL_I2C_Mem_Write( &I2cHandle, deviceAddr, addr, memAddSize, buffer, size, 2000 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
142
143 return status;
144 }
145
I2cMcuReadMemBuffer(I2c_t * obj,uint8_t deviceAddr,uint16_t addr,uint8_t * buffer,uint16_t size)146 LmnStatus_t I2cMcuReadMemBuffer( I2c_t *obj, uint8_t deviceAddr, uint16_t addr, uint8_t *buffer, uint16_t size )
147 {
148 LmnStatus_t status = LMN_STATUS_ERROR;
149 uint16_t memAddSize = 0;
150
151 if( I2cInternalAddrSize == I2C_ADDR_SIZE_8 )
152 {
153 memAddSize = I2C_MEMADD_SIZE_8BIT;
154 }
155 else
156 {
157 memAddSize = I2C_MEMADD_SIZE_16BIT;
158 }
159 status = ( HAL_I2C_Mem_Read( &I2cHandle, deviceAddr, addr, memAddSize, buffer, size, 2000 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
160
161 return status;
162 }
163
I2cMcuWaitStandbyState(I2c_t * obj,uint8_t deviceAddr)164 LmnStatus_t I2cMcuWaitStandbyState( I2c_t *obj, uint8_t deviceAddr )
165 {
166 LmnStatus_t status = LMN_STATUS_ERROR;
167
168 status = ( HAL_I2C_IsDeviceReady( &I2cHandle, deviceAddr, 300, 4096 ) == HAL_OK ) ? LMN_STATUS_OK : LMN_STATUS_ERROR;
169
170 return status;
171 }
172