1 /* By Larry Ho Ka Wai @ 23/06/2015*/
15 #include "build/build_config.h"
17 #include "drivers/nvic.h"
18 #include "drivers/io.h"
19 #include "drivers/io_impl.h"
20 #include "drivers/rcc.h"
25 #define NVIC_PRIO_BST_READ_DATA NVIC_BUILD_PRIORITY(1, 1)
27 #define BST_SHORT_TIMEOUT ((uint32_t)0x1000)
28 #define BST_LONG_TIMEOUT ((uint32_t)(10 * BST_SHORT_TIMEOUT))
30 #if !defined(BST1_SCL_PIN)
31 #define BST1_SCL_PIN PB6
32 #define BST1_SDA_PIN PB7
35 #if !defined(BST2_SCL_PIN)
36 #define BST2_SCL_PIN PA9 /* PF6 */
37 #define BST2_SDA_PIN PA10
40 static volatile uint16_t bstErrorCount
= 0;
42 static I2C_TypeDef
*BSTx
= NULL
;
47 static GPIO_TypeDef
* bstSclGpio
;
48 static uint16_t bstSclPin
;
50 volatile uint8_t CRC8
= 0;
51 volatile bool coreProReady
= false;
53 ///////////////////////////////////////////////////////////////////////////////
54 // BST TimeoutUserCallback
55 ///////////////////////////////////////////////////////////////////////////////
57 uint8_t dataBuffer
[BST_BUFFER_SIZE
] = {0};
58 uint8_t dataBufferPointer
= 0;
59 uint8_t bstWriteDataLen
= 0;
61 uint32_t micros(void);
63 uint8_t writeData
[BST_BUFFER_SIZE
] = {0};
64 uint8_t currentWriteBufferPointer
= 0;
65 bool receiverAddress
= false;
67 uint8_t readData
[BST_BUFFER_SIZE
] = {0};
68 uint8_t bufferPointer
= 0;
70 bool cleanflight_data_ready
= false;
71 uint8_t interruptCounter
= 0;
72 #define DELAY_SENDING_BYTE 40
74 void bstProcessInCommand(void);
75 void I2C_EV_IRQHandler(void)
77 if (I2C_GetITStatus(BSTx
, I2C_IT_ADDR
)) {
79 if (I2C_GetTransferDirection(BSTx
) == I2C_Direction_Receiver
) {
80 currentWriteBufferPointer
= 0;
81 receiverAddress
= true;
82 I2C_SendData(BSTx
, (uint8_t) writeData
[currentWriteBufferPointer
++]);
83 I2C_ITConfig(BSTx
, I2C_IT_TXI
, ENABLE
);
85 readData
[0] = I2C_GetAddressMatched(BSTx
);
88 I2C_ClearITPendingBit(BSTx
, I2C_IT_ADDR
);
89 } else if (I2C_GetITStatus(BSTx
, I2C_IT_RXNE
)) {
90 uint8_t data
= I2C_ReceiveData(BSTx
);
91 readData
[bufferPointer
] = data
;
92 if (bufferPointer
> 1) {
93 if (readData
[1]+1 == bufferPointer
) {
95 bstProcessInCommand();
101 I2C_ClearITPendingBit(BSTx
, I2C_IT_RXNE
);
102 } else if (I2C_GetITStatus(BSTx
, I2C_IT_TXIS
)) {
103 if (receiverAddress
) {
104 if (currentWriteBufferPointer
> 0) {
105 if (!cleanflight_data_ready
) {
106 I2C_ClearITPendingBit(BSTx
, I2C_IT_TXIS
);
109 if (interruptCounter
< DELAY_SENDING_BYTE
) {
111 I2C_ClearITPendingBit(BSTx
, I2C_IT_TXIS
);
114 interruptCounter
= 0;
116 if (writeData
[0] == currentWriteBufferPointer
) {
117 receiverAddress
= false;
119 I2C_SendData(BSTx
, (uint8_t) CRC8
);
120 I2C_ITConfig(BSTx
, I2C_IT_TXI
, DISABLE
);
122 crc8Cal((uint8_t) writeData
[currentWriteBufferPointer
]);
123 I2C_SendData(BSTx
, (uint8_t) writeData
[currentWriteBufferPointer
++]);
126 } else if (bstWriteDataLen
) {
127 I2C_SendData(BSTx
, (uint8_t) dataBuffer
[dataBufferPointer
]);
128 if (bstWriteDataLen
> 1)
130 if (dataBufferPointer
== bstWriteDataLen
) {
131 I2C_ITConfig(BSTx
, I2C_IT_TXI
, DISABLE
);
132 dataBufferPointer
= 0;
137 I2C_ClearITPendingBit(BSTx
, I2C_IT_TXIS
);
138 } else if (I2C_GetITStatus(BSTx
, I2C_IT_NACKF
)) {
139 if (receiverAddress
) {
140 receiverAddress
= false;
141 I2C_ITConfig(BSTx
, I2C_IT_TXI
, DISABLE
);
143 I2C_ClearITPendingBit(BSTx
, I2C_IT_NACKF
);
144 } else if (I2C_GetITStatus(BSTx
, I2C_IT_STOPF
)) {
145 if (bstWriteDataLen
&& dataBufferPointer
== bstWriteDataLen
) {
146 dataBufferPointer
= 0;
149 I2C_ClearITPendingBit(BSTx
, I2C_IT_STOPF
);
150 } else if (I2C_GetITStatus(BSTx
, I2C_IT_BERR
)
151 || I2C_GetITStatus(BSTx
, I2C_IT_ARLO
)
152 || I2C_GetITStatus(BSTx
, I2C_IT_OVR
)) {
153 bstTimeoutUserCallback();
154 I2C_ClearITPendingBit(BSTx
, I2C_IT_BERR
| I2C_IT_ARLO
| I2C_IT_OVR
);
158 void I2C1_EV_IRQHandler(void)
163 void I2C2_EV_IRQHandler(void)
168 uint32_t bstTimeoutUserCallback(void)
172 I2C_GenerateSTOP(BSTx
, ENABLE
);
173 receiverAddress
= false;
174 dataBufferPointer
= 0;
176 I2C_ITConfig(BSTx
, I2C_IT_TXI
, DISABLE
);
177 I2C_SoftwareResetCmd(BSTx
);
181 #define IOCFG_BST IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL)
183 void bstInit(BSTDevice index
)
185 NVIC_InitTypeDef nvic
;
186 I2C_InitTypeDef bstInit
;
188 BSTx
= (index
== BSTDEV_1
) ? I2C1
: I2C2
;
191 scl
= IOGetByTag(IO_TAG(BST1_SCL_PIN
));
192 sda
= IOGetByTag(IO_TAG(BST1_SDA_PIN
));
194 scl
= IOGetByTag(IO_TAG(BST2_SCL_PIN
));
195 sda
= IOGetByTag(IO_TAG(BST2_SDA_PIN
));
198 bstSclGpio
= IO_GPIO(scl
);
199 bstSclPin
= IO_Pin(scl
);
201 RCC_ClockCmd((BSTx
== I2C2
) ? RCC_APB1(I2C2
) : RCC_APB1(I2C1
), ENABLE
);
202 RCC_I2CCLKConfig((BSTx
== I2C2
) ? RCC_I2C2CLK_SYSCLK
: RCC_I2C1CLK_SYSCLK
);
204 IOInit(scl
, OWNER_I2C_SCL
, RESOURCE_INDEX(index
));
205 IOConfigGPIOAF(scl
, IOCFG_BST
, GPIO_AF_4
);
207 IOInit(sda
, OWNER_I2C_SDA
, RESOURCE_INDEX(index
));
208 IOConfigGPIOAF(sda
, IOCFG_BST
, GPIO_AF_4
);
210 I2C_StructInit(&bstInit
);
212 bstInit
.I2C_Mode
= I2C_Mode_I2C
;
213 bstInit
.I2C_AnalogFilter
= I2C_AnalogFilter_Enable
;
214 bstInit
.I2C_DigitalFilter
= 0x00;
215 bstInit
.I2C_OwnAddress1
= I2C_ADDR_CLEANFLIGHT_FC
;
216 bstInit
.I2C_Ack
= I2C_Ack_Enable
;
217 bstInit
.I2C_AcknowledgedAddress
= I2C_AcknowledgedAddress_7bit
;
218 bstInit
.I2C_Timing
= 0x30E0257A; // 100 Khz, 72Mhz Clock, Analog Filter Delay ON, Rise 100, Fall 10.
220 I2C_Init(BSTx
, &bstInit
);
222 I2C_GeneralCallCmd(BSTx
, ENABLE
);
224 nvic
.NVIC_IRQChannel
= (BSTx
== I2C2
) ? I2C2_EV_IRQn
: I2C1_EV_IRQn
;
225 nvic
.NVIC_IRQChannelPreemptionPriority
= NVIC_PRIORITY_BASE(NVIC_PRIO_BST_READ_DATA
);
226 nvic
.NVIC_IRQChannelSubPriority
= NVIC_PRIORITY_SUB(NVIC_PRIO_BST_READ_DATA
);
227 nvic
.NVIC_IRQChannelCmd
= ENABLE
;
230 I2C_ITConfig(BSTx
, I2C_IT_ADDRI
| I2C_IT_RXI
| I2C_IT_STOPI
| I2C_IT_NACKI
| I2C_IT_ERRI
, ENABLE
);
232 I2C_Cmd(BSTx
, ENABLE
);
235 uint16_t bstGetErrorCounter(void)
237 return bstErrorCount
;
240 /*************************************************************************************************/
242 bool bstWriteBusy(void)
250 bool bstMasterWrite(uint8_t* data
)
252 if (bstWriteDataLen
==0) {
254 dataBufferPointer
= 0;
255 dataBuffer
[0] = *data
;
256 dataBuffer
[1] = *(data
+1);
257 bstWriteDataLen
= dataBuffer
[1] + 2;
258 for (uint8_t i
=2; i
<bstWriteDataLen
; i
++) {
259 if (i
==(bstWriteDataLen
-1)) {
261 dataBuffer
[i
] = CRC8
;
263 dataBuffer
[i
] = *(data
+i
);
264 crc8Cal((uint8_t)dataBuffer
[i
]);
272 void bstMasterWriteLoop(void)
274 static uint32_t bstMasterWriteTimeout
= 0;
275 uint32_t currentTime
= micros();
277 if (bstWriteDataLen
&& dataBufferPointer
==0) {
278 bool scl_set
= (bstSclGpio
->IDR
& bstSclPin
);
280 if (I2C_GetFlagStatus(BSTx
, I2C_FLAG_BUSY
)==RESET
&& scl_set
) {
281 I2C_TransferHandling(BSTx
, dataBuffer
[dataBufferPointer
], dataBuffer
[dataBufferPointer
+1]+1, I2C_AutoEnd_Mode
, I2C_Generate_Start_Write
);
282 I2C_ITConfig(BSTx
, I2C_IT_TXI
, ENABLE
);
283 dataBufferPointer
= 1;
284 bstMasterWriteTimeout
= micros();
286 } else if (currentTime
>bstMasterWriteTimeout
+BST_SHORT_TIMEOUT
) {
287 bstTimeoutUserCallback();
291 /*************************************************************************************************/
292 void crc8Cal(uint8_t data_in
)
294 /* Polynom = x^8+x^7+x^6+x^4+x^2+1 = x^8+x^7+x^6+x^4+x^2+X^0 */
295 uint8_t Polynom
= BST_CRC_POLYNOM
;
298 /* Step through each bit of the BYTE (8-bits) */
299 for (uint8_t i
= 0; i
< 8; i
++) {
311 if (data_in
& 0x80) {
316 if (MSB_Flag
== true) {