Hello,
Few more findings:
6. SPI_PAL doesn't forward the isPcsContinuous option to LPSPI_DRV, but sets it false unconditionally, which significantly limits usage of the module.
7. LPSPI_SetBaudRate() doesn't allow to use scaler 0.
E.g.: I request 4MBit baudrate with 8MHz clock. This is possible with the following register values: SCKDIV = 0 (/2) and PRESCALE = 0 (/1). But LPSPI_SetBaudRate proceed to the next prescaler if low=0 and high=1:
low = 0;
high = 256;
while((high - low) > (uint32_t)1)
{
scaler = (low + high) / (uint32_t)2;
So there is now way scaler can be 0 in the current implementation. The following version allows scaler to be 0:
low = 0;
high = 256;
while((high - low) > (uint32_t)0)
{
scaler = (low + high) / (uint32_t)2;
Also the following lines are suspicious to me:
(void)LPSPI_SetDelay(base, LPSPI_SCK_TO_PCS, scaler >> 2U);
(void)LPSPI_SetDelay(base, LPSPI_PCS_TO_SCK, scaler >> 2U);
(void)LPSPI_SetDelay(base, LPSPI_BETWEEN_TRANSFER, scaler >> 2U);
I suppose bestScaler should be used instead. I.e.:
(void)LPSPI_SetDelay(base, LPSPI_SCK_TO_PCS, bestScaler >> 2U);
(void)LPSPI_SetDelay(base, LPSPI_PCS_TO_SCK, bestScaler >> 2U);
(void)LPSPI_SetDelay(base, LPSPI_BETWEEN_TRANSFER, bestScaler >> 2U);
Also there is a comment that we exit immediately if min_diff equals 0, but don't do this actually.
for (prescaler = (uint32_t)0; prescaler < (uint32_t)8; prescaler++)
The following patch fixes all the issues in that function:
--- ./lpspi_hw_access.c.orig 2018-04-26 00:55:11.489935500 -0700
+++ ./lpspi_hw_access.c 2018-04-26 01:13:37.033302300 -0700
@@ -496,11 +496,11 @@
scaler = 0; /* required to avoid compilation warning */
/* In all for loops, if min_diff = 0, the exit for loop*/
- for (prescaler = (uint32_t)0; prescaler < (uint32_t)8; prescaler++)
+ for (prescaler = (uint32_t)0; (min_diff != (uint32_t)0) && (prescaler < (uint32_t)8); prescaler++)
{
low = 0;
high = 256;
- while((high - low) > (uint32_t)1)
+ while((min_diff != (uint32_t)0) && ((high - low) > (uint32_t)0))
{
scaler = (low + high) / (uint32_t)2;
realBaudrate = (sourceClockInHz /
@@ -529,9 +529,9 @@
}
}
/* Add default values for delay between transfers, delay between sck to pcs and between pcs to sck. */
- (void)LPSPI_SetDelay(base, LPSPI_SCK_TO_PCS, scaler >> 2U);
- (void)LPSPI_SetDelay(base, LPSPI_PCS_TO_SCK, scaler >> 2U);
- (void)LPSPI_SetDelay(base, LPSPI_BETWEEN_TRANSFER, scaler >> 2U);
+ (void)LPSPI_SetDelay(base, LPSPI_SCK_TO_PCS, bestScaler >> 2U);
+ (void)LPSPI_SetDelay(base, LPSPI_PCS_TO_SCK, bestScaler >> 2U);
+ (void)LPSPI_SetDelay(base, LPSPI_BETWEEN_TRANSFER, bestScaler >> 2U);
/* Write the best baud rate scalar to the CCR.
* Note, no need to check for error since we've already checked to make sure the module is
I hope this will help.
Best regards,
Maksim.