ESOS32
ESOSOn32-bitProcessors
esos_stm32l4_i2c.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2019 J. W. Bruce ("AUTHOR(S)")"
3  * All rights reserved.
4  * (J. W. Bruce, jwbruce_AT_tntech.edu, Tennessee Tech University)
5  *
6  * Permission to use, copy, modify, and distribute this software and its
7  * documentation for any purpose, without fee, and without written agreement is
8  * hereby granted, provided that the above copyright notice, the following
9  * two paragraphs and the authors appear in all copies of this software.
10  *
11  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
12  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
13  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
14  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15  *
16  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
19  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
20  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
21  *
22  * Please maintain this header in its entirety when copying/modifying
23  * these files.
24  *
25  *
26  */
27 
28 
34 // Documentation for this file. If the \file tag isn't present,
35 // this file won't be documented.
42 /*** I N C L U D E S *************************************************/
43 #include "esos_stm32l4_i2c.h"
44 
45 #include <stdio.h>
46 
47 
48 /*** D E F I N E S *************************************************/
49 #define DEBUG(str) __esos_unsafe_PutString(str)
50 
51 /*** G L O B A L S *************************************************/
52 struct stTask __stChildTaskI2C, __stGrandChildTaskI2C;
53 uint8_t __esos_i2c_dataBytes[2];
54 
55 static char ac_debug[80];
56 
57 /*** T H E C O D E *************************************************/
58 
59 /*********************************************************
60  * Public functions intended to be called by other files *
61  *********************************************************/
62 
63 // Documentation for this file. If the \file tag is not present,
64 // this file will not be documented.
65 // Note: place this comment below the #if NUM_I2C_MODS so Doxygen
66 // will only see it once.
79 void __esos_i2c_hw_config(uint32_t u32_i2cbps) {
80  rcc_periph_clock_enable(RCC_I2C1);
81 
82  // this clock should have been enabled in stm32l4_tick.c
83  //rcc_periph_clock_enable(RCC_GPIOB);
84 
85  // This line is used in the f3 example, but it does not exist in l4
86  //rcc_set_i2c_clock_hsi(I2C1);
87  // will need to poke the register manually...
88  RCC_CCIPR |= 0x00002000;
89 
90  i2c_reset(I2C1);
91  /* Setup GPIO pin GPIO_USART2_TX/GPIO9 on GPIO port B for transmit. */
92  gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO8);
93  gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_100MHZ, GPIO8);
94  gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO9);
95  gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_100MHZ, GPIO9);
96  gpio_set_af(GPIOB, GPIO_AF4, GPIO8);
97  gpio_set_af(GPIOB, GPIO_AF4, GPIO9);
98  i2c_peripheral_disable(I2C1);
99  //configure ANFOFF DNF[3:0] in CR1
100  i2c_enable_analog_filter(I2C1);
101  i2c_set_digital_filter(I2C1, 0);
102  /* HSI is at 8Mhz */
103  i2c_set_speed(I2C1, u32_i2cbps, 8);
104  //configure No-Stretch CR1 (only relevant in slave mode)
105  i2c_enable_stretching(I2C1);
106  //addressing mode
107  i2c_set_7bit_addr_mode(I2C1);
108  i2c_set_own_7bit_slave_address(I2C1, 0);
109  // enable the TX interrupt
110  //i2c_enable_interrupt(I2C1, I2C_CR1_TXIE);
111  //i2c_enable_interrupt(I2C1, I2C_CR1_RXIE);
112  i2c_peripheral_enable(I2C1);
113  //sprintf(ac_debug," 4: 0x%08lx 0x%08lx 0x%08lx 0x%08lx", I2C1_CR1, I2C1_CR2, I2C1_ISR, I2C1_TXDR); DEBUG(ac_debug);
114 }
115 
138 ESOS_CHILD_TASK( __esos_i2c_hw_writeN, uint8_t u8_addr, uint8_t* pu8_d, uint8_t u8_cnt) {
139  static uint8_t u8_tempAddr;
140  static uint8_t* pu8_tempPtr;
141  static uint8_t u8_tempCnt;
142 
143 
144 
145 
146  ESOS_TASK_BEGIN();
147  //sprintf(ac_debug,"i2c_hw_writeN 1: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", I2C1_CR1, I2C1_CR2, I2C1_ISR, I2C1_ICR); DEBUG(ac_debug);
148  ESOS_TASK_WAIT_WHILE( __ESOS_I2C_STM32L4_IS_BUSY() );
149  CLEAR_REGISTER_BITS(I2C1_CR2, I2C_CR2_SADD_7BIT_MASK | I2C_CR2_NBYTES_MASK | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP );
150 
151 
152  // __ESOS_I2C_STM32L4_RESET_CR2();
153  //sprintf(ac_debug," 2: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", I2C1_CR1, I2C1_CR2, I2C1_ISR, I2C1_ICR); DEBUG(ac_debug);
154 
155  u8_tempAddr=u8_addr;
156  pu8_tempPtr=pu8_d;
157  u8_tempCnt=u8_cnt;
158 
159  __ESOS_I2C_STM32L4_SET_ADDR7_MODE();
160  __ESOS_I2C_STM32L4_SET_ADDR7(MAKE_I2C_WR_ADDR(u8_tempAddr));
161  __ESOS_I2C_STM32L4_SET_WRITE_DIR();
162  __ESOS_I2C_STM32L4_SET_NUM_BYTES(u8_cnt);
163  __ESOS_I2C_STM32L4_SET_AUTOEND();
164  //sprintf(ac_debug," 3: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", I2C1_CR1, I2C1_CR2, I2C1_ISR, I2C1_ICR); DEBUG(ac_debug);
165 
166  //i2c_peripheral_enable(I2C1);
167  //i2c_send_start(I2C1);
168  I2C1_CR2 |= I2C_CR2_START;
169 
170 
171  //sprintf(ac_debug," 4: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", I2C1_CR1, I2C1_CR2, I2C1_ISR, I2C1_ICR); DEBUG(ac_debug);
172  while (u8_tempCnt--) {
173  /*ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM();
174  ESOS_TASK_WAIT_ON_SEND_STRING("TX NOT EMPTY \n");
175  ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM();*/
176 
177  //ESOS_TASK_WAIT_WHILE( __ESOS_I2C_STM32L4_IS_NACK_RECEIVED());
178  // sprintf(ac_debug," 5: 0x%08lx 0x%08lx 0x%08lx 0x%08lx", I2C1_CR1, I2C1_CR2, I2C1_ISR, I2C1_TXDR); DEBUG(ac_debug);
179  ESOS_TASK_WAIT_UNTIL( __ESOS_I2C_STM32L4_IS_TX_EMPTY() );
180 
182  ESOS_TASK_WAIT_ON_SEND_STRING("TX EMPTY\n\r");
184 
185  //i2c_send_data(I2C1, *pu8_tempPtr++);
186 
187  //sprintf(ac_debug," 6: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n\r", I2C1_CR1, I2C1_CR2, I2C1_ISR, I2C1_TXDR); DEBUG(ac_debug);
188  I2C1_TXDR = *pu8_tempPtr;
189  pu8_tempPtr++;
190 
191  //I2C1_CR2 |= I2C_CR2_START;
192 
193  //I2C1_ICR &= I2C_ICR_NACKCF;
194  } // end-while
195  // HAL code in HAL_I2C_Master_Transmit (and family ref manual) says:
196  // NO need to check TC flag with AUTOEND mode, the STOP is
197  // automatically generated.
198  //DEBUG("7\n");
199  // clear the STOP flag (HAL code does this)
200  __ESOS_I2C_STM32L4_CLEAR_STOP_FLAG();
201  // reset CR2 register (HAL code does this)
202  __ESOS_I2C_STM32L4_RESET_CR2();
203 
204  ESOS_TASK_END();
205 } // end __esos_i2c_hw_writeN
206 
217 ESOS_CHILD_TASK( __esos_i2c_hw_readN, uint8_t u8_addr, uint8_t* pu8_d, uint8_t u8_cnt) {
218  static uint8_t u8_tempAddr;
219  static uint8_t* pu8_tempD;
220  static uint8_t u8_tempCnt, u8_i;
221 
222  ESOS_TASK_BEGIN();
223  ESOS_TASK_WAIT_WHILE( __ESOS_I2C_STM32L4_IS_BUSY() );
224  u8_tempAddr = u8_addr;
225  pu8_tempD = pu8_d;
226  u8_tempCnt = u8_cnt;
227 
228  //__ESOS_I2C_STM32L4_SET_ADDR7_MODE();
229  __ESOS_I2C_STM32L4_SET_ADDR7(u8_tempAddr);
230  __ESOS_I2C_STM32L4_SET_READ_DIR();
231  __ESOS_I2C_STM32L4_SET_NUM_BYTES(u8_cnt);
232 
233  I2C1_CR2 |= I2C_CR2_START;
234  // enable AUTOEND after the START to get REPEATED START
235  __ESOS_I2C_STM32L4_SET_AUTOEND();
236  for (u8_i=0; u8_i < u8_tempCnt; u8_i++) {
237  //sprintf(ac_debug," 6: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n\r", I2C1_CR1, I2C1_CR2, I2C1_ISR, I2C1_RXDR); DEBUG(ac_debug);
238 
239  /*ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM();
240  ESOS_TASK_WAIT_ON_SEND_STRING("RX EMPTY \n\r ");
241  ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM();*/
242 
243  ESOS_TASK_WAIT_UNTIL( __ESOS_I2C_STM32L4_IS_RX_NOT_EMPTY() );
244 
245  /*ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM();
246  ESOS_TASK_WAIT_ON_SEND_STRING("RX NOT EMPTY \n\r ");
247  ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM();*/
248 
249  //sprintf(ac_debug," 7: 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n\r", I2C1_CR1, I2C1_CR2, I2C1_ISR, I2C1_RXDR); DEBUG(ac_debug);
250  *pu8_tempD = I2C1_RXDR;
251  pu8_tempD++;
252  //I2C1_RXDR = 0;
253  } // end-for
254 
255  // HAL code in HAL_I2C_Master_Transmit (and family ref manual) says:
256  // NO need to check TC flag with AUTOEND mode, the STOP is
257  // automatically generated.
258 
259  // clear the STOP flag (HAL code does this)
260  __ESOS_I2C_STM32L4_CLEAR_STOP_FLAG();
261  // reset CR2 register (HAL code does this)
262  __ESOS_I2C_STM32L4_RESET_CR2();
263 
264  ESOS_TASK_END();
265 } // end __esos_i2c_hw_readN
266 
297 ESOS_CHILD_TASK( __esos_i2c_hw_writeNReadM, uint8_t u8_addr, uint8_t* pu8_wd, uint8_t u8_wcnt, uint8_t* pu8_rd, uint8_t u8_rcnt) {
298  static uint8_t u8_tempAddr;
299  static uint8_t* pu8_tempWPtr;
300  static uint8_t u8_tempWCnt;
301  static uint8_t* pu8_tempRPtr;
302  static uint8_t u8_tempRCnt;
303 
304  // make local copies of the arguments
305  u8_tempAddr=u8_addr;
306  pu8_tempWPtr=pu8_wd;
307  u8_tempWCnt=u8_wcnt;
308  pu8_tempRPtr=pu8_rd;
309  u8_tempRCnt=u8_rcnt;
310 
311 
312 
313  ESOS_TASK_BEGIN();
314  ESOS_TASK_WAIT_WHILE( __ESOS_I2C_STM32L4_IS_BUSY() );
315  CLEAR_REGISTER_BITS(I2C1_CR2, I2C_CR2_SADD_7BIT_MASK | I2C_CR2_NBYTES_MASK | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP );
316 
317  __ESOS_I2C_STM32L4_SET_ADDR7_MODE();
318  __ESOS_I2C_STM32L4_SET_ADDR7(MAKE_I2C_WR_ADDR(u8_tempAddr));
319  __ESOS_I2C_STM32L4_SET_WRITE_DIR();
320  __ESOS_I2C_STM32L4_SET_NUM_BYTES(u8_wcnt);
321  __ESOS_I2C_STM32L4_SET_AUTOEND();
322 
323  I2C1_CR2 |= I2C_CR2_START;
324 
325  while (u8_tempWCnt--) {
326  ESOS_TASK_WAIT_UNTIL( __ESOS_I2C_STM32L4_IS_TX_EMPTY() );
327  I2C1_TXDR = *pu8_tempWPtr;
328  pu8_tempWPtr++;
329  } // end-while
330 
331  // HAL code in HAL_I2C_Master_Transmit (and family ref manual) says:
332  // NO need to check TC flag with AUTOEND mode, the STOP is
333  // automatically generated.
334  // clear the STOP flag (HAL code does this)
335  __ESOS_I2C_STM32L4_CLEAR_STOP_FLAG();
336  // reset CR2 register (HAL code does this)
337  __ESOS_I2C_STM32L4_RESET_CR2();
338 
339  ESOS_TASK_END();
340 } // end __esos_i2c_hw_writeN
ESOS_TASK_WAIT_UNTIL
#define ESOS_TASK_WAIT_UNTIL(condition)
Definition: esos_task.h:335
ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM
#define ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM()
Definition: esos_comm.h:227
esos_stm32l4_i2c.h
This file contains routines which define, configure and allow use of the I2C service on the ST Microe...
__esos_i2c_hw_config
void __esos_i2c_hw_config(uint32_t u32_i2cbps)
Definition: esos_hwxxx_i2c.c:74
ESOS_TASK_END
#define ESOS_TASK_END()
Definition: esos_task.h:271
ESOS_CHILD_TASK
#define ESOS_CHILD_TASK(taskname,...)
Definition: esos_task.h:246
ESOS_TASK_WAIT_ON_SEND_STRING
#define ESOS_TASK_WAIT_ON_SEND_STRING(psz_out)
Definition: esos_comm.h:414
ESOS_TASK_WAIT_WHILE
#define ESOS_TASK_WAIT_WHILE(cond)
Definition: esos_task.h:363
stTask
Definition: esos_task.h:54
ESOS_TASK_BEGIN
#define ESOS_TASK_BEGIN()
Definition: esos_task.h:259
ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM
#define ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM()
Definition: esos_comm.h:246