How to set i.MX RT FlexCAN receive message buffer Mask for range of IDs ?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to set i.MX RT FlexCAN receive message buffer Mask for range of IDs ?

Jump to solution
3,087 Views
Maciek
Contributor V

Hi, 

in FCAN receive block for i.MX RT we can only set Message Buffer number and there is no output port for the message ID. Also, it looks like we can define only specific ID for a specific Message Buffer in 'Message buffers initialization' section of FLEXCAN driver in Config Tools. 

We are using specific ID ranges for CAN communication between nodes. In earlier implementations using S32K116 and S32K118 we were able to set both: 'ID' and 'Message ID mask' for specific Message Buffer directly in the FCAN_Receive block for S32K...

How can we do the same in case of i.MX RT MBDT ? What is the intended workflow here ?

Thanks for help

Maciek

0 Kudos
1 Solution
2,951 Views
ioanapirjol
NXP Employee
NXP Employee

Hi @Maciek ,

I have attached an early patch with the modifications for the FlexCAN block, so the Frame ID Output port and Individual Mask should be available for use. For FlexCan we recommend you update to ConfigTools v10, since in v9 (which is for now used by the toolbox) the Frame ID is not set correctly in the generated code.

I have also added modifications for the issues mentioned here How to use LPI2C in transfer mode in i.MX RT  - the LPI2C Transfer Callback for master Non-blocking mode is now a separated block, so multiple master operations can be used.
I have also attached 2 examples for LPI2C containing combined read/write operations, for both blocking and non-blocking modes.

To use this patch, please copy the files contained in the archive to their respective location in the toolbox, by unzipping the attached in "mbdtbx_imxrt.zip" in <toolbox_path>\
Please let me know if you encounter any issues.

Kind Regards,
Ioana

View solution in original post

0 Kudos
7 Replies
3,069 Views
nxa11767
NXP Employee
NXP Employee

Hi @Maciek ,

 

In configuration tool you can define multiple message buffers and specify for the RX as frame ID the RX message ID mask. In current toolbox there is no option to specify the RX Message ID mask - as an workaround for now, you can use custom code and call the SDK functions for this: (and neither the configuration tool has this option).

void FLEXCAN_SetRxMbGlobalMask(CAN_Type *base, uint32_t mask); or

void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask); (this option should be collaborated with enabling the Rx Individual Mask option from MCUX Configuration Tool)

As for outputting the frame id for the receive block, is something that we did not considered but it can be added by us in the block.  

We'll include the fixes for the above issues in the next update for the IMXRT toolbox (that will probably be in first quarter of the next year). Please let me know if you need an early patch. And also if you notice other options that are missing and you require in your application.

Thank you,

Alexandra

 

0 Kudos
3,056 Views
Maciek
Contributor V

Hi @nxa11767

isn't easier to set the masks by writing explicitly to RXIMRn (Rx Individual Mask Register n) registers using Register Write blocks from the toolbox (for example in the Initialize Function block/subsystem) ?

And Yes, we are very interested in the patch that will enable us to read the message ID from particular Message Buffer. Please let me know when such patch (replacement block) may be available for testing!

On the other hand: is it possible to read the message ID using Register Read block inside the subsystem triggered by CAN Receive event (or it will be a conflict with the Toolbox driver implementation) ?

We have 3 groups (ID ranges) of CAN messages: 48 IDs each - so 64 individual message buffers without masking in iMX RT is not enough... 

Thanks for help

Maciek

0 Kudos
3,005 Views
nxa11767
NXP Employee
NXP Employee

Hi @Maciek ,

 

Yes, you can use the registers read/write blocks for both setting the RX mask and reading the message buffer id.

We plan to have an update on the IMXRT toolbox in March timeframe - but we'll try to have a fix for this till end of January for testing (maybe sooner).

Best regards,

Alexandra

0 Kudos
2,983 Views
Maciek
Contributor V

Thanks @nxa11767

please let me know as soon as the fix is available for testing.

I will remind You about this fix if there is no relevant info till the end of the month.

I've asked also in another thread about the possible support for i.MX RT1024 parts...

Thanks

Maciek

 

0 Kudos
2,952 Views
ioanapirjol
NXP Employee
NXP Employee

Hi @Maciek ,

I have attached an early patch with the modifications for the FlexCAN block, so the Frame ID Output port and Individual Mask should be available for use. For FlexCan we recommend you update to ConfigTools v10, since in v9 (which is for now used by the toolbox) the Frame ID is not set correctly in the generated code.

I have also added modifications for the issues mentioned here How to use LPI2C in transfer mode in i.MX RT  - the LPI2C Transfer Callback for master Non-blocking mode is now a separated block, so multiple master operations can be used.
I have also attached 2 examples for LPI2C containing combined read/write operations, for both blocking and non-blocking modes.

