Rev 184 | Rev 195 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 184 | Rev 189 | ||
---|---|---|---|
Line 52... | Line 52... | ||
52 | // + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
52 | // + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
53 | // + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
53 | // + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
54 | // + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
54 | // + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
55 | // + POSSIBILITY OF SUCH DAMAGE. |
55 | // + POSSIBILITY OF SUCH DAMAGE. |
56 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
56 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
57 | #include <stdlib.h> |
- | |
58 | #include <string.h> |
57 | #include <string.h> |
59 | #include "91x_lib.h" |
58 | #include "91x_lib.h" |
60 | #include "i2c.h" |
59 | #include "i2c.h" |
61 | #include "uart1.h" |
60 | #include "uart1.h" |
62 | #include "timer1.h" |
61 | #include "timer1.h" |
63 | #include "config.h" |
62 | #include "config.h" |
64 | #include "main.h" |
63 | #include "main.h" |
65 | #include "led.h" |
64 | #include "led.h" |
66 | #include "spi_slave.h" |
65 | #include "spi_slave.h" |
Line -... | Line 66... | ||
- | 66 | ||
Line -... | Line 67... | ||
- | 67 | #define I2C_SLAVE_ADDRESS 0x50 |
|
- | 68 | ||
- | 69 | // I2C states |
|
- | 70 | #define I2C_UNDEF 0 |
|
- | 71 | #define I2C_IDLE 1 |
|
- | 72 | #define I2C_TX_PROGRESS 2 |
|
- | 73 | #define I2C_RX_PENDING 3 |
|
- | 74 | #define I2C_RX_PROGRESS 4 |
|
67 | 75 | #define I2C_OFF 5 |
|
68 | 76 | ||
Line 69... | Line 77... | ||
69 | volatile I2C_State_t I2C_State = I2C_OFF; |
77 | volatile u8 I2C_State = I2C_OFF; // only on byte! because of sync by nesting irqs |
70 | volatile u8 I2C_StopPolling = 1; |
78 | u8 I2C_StopPolling = 1; |
71 | 79 | ||
72 | // rxbuffer |
- | |
73 | volatile u8 I2C_RxBufferSize; |
80 | // rxbuffer |
74 | volatile u8 *I2C_RxBuffer; |
81 | volatile u8 I2C_RxBufferSize; |
75 | volatile u8 Rx_Idx = 0; |
82 | volatile u8 *I2C_RxBuffer; |
76 | // txbuffer |
- | |
Line 77... | Line 83... | ||
77 | volatile u8 I2C_TxBufferSize; |
83 | // txbuffer |
78 | volatile u8 *I2C_TxBuffer; |
84 | volatile u8 I2C_TxBufferSize; |
79 | volatile u8 Tx_Idx = 0; |
- | |
- | 85 | volatile u8 *I2C_TxBuffer; |
|
80 | 86 | ||
81 | volatile u8 I2C_Direction; |
87 | volatile u8 I2C_Direction; |
82 | volatile u8 I2C_Command; |
88 | volatile u8 I2C_Command; |
83 | 89 | // I2C Transfer buffers |
|
84 | volatile I2C_Heading_t I2C_Heading; |
90 | volatile I2C_Heading_t I2C_Heading; |
85 | volatile I2C_WriteAttitude_t I2C_WriteAttitude; |
91 | volatile I2C_WriteAttitude_t I2C_WriteAttitude; |
Line 86... | Line 92... | ||
86 | volatile I2C_Mag_t I2C_Mag; |
92 | volatile I2C_Mag_t I2C_Mag; |
87 | volatile I2C_Version_t MK3MAG_Version; |
93 | volatile I2C_Version_t MK3MAG_Version; |
88 | volatile I2C_Cal_t I2C_WriteCal; |
- | |
Line 89... | Line 94... | ||
89 | volatile I2C_Cal_t I2C_ReadCal; |
94 | volatile I2C_Cal_t I2C_WriteCal; |
90 | 95 | volatile I2C_Cal_t I2C_ReadCal; |
|
91 | #define I2C1_TIMEOUT 500 // 500 ms |
96 | |
92 | volatile u32 I2C1_Timeout = 0; |
97 | #define I2C1_TIMEOUT 500 // 500 ms |
Line 170... | Line 175... | ||
170 | I2C_Struct.I2C_CLKSpeed = I2C1_CLOCK; |
175 | I2C_Struct.I2C_CLKSpeed = I2C1_CLOCK; |
171 | I2C_Struct.I2C_OwnAddress = 0x00; |
176 | I2C_Struct.I2C_OwnAddress = 0x00; |
172 | I2C_Init(I2C1, &I2C_Struct); |
177 | I2C_Init(I2C1, &I2C_Struct); |
Line 173... | Line 178... | ||
173 | 178 | ||
174 | I2C_TxBuffer = NULL; |
- | |
175 | Tx_Idx = 0; |
179 | I2C_TxBuffer = NULL; |
Line 176... | Line 180... | ||
176 | I2C_TxBufferSize = 0; |
180 | I2C_TxBufferSize = 0; |
177 | - | ||
178 | I2C_RxBuffer = NULL; |
181 | |
Line 179... | Line 182... | ||
179 | Rx_Idx = 0; |
182 | I2C_RxBuffer = NULL; |
180 | I2C_RxBufferSize = 0; |
183 | I2C_RxBufferSize = 0; |
Line 181... | Line 184... | ||
181 | 184 | ||
182 | I2C_Cmd(I2C1, ENABLE); |
- | |
Line 183... | Line 185... | ||
183 | I2C_ITConfig(I2C1, ENABLE); |
185 | I2C_Cmd(I2C1, ENABLE); |
184 | 186 | I2C_ITConfig(I2C1, ENABLE); |
|
185 | VIC_Config(I2C1_ITLine, VIC_IRQ , PRIORITY_I2C1); |
187 | |
186 | VIC_ITCmd(I2C1_ITLine, ENABLE); |
188 | VIC_Config(I2C1_ITLine, VIC_IRQ , PRIORITY_I2C1); |
Line 187... | Line 189... | ||
187 | 189 | ||
Line 220... | Line 222... | ||
220 | GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable; |
222 | GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable; |
221 | GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1; |
223 | GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1; |
222 | GPIO_Init(GPIO2, &GPIO_InitStructure); |
224 | GPIO_Init(GPIO2, &GPIO_InitStructure); |
Line 223... | Line 225... | ||
223 | 225 | ||
224 | I2C_TxBuffer = NULL; |
- | |
225 | Tx_Idx = 0; |
226 | I2C_TxBuffer = NULL; |
Line 226... | Line 227... | ||
226 | I2C_TxBufferSize = 0; |
227 | I2C_TxBufferSize = 0; |
227 | - | ||
228 | I2C_RxBuffer = NULL; |
228 | |
Line 229... | Line 229... | ||
229 | Rx_Idx = 0; |
229 | I2C_RxBuffer = NULL; |
230 | I2C_RxBufferSize = 0; |
230 | I2C_RxBufferSize = 0; |
Line 231... | Line 231... | ||
231 | 231 | ||
232 | I2C1_Timeout = 0; |
232 | I2C1_Timeout = SetDelay(10*I2C1_TIMEOUT); |
Line 233... | Line 233... | ||
233 | I2C_Heading.Heading = -1; |
233 | I2C_Heading.Heading = -1; |
234 | 234 | ||
235 | UART1_PutString("ok"); |
235 | UART1_PutString("ok"); |
- | 236 | } |
|
- | 237 | ||
236 | } |
238 | |
237 | 239 | //-------------------------------------------------------------- |
|
238 | 240 | void I2C1_IRQHandler(void) |
|
239 | //-------------------------------------------------------------- |
241 | { |
Line 240... | Line 242... | ||
240 | void I2C1_IRQHandler(void) |
242 | static u8 Rx_Idx = 0, Tx_Idx = 0, crc = 0; |
241 | { |
243 | static u8 I2C_PrimRxBuffer[10]; // must be larger than any of the secondary rx buffers |
Line 250... | Line 252... | ||
250 | { |
252 | { |
251 | I2C_GenerateSTOP (I2C1, ENABLE); // free the bus |
253 | I2C_GenerateSTOP (I2C1, ENABLE); // free the bus |
252 | I2C_GenerateSTOP (I2C1, DISABLE); // free the bus |
254 | I2C_GenerateSTOP (I2C1, DISABLE); // free the bus |
253 | } |
255 | } |
254 | I2C_State = I2C_IDLE; |
256 | I2C_State = I2C_IDLE; |
- | 257 | VIC_ITCmd(I2C1_ITLine, DISABLE); |
|
255 | LED_GRN_OFF; |
258 | LED_GRN_OFF; |
- | 259 | return; |
|
256 | } |
260 | } |
257 | else |
261 | else |
258 | { // depending on current i2c state |
262 | { // depending on current i2c state |
259 | switch (status) |
263 | switch (status) |
260 | { |
264 | { |
Line 270... | Line 274... | ||
270 | 274 | ||
271 | case I2C_MODE_RECEIVER: |
275 | case I2C_MODE_RECEIVER: |
272 | if ((I2C_RxBuffer == NULL) || (I2C_RxBufferSize == 0)) |
276 | if ((I2C_RxBuffer == NULL) || (I2C_RxBufferSize == 0)) |
273 | { |
277 | { |
- | 278 | I2C_GenerateSTOP (I2C1, ENABLE); |
|
- | 279 | VIC_ITCmd(I2C1_ITLine, DISABLE); |
|
274 | I2C_GenerateSTOP (I2C1, ENABLE); |
280 | LED_GRN_OFF; |
275 | I2C_State = I2C_IDLE; |
281 | I2C_State = I2C_IDLE; |
276 | return; |
282 | return; |
277 | } |
283 | } |
278 | else |
284 | else |
Line 281... | Line 287... | ||
281 | } |
287 | } |
282 | break; |
288 | break; |
Line 283... | Line 289... | ||
283 | 289 | ||
284 | default: // invalid direction |
290 | default: // invalid direction |
285 | I2C_GenerateSTOP (I2C1, ENABLE); |
291 | I2C_GenerateSTOP (I2C1, ENABLE); |
286 | I2C_State = I2C_IDLE; |
292 | VIC_ITCmd(I2C1_ITLine, DISABLE); |
- | 293 | LED_GRN_OFF; |
|
287 | LED_GRN_OFF; |
294 | I2C_State = I2C_IDLE; |
288 | return; |
295 | return; |
289 | } |
296 | } |
290 | // enable acknowledge |
297 | // enable acknowledge |
291 | I2C_AcknowledgeConfig (I2C1, ENABLE); |
298 | I2C_AcknowledgeConfig (I2C1, ENABLE); |
Line 305... | Line 312... | ||
305 | // send command 1st data byte (allways the command id) |
312 | // send command 1st data byte (allways the command id) |
306 | I2C_SendData(I2C1, I2C_Command); |
313 | I2C_SendData(I2C1, I2C_Command); |
307 | crc += I2C_Command; |
314 | crc += I2C_Command; |
308 | Tx_Idx = 0; |
315 | Tx_Idx = 0; |
309 | // reset timeout |
316 | // reset timeout |
310 | I2C1_Timeout = SetDelay(500); // after 500 ms of inactivity the I2C1 bus will be reset |
317 | I2C1_Timeout = SetDelay(I2C1_TIMEOUT); // after inactivity the I2C1 bus will be reset |
311 | break; |
318 | break; |
Line 312... | Line 319... | ||
312 | 319 | ||
313 | case I2C_RX_PROGRESS: |
320 | case I2C_RX_PROGRESS: |
314 | Rx_Idx = 0; |
321 | Rx_Idx = 0; |
Line 315... | Line 322... | ||
315 | break; |
322 | break; |
316 | 323 | ||
317 | default: // unknown I2C state |
324 | default: // unknown I2C state |
- | 325 | // should never happen |
|
- | 326 | I2C_GenerateSTOP (I2C1, ENABLE); |
|
318 | // should never happen |
327 | LED_GRN_OFF; |
- | 328 | VIC_ITCmd(I2C1_ITLine, DISABLE); |
|
319 | I2C_GenerateSTOP (I2C1, ENABLE); |
329 | I2C_State = I2C_IDLE; |
320 | I2C_State = I2C_IDLE; |
330 | return; |
321 | break; |
331 | break; |
Line 322... | Line 332... | ||
322 | } |
332 | } |
Line 336... | Line 346... | ||
336 | else |
346 | else |
337 | { |
347 | { |
338 | I2C_SendData(I2C1, 0x00); |
348 | I2C_SendData(I2C1, 0x00); |
339 | } |
349 | } |
340 | } |
350 | } |
341 | else // the last tx buffer byte was send |
351 | else if(Tx_Idx == I2C_TxBufferSize) // the last tx buffer byte was send |
342 | { |
352 | { |
343 | // send crc byte at the end |
353 | // send crc byte at the end |
344 | crc = ~crc; // flip all bits in the checksum |
354 | crc = ~crc; // flip all bits in the checksum |
345 | I2C_SendData(I2C1, crc); |
355 | I2C_SendData(I2C1, crc); |
- | 356 | } |
|
- | 357 | else if(Tx_Idx == (I2C_TxBufferSize+1) ) |
|
- | 358 | { |
|
- | 359 | I2C_SendData(I2C1, 0xAA); // send a dummybyte |
|
- | 360 | } |
|
- | 361 | else // last byte was send |
|
- | 362 | { |
|
346 | // generate stop or repeated start condition |
363 | // generate stop or repeated start condition |
347 | if ((I2C_RxBuffer != NULL) && (I2C_RxBufferSize > 0)) // is any answer byte expected? |
364 | if ((I2C_RxBuffer != NULL) && (I2C_RxBufferSize > 0)) // is any answer byte expected? |
348 | { |
365 | { |
349 | I2C_Direction = I2C_MODE_RECEIVER; // switch to master receiver after repeated start condition |
366 | I2C_Direction = I2C_MODE_RECEIVER; // switch to master receiver after repeated start condition |
350 | I2C_GenerateStart(I2C1, ENABLE); // initiate repeated start condition on the bus |
367 | I2C_GenerateStart(I2C1, ENABLE); // initiate repeated start condition on the bus |
351 | } |
368 | } |
352 | else |
369 | else |
353 | { // stop communication |
370 | { // stop communication |
354 | I2C_GenerateSTOP(I2C1, ENABLE); // generate stop condition to free the bus |
371 | I2C_GenerateSTOP(I2C1, ENABLE); // generate stop condition to free the bus |
355 | I2C_State = I2C_IDLE; // ready for new actions |
372 | VIC_ITCmd(I2C1_ITLine, DISABLE); |
356 | LED_GRN_OFF; |
373 | LED_GRN_OFF; |
357 | DebugOut.Analog[15]++; |
374 | DebugOut.Analog[15]++; |
- | 375 | I2C_State = I2C_IDLE; // ready for new actions |
|
- | 376 | ||
358 | } |
377 | } |
359 | } |
378 | } |
360 | Tx_Idx++; |
379 | Tx_Idx++; |
361 | break; |
380 | break; |
Line 375... | Line 394... | ||
375 | // generate a STOP condition on the bus before reading data register |
394 | // generate a STOP condition on the bus before reading data register |
376 | I2C_GenerateSTOP(I2C1, ENABLE); |
395 | I2C_GenerateSTOP(I2C1, ENABLE); |
377 | // compare last byte with checksum |
396 | // compare last byte with checksum |
378 | crc = ~crc;// flip all bits in calulated checksum |
397 | crc = ~crc;// flip all bits in calulated checksum |
379 | if(crc == I2C_ReceiveData(I2C1)) |
398 | if(crc == I2C_ReceiveData(I2C1)) |
- | 399 | { |
|
380 | { // copy primary rx buffer content to rx buffer if exist |
400 | // copy primary rx buffer content to rx buffer if exist |
381 | if(I2C_RxBuffer != NULL) |
401 | if(I2C_RxBuffer != NULL) |
382 | { |
402 | { |
383 | memcpy((u8 *)I2C_RxBuffer, (u8 *)I2C_PrimRxBuffer, I2C_RxBufferSize); |
403 | memcpy((u8 *)I2C_RxBuffer, (u8 *)I2C_PrimRxBuffer, I2C_RxBufferSize); |
384 | } |
404 | } |
385 | I2C1_Timeout = SetDelay(500); |
405 | I2C1_Timeout = SetDelay(I2C1_TIMEOUT); |
386 | DebugOut.Analog[15]++; |
406 | DebugOut.Analog[15]++; |
387 | } |
407 | } |
388 | else // checksum error detected |
408 | else // checksum error detected |
389 | { |
409 | { |
390 | // DebugOut.Analog[14]++; |
410 | DebugOut.Analog[14]++; |
391 | } |
411 | } |
392 | I2C_State = I2C_IDLE; |
412 | VIC_ITCmd(I2C1_ITLine, DISABLE); |
393 | LED_GRN_OFF; |
413 | LED_GRN_OFF; |
- | 414 | I2C_State = I2C_IDLE; |
|
- | 415 | return; |
|
394 | } |
416 | } |
395 | Rx_Idx++; |
417 | Rx_Idx++; |
396 | // if the 2nd last byte was received disable acknowledge for the last one |
418 | // if the 2nd last byte was received disable acknowledge for the last one |
397 | if ( Rx_Idx == I2C_RxBufferSize ) |
419 | if ( Rx_Idx == I2C_RxBufferSize ) |
398 | { |
420 | { |
Line 406... | Line 428... | ||
406 | } |
428 | } |
407 | } |
429 | } |
408 | //---------------------------------------------------------------- |
430 | //---------------------------------------------------------------- |
409 | void I2C1_SendCommand(u8 command) |
431 | void I2C1_SendCommand(u8 command) |
410 | { |
432 | { |
- | 433 | // disable I2C IRQ to check state |
|
- | 434 | VIC_ITCmd(I2C1_ITLine, DISABLE); |
|
411 | // If I2C transmission is in progress |
435 | // If I2C transmission is in progress |
412 | if(I2C_State != I2C_IDLE) return; // return imediatly if a transfer is still in progress |
- | |
413 | // disable I2C IRQ to avoid read/write access to the tx/rx buffer pointers during |
- | |
414 | // update of that buffer pointers and length |
- | |
415 | I2C_ITConfig(I2C1, DISABLE); |
436 | if(I2C_State == I2C_IDLE) |
- | 437 | { |
|
416 | // update current command id |
438 | // update current command id |
417 | I2C_Command = command; |
439 | I2C_Command = command; |
418 | // set pointers to data area with respect to the command id |
440 | // set pointers to data area with respect to the command id |
419 | switch (command) |
441 | switch (command) |
420 | { |
442 | { |
Line 435... | Line 457... | ||
435 | I2C_RxBufferSize = sizeof(I2C_Mag); |
457 | I2C_RxBufferSize = sizeof(I2C_Mag); |
436 | I2C_TxBuffer = NULL; |
458 | I2C_TxBuffer = NULL; |
437 | I2C_TxBufferSize = 0; |
459 | I2C_TxBufferSize = 0; |
438 | break; |
460 | break; |
439 | case I2C_CMD_READ_HEADING: |
461 | case I2C_CMD_READ_HEADING: |
440 | DebugOut.Analog[10] = I2C_Heading.Heading; |
- | |
441 | I2C_RxBuffer = (u8 *)&I2C_Heading; |
462 | I2C_RxBuffer = (u8 *)&I2C_Heading; |
442 | I2C_RxBufferSize = sizeof(I2C_Heading); |
463 | I2C_RxBufferSize = sizeof(I2C_Heading); |
443 | // updat atitude from spi rx buffer |
- | |
444 | I2C_WriteAttitude.Roll = FromFlightCtrl.AngleRoll; |
- | |
445 | I2C_WriteAttitude.Nick = FromFlightCtrl.AngleNick; |
- | |
446 | I2C_TxBuffer = (u8 *)&I2C_WriteAttitude; |
464 | I2C_TxBuffer = (u8 *)&I2C_WriteAttitude; |
447 | I2C_TxBufferSize = sizeof(I2C_WriteAttitude); |
465 | I2C_TxBufferSize = sizeof(I2C_WriteAttitude); |
- | 466 | // update attitude from spi rx buffer |
|
- | 467 | VIC_ITCmd(SSP0_ITLine, DISABLE); // avoid spi buffer update during copy |
|
- | 468 | I2C_WriteAttitude.Roll = FromFlightCtrl.AngleRoll; |
|
- | 469 | I2C_WriteAttitude.Nick = FromFlightCtrl.AngleNick; |
|
- | 470 | VIC_ITCmd(SSP0_ITLine, ENABLE); |
|
448 | break; |
471 | break; |
449 | default: // unknown command id |
472 | default: // unknown command id |
450 | I2C_RxBuffer = NULL; |
473 | I2C_RxBuffer = NULL; |
451 | I2C_RxBufferSize = 0; |
474 | I2C_RxBufferSize = 0; |
452 | I2C_TxBuffer = NULL; |
475 | I2C_TxBuffer = NULL; |
Line 456... | Line 479... | ||
456 | // set direction to master transmitter |
479 | // set direction to master transmitter |
457 | I2C_Direction = I2C_MODE_TRANSMITTER; |
480 | I2C_Direction = I2C_MODE_TRANSMITTER; |
458 | // test on busy flag and clear it |
481 | // test on busy flag and clear it |
459 | I2C_CheckEvent( I2C1, I2C_FLAG_BUSY ); |
482 | I2C_CheckEvent( I2C1, I2C_FLAG_BUSY ); |
460 | // enable I2C IRQ again |
483 | // enable I2C IRQ again |
461 | I2C_ITConfig(I2C1, ENABLE); |
484 | VIC_ITCmd(I2C1_ITLine, ENABLE); |
462 | // initiale start condition on the bus |
485 | // initiate start condition on the bus |
463 | I2C_GenerateStart(I2C1, ENABLE); |
486 | I2C_GenerateStart(I2C1, ENABLE); |
464 | // to be continued in the I2C1_IRQHandler() above |
487 | // to be continued in the I2C1_IRQHandler() above |
- | 488 | } // EOF I2C_State == I2C_IDLE |
|
- | 489 | else // I2C_State != I2C_IDLE |
|
- | 490 | { |
|
- | 491 | // re-enable I2C IRQ again |
|
- | 492 | VIC_ITCmd(I2C1_ITLine, ENABLE); |
|
- | 493 | } |
|
465 | } |
494 | } |
Line 466... | Line 495... | ||
466 | 495 | ||
467 | //---------------------------------------------------------------- |
496 | //---------------------------------------------------------------- |
468 | void I2C1_GetMK3MagVersion(void) |
497 | void I2C1_GetMK3MagVersion(void) |
Line 525... | Line 554... | ||
525 | } |
554 | } |
526 | else // request current heading |
555 | else // request current heading |
527 | { |
556 | { |
528 | I2C1_SendCommand(I2C_CMD_READ_HEADING); |
557 | I2C1_SendCommand(I2C_CMD_READ_HEADING); |
529 | } |
558 | } |
530 | TimerCompassUpdate = SetDelay(25); // every 25 ms |
559 | TimerCompassUpdate = SetDelay(40); // every 40 ms are 25 Hz |
531 | } |
560 | } |
532 | } |
561 | } |