Create release.yml
[betaflight.git] / src / main / target / COLIBRI_RACE / bus_bst_stm32f30x.c
blob0a6e818d2f7de0f22ec092f8310f99471921fd43
1 /* By Larry Ho Ka Wai @ 23/06/2015*/
3 #include <stdbool.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include <string.h>
8 #include <math.h>
9 #include <ctype.h>
11 #include "platform.h"
13 #ifdef USE_BST
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"
22 #include "bst.h"
23 #include "bus_bst.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
33 #endif
35 #if !defined(BST2_SCL_PIN)
36 #define BST2_SCL_PIN PA9 /* PF6 */
37 #define BST2_SDA_PIN PA10
38 #endif
40 static volatile uint16_t bstErrorCount = 0;
42 static I2C_TypeDef *BSTx = NULL;
44 static IO_t scl;
45 static IO_t sda;
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)) {
78 CRC8 = 0;
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);
84 } else {
85 readData[0] = I2C_GetAddressMatched(BSTx);
86 bufferPointer = 1;
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) {
94 crc8Cal(0);
95 bstProcessInCommand();
96 } else {
97 crc8Cal(data);
100 bufferPointer++;
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);
107 return;
109 if (interruptCounter < DELAY_SENDING_BYTE) {
110 interruptCounter++;
111 I2C_ClearITPendingBit(BSTx, I2C_IT_TXIS);
112 return;
113 } else {
114 interruptCounter = 0;
116 if (writeData[0] == currentWriteBufferPointer) {
117 receiverAddress = false;
118 crc8Cal(0);
119 I2C_SendData(BSTx, (uint8_t) CRC8);
120 I2C_ITConfig(BSTx, I2C_IT_TXI, DISABLE);
121 } else {
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)
129 dataBufferPointer++;
130 if (dataBufferPointer == bstWriteDataLen) {
131 I2C_ITConfig(BSTx, I2C_IT_TXI, DISABLE);
132 dataBufferPointer = 0;
133 bstWriteDataLen = 0;
135 } else {
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;
147 bstWriteDataLen = 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)
160 I2C_EV_IRQHandler();
163 void I2C2_EV_IRQHandler(void)
165 I2C_EV_IRQHandler();
168 uint32_t bstTimeoutUserCallback(void)
170 bstErrorCount++;
172 I2C_GenerateSTOP(BSTx, ENABLE);
173 receiverAddress = false;
174 dataBufferPointer = 0;
175 bstWriteDataLen = 0;
176 I2C_ITConfig(BSTx, I2C_IT_TXI, DISABLE);
177 I2C_SoftwareResetCmd(BSTx);
178 return false;
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;
190 if (BSTx == I2C1) {
191 scl = IOGetByTag(IO_TAG(BST1_SCL_PIN));
192 sda = IOGetByTag(IO_TAG(BST1_SDA_PIN));
193 } else {
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;
228 NVIC_Init(&nvic);
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)
244 if (bstWriteDataLen)
245 return true;
246 else
247 return false;
250 bool bstMasterWrite(uint8_t* data)
252 if (bstWriteDataLen==0) {
253 CRC8 = 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)) {
260 crc8Cal(0);
261 dataBuffer[i] = CRC8;
262 } else {
263 dataBuffer[i] = *(data+i);
264 crc8Cal((uint8_t)dataBuffer[i]);
267 return true;
269 return false;
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;
296 bool MSB_Flag;
298 /* Step through each bit of the BYTE (8-bits) */
299 for (uint8_t i = 0; i < 8; i++) {
300 /* Clear the Flag */
301 MSB_Flag = false;
303 /* MSB_Set = 80; */
304 if (CRC8 & 0x80) {
305 MSB_Flag = true;
308 CRC8 <<= 1;
310 /* MSB_Set = 80; */
311 if (data_in & 0x80) {
312 CRC8++;
314 data_in <<= 1;
316 if (MSB_Flag == true) {
317 CRC8 ^= Polynom;
321 #endif