To use this patch, please copy the files contained in the archive to their respective location in the toolbox, by unzipping the attached in "mbdtbx_imxrt.zip" in <toolbox_path>\
Please let me know if you encounter any issues.

Kind Regards,
Ioana

0 Kudos
2,891 Views
Maciek
Contributor V

Hi @ioanapirjol  and @nxa11767 
thanks for quick patch and examples. After observing the generated code (patch applied) I have a few more questions:

1. LPI2C driver in 'transfer' mode. Block 'LPI2C_Data_Transfer' used for 'read' transfer. After block execution, output port 'Data_Rx' provides 'meaningless' data to the model until the end of the transfer. It means that the data from this port should be read/used after the end of the transfer (for example after some flag is set in transfer callback). Before the end of the transfer, this port provides old data, used in previously initiated transfer.
Am I right ? If not, how it works ?

2. If I'm right with the above: this single block, at the same time, tries to initiate the transfer and returns the data from the transfer. It would work in the simple case, like a constant read from a sensor (block called in every model_step()). But if we model more complex scenario like: at one time write, at another read, yet another read from a different register, etc. (block execution controlled by triggered subsystem or stateflow) - we always must initiate another (dummy) transfer only to read the updated 'Data_Rx' (when the transfer has finished, block execution returns the updated 'Data_Rx' but also initiates another transfer). It's not efficient and complicates the model (we must wait for the dummy transfer to finish, take into account the increase of the automatic address register in slave etc.).
Wouldn't be better to have a single block that simply returns the .data field of the 'transfer structure' ? We could execute it at the end of the transfer (in callback for example) without initiating another transfer. Am I missing anything here ?

3. The 'Transfer_Status' output in 'LPI2C_Transfer_Callback' block provides meaningless (for the current transfer) data until the callback is actually called (the transfer has finished). Before that - it outputs the status of the previous transfer.
Am I right ?

4. As I see: current implementation allows 2 types of master transfers: write bytes after slave address or read bytes after slave address. It doesn't allow read operation using scheme: 'slave_address/write + subaddress + repeated_start + slave_address/read + data_from_slave'. In the SDK's 'transfer structure' there are fields 'subaddress' and 'subaddressSize' that probably allow the above (please - confirm this: I can't find any description of these fields anywhere!). It's a very common method of accessing EEPROMs and other I2C slaves.
If I'm right with the above: why can't we set these fields ? It would require to generate only 2 additional lines of code (by the TLC) but implement important functionality of the SDK driver ? Is there any other way of initiating the 'read' operation with 'repeated start' ?

5. Questions 1,2,3 (above) are relevant to the LPSPI driver (in the same way).
Am I right ?

I will give you our feedback on CAN message buffers masks as soon as we check them...

Thanks
Maciek

0 Kudos
2,837 Views
ioanapirjol
NXP Employee
NXP Employee

Hi @Maciek,

1. Yes, that is correct - for the transfer to be considered complete and the received data to be accurate, the user callback function must be called - for that a synchronization mechanism between the data transfer block and the callback block should be used - a flag to signal that the callback has completed, otherwise it will most probably result in an LPI2C Busy Status, or the data will be outdated.


2. The problem here is that you need to make sure that the interrupt routine where the Receive is handled has finished (more precisely, the handle state has been reset to idle and transmission has thus completed - the reasoning is the same as in 1.) This may not happen immediately after the PC returns from the LPI2C_MasterTransferNonBlocking function. The callback function is invoked in the interrupt handler immediately after the LPI2C state has been reset to idle - so checking if the callback has been called should be a guarantee that the data is now available for use.

We plan to do a refactorization for the LPI2C Master Transfer in order to simplify the transmission: we are investigating the possibility of returning the received data using the Callback block instead of Data Transfer as you suggested - the Data Transfer block would then be used to update the transfer structure and start the transmission. Another approach we have in mind is adding the LPI2C_MasterTransferBlocking from the SDK, for the case where the user doesn't enable the Callback option in ConfigTools - this way the synchronization will be handled by the API, but you can still use the SDK transfer structure (you could try to use custom code to generate this behavior, to see if would benefit more your application).


3. The transfer status output will contain the last completed transfer status returned by the callback function - so yes, it can be considered outdated for the transfer that is in progress until the callback function is called and completed again.


4. You are correct about the operation scheme. In the current version of the toolbox, you can configure the subAddress, subaddressSize, and the flags fields of the master transfer structure with MCUXpresso ConfigTools, but this allows for only one initialization at the beginning of the program - we are aware of this limitation and plan to add those fields for next release as editable options in the LPI2C block, so that they can be updated as needed during transmission. My guess is that this update should solve the issue with the dummy transfers presented in (2), am I correct?


5. Yes, the approach is similar for the LPSPI peripheral.

Kind Regards,

Ioana

0 Kudos