LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i2c.c
Go to the documentation of this file.
1 /*
2  * @brief I2C example
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "board.h"
33 
61 /*****************************************************************************
62  * Private types/enumerations/variables
63  ****************************************************************************/
64 
66 #define I2C_MASTER_MODE 1
67 
68 #define I2C_SLAVE_ADDR_7BIT (0x90)
69 
70 #define I2C_SLAVE_ADDR_10BIT (0x2CA)
71 
72 #define I2C_ROM_MEM_SIZE (0x100UL)
73 
74 #define I2C_BITRATE (1000000)
75 
76 #define BUFFER_SIZE (0xFF)
77 
83 volatile bool isTxCompleted = false;
84 volatile bool isRxCompleted = false;
85 volatile bool isTxRxCompleted = false;
86 
89 
90 /*****************************************************************************
91  * Public types/enumerations/variables
92  ****************************************************************************/
93 
94 /*****************************************************************************
95  * Private functions
96  ****************************************************************************/
97 
98 /* Initialize buffer */
99 static void Buffer_Init(uint8_t *buffer, uint32_t buf_len, uint8_t type)
100 {
101  uint8_t i;
102 
103  if (type) {
104  for (i = 0; i < buf_len; i++) {
105  buffer[i] = i;
106  }
107  }
108  else {
109  for (i = 0; i < buf_len; i++) {
110  buffer[i] = 0;
111  }
112  }
113 }
114 
115 /* If error occurs, turn LED 0 (red LED) on and wait forever */
116 static void spin_on_error(void)
117 {
118  while (1) {
119  /* Show the red LED continuously due to error */
120  Board_LED_Toggle(0);
121  }
122 }
123 
124 /* Compare two buffers from position StartPos to StopPos */
125 static void Buffer_Compare(uint8_t *buffer1, uint8_t *buffer2, uint32_t StartPos, uint32_t StopPos)
126 {
127  uint32_t i = 0;
128  for (i = StartPos; i < StopPos; i++) {
129  if (buffer1[i] != buffer2[i]) {
130  /* buffer1 differs from buffer2 and red LED is shown due to error */
131  spin_on_error();
132  }
133  }
134 }
135 
136 /* I2C Receive Callback function */
138 {
139  isRxCompleted = true;
140  error_code = err_code;
141 }
142 
143 /* I2C Transmit Callback function */
145 {
146  isTxCompleted = true;
147  error_code = err_code;
148 }
149 #if I2C_MASTER_MODE
150 /* I2C Transmit and Receive Callback function */
152 {
153  isTxRxCompleted = true;
154  error_code = err_code;
155 }
156 #endif
157 
158 #if I2C_MASTER_MODE
159 /* Master Polling Mode */
160 static void App_I2C_Master_Polling(void)
161 {
162  /* Transmit TmpBuffer */
163  /* Initialize buffer */
166 
167  param.num_bytes_send = BUFFER_SIZE;
168  param.buffer_ptr_send = &TmpBuffer[0];
169  param.stop_flag = 1;
170  do {
171  error_code = LPC_I2CD_API->i2c_master_transmit_poll(i2c_handle, &param, &result);
172  } while (error_code);
173 
174  /* Receive Buffer and compare with TmpBuffer */
175  /* Initialize buffer */
177  Buffer[0] = I2C_SLAVE_ADDR_7BIT | 0x01;
178 
179  param.num_bytes_recv = BUFFER_SIZE;
180  param.buffer_ptr_recv = &Buffer[0];
181  param.stop_flag = 1;
182  do {
183  error_code = LPC_I2CD_API->i2c_master_receive_poll(i2c_handle, &param, &result);
184  } while (error_code);
185 
186  /* Verify */
188 
189  /* Transmit TmpBuffer and receive Buffer, then compare them together */
190  /* Initialize buffer */
192  Buffer[0] = I2C_SLAVE_ADDR_7BIT | 0x01;
193 
195  TmpBuffer[1] = 0xBA;
196 
197  param.num_bytes_send = BUFFER_SIZE;
198  param.buffer_ptr_send = &TmpBuffer[0];
199  param.num_bytes_recv = BUFFER_SIZE;
200  param.buffer_ptr_recv = &Buffer[0];
201  param.stop_flag = 1;
202 
203  do {
204  error_code = LPC_I2CD_API->i2c_master_tx_rx_poll(i2c_handle, &param, &result);
205  } while (error_code);
206 
207  /* Verify */
209 }
210 
211 /* Master Interrupt Mode */
212 static void App_I2C_Master_Interrupt(void)
213 {
214  /* Transmit TmpBuffer */
215  /* Initialize buffer */
218 
219  param.num_bytes_send = BUFFER_SIZE;
220  param.buffer_ptr_send = &TmpBuffer[0];
222  param.stop_flag = 1;
223 
224  NVIC_DisableIRQ(I2C_IRQn);
225  NVIC_ClearPendingIRQ(I2C_IRQn);
226  NVIC_EnableIRQ(I2C_IRQn);
227 
228  do {
229  isTxCompleted = false;
230  LPC_I2CD_API->i2c_master_transmit_intr(i2c_handle, &param, &result);
231  while (!isTxCompleted) {}
232  } while (error_code);
233 
234  /* Receive Buffer and compare with TmpBuffer */
235  /* Initialize buffer */
237  Buffer[0] = I2C_SLAVE_ADDR_7BIT | 0x01;
238 
239  param.num_bytes_recv = BUFFER_SIZE;
240  param.buffer_ptr_recv = &Buffer[0];
242  param.stop_flag = 1;
243 
244  do {
245  isRxCompleted = false;
246  LPC_I2CD_API->i2c_master_receive_intr(i2c_handle, &param, &result);
247  while (!isRxCompleted) {}
248  } while (error_code);
249 
250  /* Verify */
252 
253  /* Transmit TmpBuffer and receive Buffer, then compare them together */
254  /* Initialize buffer */
256  Buffer[0] = I2C_SLAVE_ADDR_7BIT | 0x01;
257 
259  TmpBuffer[1] = 0xBA;
260 
261  param.num_bytes_send = BUFFER_SIZE;
262  param.buffer_ptr_send = &TmpBuffer[0];
263  param.num_bytes_recv = BUFFER_SIZE;
264  param.buffer_ptr_recv = &Buffer[0];
266  param.stop_flag = 1;
267 
268  do {
269  isTxRxCompleted = false;
270  LPC_I2CD_API->i2c_master_tx_rx_intr(i2c_handle, &param, &result);
271  while (!isTxRxCompleted) {}
272  } while (error_code);
273 
274  /* Verify */
276 }
277 
278 /* Master Mode with 10-bit address */
280 {
281  /* Transmit Buffer to slave with 10-bit addressing mode */
282  /* Initialize buffer */
283  Buffer_Init(&TmpBuffer[1], (BUFFER_SIZE - 1), 1);
285 
286  TmpBuffer[0] = ((I2C_SLAVE_ADDR_10BIT >> 7) & 0x06) | 0xF0; /* 4 MSBs of slave address in first byte of transmit buffer */
287  TmpBuffer[1] = I2C_SLAVE_ADDR_10BIT & 0x0FF;
288 
289  param.num_bytes_send = BUFFER_SIZE;
290  param.buffer_ptr_send = &TmpBuffer[0];
292 
293  NVIC_DisableIRQ(I2C_IRQn);
294  NVIC_ClearPendingIRQ(I2C_IRQn);
295  NVIC_EnableIRQ(I2C_IRQn);
296 
297  do {
298  isTxCompleted = false;
299  LPC_I2CD_API->i2c_master_transmit_intr(i2c_handle, &param, &result);
300  while (!isTxCompleted) {}
301  } while (error_code);
302 
303  /* Receive buffer from slave with 10-bit addressing mode */
304  Buffer[0] = ((I2C_SLAVE_ADDR_10BIT >> 7) & 0x06) | 0xF0;
305 
306  param.num_bytes_send = 2;
307  param.buffer_ptr_send = &TmpBuffer[0];
308  param.num_bytes_recv = BUFFER_SIZE;
309  param.buffer_ptr_recv = &Buffer[0];
311 
312  NVIC_DisableIRQ(I2C_IRQn);
313  NVIC_ClearPendingIRQ(I2C_IRQn);
314  NVIC_EnableIRQ(I2C_IRQn);
315 
316  do {
317  isTxRxCompleted = false;
318  LPC_I2CD_API->i2c_master_tx_rx_intr(i2c_handle, &param, &result);
319  while (!isTxRxCompleted) {}
320  } while (error_code);
321 
322  /* Verify */
324 }
325 
326 #else
327 /* Slave Polling Mode */
328 static void App_I2C_Slave_Polling(void)
329 {
330  /* Receive an array of bytes from master */
331  /* Initialize buffer */
334 
335  param.num_bytes_recv = BUFFER_SIZE;
336  param.buffer_ptr_recv = &Buffer[0];
337  param.stop_flag = 1;
338  do {
339  error_code = LPC_I2CD_API->i2c_slave_receive_poll(i2c_handle, &param, &result);
340  } while (error_code);
341 
342  /* Verify */
344 
345  /* Transmit the buffer received */
346  param.num_bytes_send = BUFFER_SIZE - 1;
347  param.buffer_ptr_send = &Buffer[1];
348  param.stop_flag = 1;
349  do {
350  error_code = LPC_I2CD_API->i2c_slave_transmit_poll(i2c_handle, &param, &result);
351  } while (error_code);
352 
353  /* Receive an array of byte from master; if Buffer[1] is equal to 0xBA, send the received buffer to master */
354  /* Initialize buffer */
356 
357  param.num_bytes_recv = BUFFER_SIZE;
358  param.buffer_ptr_recv = &Buffer[0];
359  param.stop_flag = 1;
360  do {
361  error_code = LPC_I2CD_API->i2c_slave_receive_poll(i2c_handle, &param, &result);
362  } while (error_code);
363 
364  if (Buffer[1] == 0xBA) {
365  param.num_bytes_send = BUFFER_SIZE - 1;
366  param.buffer_ptr_send = &Buffer[1];
367  param.stop_flag = 1;
368  do {
369  error_code = LPC_I2CD_API->i2c_slave_transmit_poll(i2c_handle, &param, &result);
370  } while (error_code);
371  }
372 }
373 
374 /* Slave Interrupt Mode */
375 static void App_I2C_Slave_Interrupt(void)
376 {
377  /* Receive an array of bytes from master */
378  /* Initialize buffer */
381 
382  param.num_bytes_recv = BUFFER_SIZE;
383  param.buffer_ptr_recv = &Buffer[0];
385  param.stop_flag = 1;
386 
387  NVIC_DisableIRQ(I2C_IRQn);
388  NVIC_ClearPendingIRQ(I2C_IRQn);
389  NVIC_EnableIRQ(I2C_IRQn);
390 
391  do {
392  isRxCompleted = false;
393  LPC_I2CD_API->i2c_slave_receive_intr(i2c_handle, &param, &result);
394  while (!isRxCompleted) {}
395  } while (error_code);
396 
397  /* Verify */
399 
400  /* Transmit the buffer received */
401  param.num_bytes_send = BUFFER_SIZE - 1;
402  param.buffer_ptr_send = &TmpBuffer[1];
404  param.stop_flag = 1;
405 
406  do {
407  isTxCompleted = false;
408  LPC_I2CD_API->i2c_slave_transmit_intr(i2c_handle, &param, &result);
409  while (!isTxCompleted) {}
410  } while (error_code);
411 
412  /* Receive an array of byte from master; if Buffer[1] is equal to 0xBA, send the received buffer to master */
413  /* Initialize buffer */
415 
416  param.num_bytes_recv = BUFFER_SIZE;
417  param.buffer_ptr_recv = &Buffer[0];
419  param.stop_flag = 1;
420 
421  do {
422  isRxCompleted = false;
423  LPC_I2CD_API->i2c_slave_receive_intr(i2c_handle, &param, &result);
424  while (!isRxCompleted) {}
425  } while (error_code);
426 
427  if (Buffer[1] == 0xBA) {
428  param.num_bytes_send = BUFFER_SIZE - 1;
429  param.buffer_ptr_send = &Buffer[1];
431  param.stop_flag = 1;
432 
433  do {
434  isTxCompleted = false;
435  LPC_I2CD_API->i2c_slave_transmit_intr(i2c_handle, &param, &result);
436  while (!isTxCompleted) {}
437  } while (error_code);
438  }
439 }
440 
441 /* Slave Mode with 10-bit address */
442 static void App_I2C_Slave_10bitAddressTest(void)
443 {
444  /* Receive buffer from master */
445  /* Initialize buffer */
447 
448  param.num_bytes_recv = BUFFER_SIZE;
449  param.buffer_ptr_recv = &Buffer[0];
451  param.stop_flag = 1;
452 
453  NVIC_DisableIRQ(I2C_IRQn);
454  NVIC_ClearPendingIRQ(I2C_IRQn);
455  NVIC_EnableIRQ(I2C_IRQn);
456 
457  do {
458  isRxCompleted = false;
459  LPC_I2CD_API->i2c_slave_receive_intr(i2c_handle, &param, &result);
460  while (!isRxCompleted) {}
461  } while (error_code);
462 
463  /* Send received buffer back to master */
464  param.num_bytes_send = BUFFER_SIZE - 1; /* Only send data + 1 byte slave address(only LSB 8bits) */
465  param.buffer_ptr_send = &Buffer[1];
467  param.stop_flag = 1;
468 
469  do {
470  isTxCompleted = false;
471  LPC_I2CD_API->i2c_slave_transmit_intr(i2c_handle, &param, &result);
472  while (!isTxCompleted) {}
473  } while (error_code);
474 }
475 
476 #endif
477 
478 /*****************************************************************************
479  * Public functions
480  ****************************************************************************/
481 
486 void I2C_IRQHandler(void)
487 {
488 // Board_LED_Toggle(1);
489  LPC_I2CD_API->i2c_isr_handler(i2c_handle);
490 }
491 
496 void HW_Setup(void)
497 {
498  volatile uint32_t mem;
499 
500  /* Generic Initialization */
501  Board_Init();
502  Board_I2C_Init();
503  Chip_I2C_Init();
504 
505  /* Get the I2C memory size needed */
506  mem = LPC_I2CD_API->i2c_get_mem_size();
507 
508  /* Perform a sanity check on the storage allocation */
509  if (I2C_ROM_MEM_SIZE < (mem / sizeof(uint32_t))) {
510  spin_on_error();
511  }
512 
513  /* Setup the I2C */
515 
516  /* Check the API return value for a valid handle */
517  if (i2c_handle != NULL) {
518  /* initialize the I2C with the configuration parameters */
520  if (error_code) {
521  spin_on_error();
522  }
523  }
524 }
525 
530 int main(void) {
531  HW_Setup();
532 
533  Board_LED_Set(0, false);
534  Board_LED_Set(1, false);
535 
536 #if I2C_MASTER_MODE
540 
541 #else
542  error_code =
543  LPC_I2CD_API->i2c_set_slave_addr(i2c_handle,
544  ((I2C_SLAVE_ADDR_7BIT << 8) | (((I2C_SLAVE_ADDR_10BIT >> 7) & 0x06) | 0xF0)),
545  (0 | ((I2C_SLAVE_ADDR_10BIT & 0x0FF) << 8) ));
546  if (error_code) {
547  spin_on_error();
548  }
549 
550  App_I2C_Slave_Polling();
551  App_I2C_Slave_Interrupt();
552  App_I2C_Slave_10bitAddressTest();
553 
554 #endif
555  /* Show the blue LED if no errors occurs */
556  Board_LED_Set(1, true);
557 
558  while (1) {
559  __WFE();
560  }
561  return 0;
562 }
563