Thanks for theses questions and inputs.
We tried to make I2C block for Simulink as easy as possible, However as Manora mentioned, I2C is tricky ; prior knowledge on I2C BUS might help.
Let's reply point by point:
1. Address (7 or 10 bits, see figure)
The I2C block set the chip address using the 7 (or 10) bit address. Last bit (read/write) is set appropriately depending whether the next action following the « Write address » is a read or a write action. As Mysil mentioned (post above), data sheet of component might be confusing as some define the address using the 7-bit value, others define 8-bit address that takes account the last bit as with the BOSH BPM180 data sheet.
2. Several I2C blocks / Blocks sample time (see time offset on figure)
The I2C generated code handle I2C in background through interrupt and a state machine. (The Blocking mode in the GUI can override the “background” execution)
Background / Interrupt driven mode are interesting :
- It save MCU time (Background & Interrupt)
- It is safer : if the I2C Bus get stuck for any reasons, the overall model execution continue ; When one I2C block does not finish its sequence after, it free up the I2C BUS and reset its state (after 3 of its own sample time). In most case, the I2C will recover even after an important EM perturbation.
Price to pay » is the block output delay: The block does not wait for the end of I2C transfer. Block outputs are thus « delayed » by 1 « block » sample.
One I2C block allows addressing many chips.
However, it is possible to use several I2C blocks driving the same I2C peripheral/BUS. Using several I2C blocks allows addressing different chips with different rates.
Multiple I2C blocks with different rates are used within this example: The BMP180 sensor provides both pressure (P) and temperature (T). There is only one conversion unit within the BMP180 chip. User must initiate a conversion of either P or T, wait for end of conversion and read the result of that conversion.
Each conversion takes 4.5ms.
- one block (green on figure) reads the result T from the previous conversion and initiate a P conversion each 10ms, (block sample time set as [0.01], time offset not provided is 0 by default) while
- a second block (blue on figure) reads result P from the previous conversion and initiate a T conversion each 10ms with a delay of 5ms. (sample time set as [.01 .005])
Delay for each conversion is 5ms and fit with the 4.5ms requirement. (see[image]C:\M91449\MCHP_Blockset\doc\Figs\forum[/image]***
Sample time offset are not used very often with Simulink but this capability worth to be known for code generation.
To go further with the BPM180: The dynamic (rate of change) difference between T variations (slow) and P variations (fast in UAVs) is important. It might worth using only one I2C block setting the conversion command as a block input (i.e. not static value as with this example), and add the appropriate logic so as to convert P with a higher rate than T…
3. Blocks data are independent
With this blockset, data for each I2C (or SPI) blocks are isolated: data from each I2C blocks result from transaction initiated by itself. (This was different from the outdated « LK » blockset). The implementation you described is not Ok as you mentioned.
4. Several I2C block with the same sample rate
Using two I2C blocks at 1ms would be equivalent to one I2C block where the transaction sequence is the concatenation of the two I2C blocks.
We do not provide an estimated time of the transaction. User must make sure that BUS clock rate and component responsiveness/task comply with the sampling rate of the I2C blocks. ***
Lower rate tasks have lower priority thus jitter might appear for these tasks and might then violate the 4.5ms requirement for the BM180 conversion. If the mcu is heavily loaded, it might be safer to either add margins, check for end of conversion (see BMP180 doc), or place theses blocks within a higher rate with a custom logic to run theses at a lower rate..