Using : MBDToolbox 4.2.1,with hotfix for register access blocks.
Using: S32K144 LQFP-100, on proprietary hardware board
When setting the LPSPI_Config block to have a transfer size of 8 bits, I can pass an array of one UINT8 to the LPSPI_Master_Transfer block and the SPI bus correctly outputs the byte of data.
When I set the transfer size to 32 bits, and pass an array of 4 UNIT8 bytes, there is no SPI activity.
I have tracked this down to the generated code for the block. With a 32 bit wide transfer, the generated code is
/* S-Function (lpspi_s32k_master_transfer): '<Root>/LPSPI_Master_Transfer' */
{
/* Update the peripheral CS to select the slave you want to send data to */
LPSPI_DRV_SetPcs(1, LPSPI_PCS3, LPSPI_ACTIVE_LOW);
/* Send data */
LPSPI_DRV_MasterTransferBlocking(1,
&JVCB3_TEST_TOP_B.TmpSignalConversionAtLPSPI_Mast[0],
&JVCB3_TEST_TOP_B.LPSPI_Master_Transfer[0], 1, 50);
}
The problem is argument 4 of LPSPI_DRV_MasterTransferBlocking(). It should be 4, not one. I went through the pain of converting the test model to a compiling S32DS project, and manually changing this to 4 and compiling it produces the expected SPI transfers.
已解决! 转到解答。
Hello, @gmud1234 @glenndoiron
Sorry for the late answer! I have been investigating the issue that you have and indeed it is a bug on our side on how the transfer byte count value is computed (the 4th paramater of the LPSPI_DRV_MasterTransferBlocking function). This will be resolved as soon as possible in the next release which will be available soon.
Regards,
Stefan.
Hello, @gmud1234 @glenndoiron
Sorry for the late answer! I have been investigating the issue that you have and indeed it is a bug on our side on how the transfer byte count value is computed (the 4th paramater of the LPSPI_DRV_MasterTransferBlocking function). This will be resolved as soon as possible in the next release which will be available soon.
Regards,
Stefan.
Hello @glenndoiron,
The signature of the function LPSPI_DRV_MasterTransferBlocking requires that the data shall be transferred as an UINT8 array. So, if you want to send an UIN32_T value, you shall first cast that to an uint8_t * data type. The Simulink block expects such value data type and will compute automatically the size of the input array.
In this way, you could also send multiple bytes as a single transfer, in a combination with the Continous Transfer setting of the SPI_Config block.
If the transfer is not working, then the priorities of the interrupts shall be considered. When the timeout of the transfer action is computed, it uses the OSIF software component, which uses the PIT channel 3 as a timer for such computation. So the priorities of the PIT 3 > SPI > Step timer.
Hope this helps,
Marius
This was tested by first sending an array of 1 UINT8 (using a 1 input mux) with a frame size of 8 bits. This compiles and executes correctly.
I then switched to a frame size of 32 bits, and expanded the mux from 1 to 4 inputs. Simulink reports the output of the mux which is feeding the spi block to be "uint8 (4)", however the generated code with this configuration does not issue a byte count of 4, it issues a byte count of 1.
Additionally at the time I had the baud rate set to 10,000bps. When I manually changes the transfer size to 4 bytes, the compiled code executed without any issues. The actual transfer would take (setup time + 3.2ms); the SPI transfer timeout should be 50mS, and the step timer is 100mS.
I had/have a similar problem with data length set to 2 bytes (16 bits).
If I provide it with uint8[2], it calculates the length by dividing [2]/2 = 1, and sends nothing.
If I provide it with uint8[4], it calculates the length by dividing [4]/2 = 2,, it sends the first 2 bytes and ignores the second 2 bytes.
For 32 bit, I imagine you may need to provide it with 16 bytes, the first 4 bytes it will transmit, and ignore the other 12.
Not sure I understand what the option 'continuous transfer' does - it doesn't appear to be mentioned at all in the documentation that I have.
Hello @gmud1234 ,
The "Continous transfer" option, ensures that the CS pin is held on LOW for the entire Transfer length of n Bytes you want to send so that if you need to send 40bits of data, you put the data in a 5x uint8_t array and the selected device will "See" 40bits on data in one transfer.
@gmud1234 , @glenndoiron could you please send me one of your example models, so that I could have a look on how de example behaves?
Regards,
Marius
Top level model: JVCB3_TEST_TOP.
Change the MBD_S32K1xx_Config_Information to point to the COM port for your board (or switch to OpenSDA if you're using an evaluation board).
Go to Modelling tab and click on "Update Model".
Go to the "Apps" tab and click on Embedded Coder.
Click on "Build" and upload the model to the board. Observe that there is no SPI communication. Notice that the signal being fed into the LPSPI_Master_Transfer block is declared as "uint8 (4)" on the simulink model.
Navigate to the generated code at "<model root>\JVCB3_TEST_TOP_mbd_rtw\JVCB3_TEST_TOP.c"
Note on line 57:
/* Send data */
LPSPI_DRV_MasterTransferBlocking(1,
&JVCB3_TEST_TOP_B.TmpSignalConversionAtLPSPI_Master_TransferInport1[0],
&JVCB3_TEST_TOP_B.LPSPI_Master_Transfer[0], 1, 50);
}
And on line 42:
/* SignalConversion generated from: '<Root>/LPSPI_Master_Transfer' */
JVCB3_TEST_TOP_B.TmpSignalConversionAtLPSPI_Master_TransferInport1[0] =
rtb_byte_out;
JVCB3_TEST_TOP_B.TmpSignalConversionAtLPSPI_Master_TransferInport1[1] =
rtb_byte_out;
JVCB3_TEST_TOP_B.TmpSignalConversionAtLPSPI_Master_TransferInport1[2] =
rtb_byte_out;
JVCB3_TEST_TOP_B.TmpSignalConversionAtLPSPI_Master_TransferInport1[3] =
rtb_byte_out;
Navigate to JVCB3_TEST_TOP.h.
Note on line 37:
/* Block signals (default storage) */
typedef struct {
uint8_T TmpSignalConversionAtLPSPI_Master_TransferInport1[4];
uint8_T LPSPI_Master_Transfer[4]; /* '<Root>/LPSPI_Master_Transfer' */
} B_JVCB3_TEST_TOP_T;
The generated code is clearly a C array of 4 unit8's. However LPSPI_DRV_MasterTransferBlocking in being passed a length of 1 byte.
I tried with 8b frame size and continuous transfer checked and it seems to work fine. I didn't connect the bus to anything so there is no reply.
This is running on the S32K144 EVB. But I have been running it on a proprietary board with the same MCU with these settings.
I attached the simple model if you want to compare the SPI settings.
For what it's worth, the target tested SPI device in question is a PCB with a string of daisy chained 74164's and it wouldn't matter if CS is dropped between bytes or not. But my testing was done with continuous transfers enabled.
Also there are other devices on other SPI ports, which have 16-bit, 32-bit, and 64-bit frame sizes, and WILL have an issue if chip select is dropped between bytes, so its pretty important that this gets fixed