diff options
author | Dominik Sliwa <dominik.sliwa@toradex.com> | 2018-09-11 15:37:36 +0200 |
---|---|---|
committer | Dominik Sliwa <dominik.sliwa@toradex.com> | 2018-09-25 14:46:22 +0200 |
commit | 01010e72728a979b0a991576d1101d19829ecec5 (patch) | |
tree | e636978754c914767ca9df791c5164c2f2a9be31 /drivers | |
parent | 44b9ce104362ecc6b8850afbf97ce8007845c869 (diff) |
Improved CAN, locking and general IRQ performance
Fixes issues with CAN stopping when overwhelmed by data RX\TX.
Keeps can in freezemode until explicitly activated.
CANINTF_TX is now a CAN TX in progress flag.
Runtime asserts are now disabled.
Signed-off-by: Dominik Sliwa <dominik.sliwa@toradex.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/fsl_dspi.c | 23 | ||||
-rw-r--r-- | drivers/fsl_dspi_edma.c | 28 | ||||
-rw-r--r-- | drivers/fsl_flexcan.c | 108 | ||||
-rw-r--r-- | drivers/fsl_flexcan.h | 29 |
4 files changed, 125 insertions, 63 deletions
diff --git a/drivers/fsl_dspi.c b/drivers/fsl_dspi.c index 66f8974..1ec01b3 100644 --- a/drivers/fsl_dspi.c +++ b/drivers/fsl_dspi.c @@ -1445,7 +1445,7 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle) assert(handle); volatile uint32_t dataReceived; - uint32_t dataSend = 0; +// uint32_t dataSend = 0; /* Because SPI protocol is synchronous, the number of bytes that that slave received from the * master is the actual number of bytes that the slave transmitted to the master. So we only @@ -1492,25 +1492,26 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle) case APALIS_TK1_K20_IRQREG: registers[APALIS_TK1_K20_IRQREG] = 0; break; - case APALIS_TK1_K20_CANREG: - registers[APALIS_TK1_K20_CANREG] &= ~0x10; - break; - case APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_OFFSET: - registers[APALIS_TK1_K20_CANREG - + APALIS_TK1_K20_CAN_OFFSET] &= ~0x10; - break; + case APALIS_TK1_K20_CANERR: + registers[APALIS_TK1_K20_CANERR] = 0x00; + case APALIS_TK1_K20_CANERR + APALIS_TK1_K20_CAN_OFFSET: + registers[APALIS_TK1_K20_CANERR + + APALIS_TK1_K20_CAN_OFFSET] = 0x00; } } else { - base->PUSHR_SLAVE = 0x55; + if ( *(handle->rxData - 1) == APALIS_TK1_K20_READ_INST) + { + base->PUSHR_SLAVE = 0x55; + } } } } /* Decrease remaining receive byte count */ --handle->remainingReceiveByteCount; - +#ifndef SPI_DMA if (handle->remainingSendByteCount > 0) { if (handle->txData) @@ -1527,6 +1528,7 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle) /* Write the data to the DSPI data register */ base->PUSHR_SLAVE = dataSend; } +#endif #if 0 } else /* If bits/frame is 2 bytes */ @@ -1617,7 +1619,6 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle) if ((handle->remainingReceiveByteCount == 0) || (handle->state == kDSPI_Error)) { /* Other cases, stop the transfer. */ - dataReceived = base->POPR; DSPI_SlaveTransferComplete(base, handle); return; } diff --git a/drivers/fsl_dspi_edma.c b/drivers/fsl_dspi_edma.c index fa26b2f..2b91cdc 100644 --- a/drivers/fsl_dspi_edma.c +++ b/drivers/fsl_dspi_edma.c @@ -890,9 +890,9 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle handle->state = kDSPI_Busy; uint32_t instance = DSPI_GetInstance(base); - uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT; - handle->bitsPerFrame = - (((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1; + //uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT; + handle->bitsPerFrame = 8; + //(((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1; /* If using a shared RX/TX DMA request, then this limits the amount of data we can transfer * due to the linked channel. The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame @@ -1213,23 +1213,23 @@ static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle, extern dspi_slave_edma_handle_t g_dspi_edma_s_handle; static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle, - void *g_dspiEdmaPrivateHandle, - bool transferDone, - uint32_t tcds) + void *g_dspiEdmaPrivateHandle, + bool transferDone, + uint32_t tcds) { - assert(edmaHandle); + assert(edmaHandle); - DSPI_DisableDMA(SPI2, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); + DSPI_DisableDMA(SPI2, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); - g_dspi_edma_s_handle.state = kDSPI_Idle; + g_dspi_edma_s_handle.state = kDSPI_Idle; - if (g_dspi_edma_s_handle.callback) - { + if (g_dspi_edma_s_handle.callback) + { - g_dspi_edma_s_handle.callback(SPI2, &g_dspi_edma_s_handle, - kStatus_Success, g_dspi_edma_s_handle.userData); - } + g_dspi_edma_s_handle.callback(SPI2, &g_dspi_edma_s_handle, + kStatus_Success, g_dspi_edma_s_handle.userData); + } } #endif void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle) diff --git a/drivers/fsl_flexcan.c b/drivers/fsl_flexcan.c index 09add9e..2a07dc5 100644 --- a/drivers/fsl_flexcan.c +++ b/drivers/fsl_flexcan.c @@ -88,24 +88,6 @@ typedef void (*flexcan_isr_t)(CAN_Type *base, flexcan_handle_t *handle); */ uint32_t FLEXCAN_GetInstance(CAN_Type *base); -/*! - * @brief Enter FlexCAN Freeze Mode. - * - * This function makes the FlexCAN work under Freeze Mode. - * - * @param base FlexCAN peripheral base address. - */ -static void FLEXCAN_EnterFreezeMode(CAN_Type *base); - -/*! - * @brief Exit FlexCAN Freeze Mode. - * - * This function makes the FlexCAN leave Freeze Mode. - * - * @param base FlexCAN peripheral base address. - */ -static void FLEXCAN_ExitFreezeMode(CAN_Type *base); - #if !defined(NDEBUG) /*! * @brief Check if Message Buffer is occupied by Rx FIFO. @@ -117,7 +99,7 @@ static void FLEXCAN_ExitFreezeMode(CAN_Type *base); */ static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx); #endif - +#if 0 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) /*! * @brief Get the first valid Message buffer ID of give FlexCAN instance. @@ -129,7 +111,7 @@ static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx); */ static uint32_t FLEXCAN_GetFirstValidMb(CAN_Type *base); #endif - +#endif /*! * @brief Check if Message Buffer interrupt is enabled. * @@ -214,7 +196,7 @@ uint32_t FLEXCAN_GetInstance(CAN_Type *base) return instance; } -static void FLEXCAN_EnterFreezeMode(CAN_Type *base) +void FLEXCAN_EnterFreezeMode(CAN_Type *base) { /* Set Freeze, Halt bits. */ base->MCR |= CAN_MCR_HALT_MASK; @@ -225,7 +207,7 @@ static void FLEXCAN_EnterFreezeMode(CAN_Type *base) } } -static void FLEXCAN_ExitFreezeMode(CAN_Type *base) +void FLEXCAN_ExitFreezeMode(CAN_Type *base) { /* Clear Freeze, Halt bits. */ base->MCR &= ~CAN_MCR_HALT_MASK; @@ -279,7 +261,7 @@ static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx) } } #endif - +#if 0 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) static uint32_t FLEXCAN_GetFirstValidMb(CAN_Type *base) { @@ -298,6 +280,7 @@ static uint32_t FLEXCAN_GetFirstValidMb(CAN_Type *base) return firstValidMbNum; } #endif +#endif static bool FLEXCAN_IsMbIntEnabled(CAN_Type *base, uint8_t mbIdx) { @@ -487,6 +470,9 @@ void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourc mcrTemp = (config->enableDoze) ? mcrTemp | CAN_MCR_DOZE_MASK : mcrTemp & ~CAN_MCR_DOZE_MASK; #endif + mcrTemp |= CAN_MCR_HALT_MASK; + mcrTemp |= CAN_MCR_FRZ_MASK; + /* Save MCR Configuation. */ base->MCR = mcrTemp; @@ -539,6 +525,10 @@ void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *conf { /* Assertion. */ assert(config); + int keep_frozen = 0; + + if (base->MCR & CAN_MCR_FRZACK_MASK) + keep_frozen = 1; /* Enter Freeze Mode. */ FLEXCAN_EnterFreezeMode(base); @@ -553,24 +543,65 @@ void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *conf CAN_CTRL1_PSEG1(config->phaseSeg1) | CAN_CTRL1_PSEG2(config->phaseSeg2) | CAN_CTRL1_PROPSEG(config->propSeg)); /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); + if (!keep_frozen) + FLEXCAN_ExitFreezeMode(base); } void FLEXCAN_SetBitRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Bps) { + int keep_frozen = 0; + + if (base->MCR & CAN_MCR_FRZACK_MASK) + keep_frozen = 1; + /* Enter Freeze Mode. */ FLEXCAN_EnterFreezeMode(base); FLEXCAN_SetBaudRate(base, sourceClock_Hz, baudRate_Bps); /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); + if (!keep_frozen) + FLEXCAN_ExitFreezeMode(base); +} + +void FLEXCAN_SetMode(CAN_Type *base, uint32_t mode) +{ + int keep_frozen = 0; + + if (base->MCR & CAN_MCR_FRZACK_MASK) + keep_frozen = 1; + /* Enter Freeze Mode. */ + FLEXCAN_EnterFreezeMode(base); + switch (mode){ + case CAN_CTRLMODE_3_SAMPLES: + base->CTRL1 &= ~CAN_CTRL1_LPB_MASK; + base->CTRL1 &= ~CAN_CTRL1_LOM_MASK; + base->CTRL1 |= CAN_CTRL1_SMP_MASK; + break; + case CAN_CTRLMODE_LISTENONLY: + base->CTRL1 &= ~CAN_CTRL1_LPB_MASK; + base->CTRL1 &= ~CAN_CTRL1_SMP_MASK; + base->CTRL1 |= CAN_CTRL1_LOM_MASK; + break; + case CAN_CTRLMODE_LOOPBACK: + base->CTRL1 &= ~CAN_CTRL1_SMP_MASK; + base->CTRL1 &= ~CAN_CTRL1_LOM_MASK; + base->CTRL1 |= CAN_CTRL1_LPB_MASK; + break; + case CAN_CTRLMODE_NORMAL: + base->CTRL1 &= ~CAN_CTRL1_LPB_MASK; + base->CTRL1 &= ~CAN_CTRL1_LOM_MASK; + base->CTRL1 &= ~CAN_CTRL1_SMP_MASK; + } + /* Exit Freeze Mode. */ + if (!keep_frozen) + FLEXCAN_ExitFreezeMode(base); } void FLEXCAN_SetRxMbGlobalMask(CAN_Type *base, uint32_t mask) { /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); + //FLEXCAN_EnterFreezeMode(base); /* Setting Rx Message Buffer Global Mask value. */ base->RXMGMASK = mask; @@ -578,19 +609,19 @@ void FLEXCAN_SetRxMbGlobalMask(CAN_Type *base, uint32_t mask) base->RX15MASK = mask; /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); + //FLEXCAN_ExitFreezeMode(base); } void FLEXCAN_SetRxFifoGlobalMask(CAN_Type *base, uint32_t mask) { /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); + //FLEXCAN_EnterFreezeMode(base); /* Setting Rx FIFO Global Mask value. */ base->RXFGMASK = mask; /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); + //FLEXCAN_ExitFreezeMode(base); } void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask) @@ -678,7 +709,7 @@ void FLEXCAN_SetRxFifoConfig(CAN_Type *base, const flexcan_rx_fifo_config_t *con uint8_t setup_mb, i, rffn = 0; /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); + //FLEXCAN_EnterFreezeMode(base); if (enable) { @@ -771,7 +802,7 @@ void FLEXCAN_SetRxFifoConfig(CAN_Type *base, const flexcan_rx_fifo_config_t *con } base->MCR |= CAN_MCR_SRXDIS_MASK; /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); + //FLEXCAN_ExitFreezeMode(base); } #if (defined(FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA) && FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA) @@ -843,8 +874,8 @@ status_t FLEXCAN_WriteTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_frame_t base->MB[mbIdx].CS = cs_temp; #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) - base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive); - base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive); + base->MB[8].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive); + base->MB[8].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive); #endif return kStatus_Success; @@ -1162,7 +1193,7 @@ void FLEXCAN_TransferAbortSend(CAN_Type *base, flexcan_handle_t *handle, uint8_t assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); /* Disable Message Buffer Interrupt. */ - FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx); + //FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx); /* Un-register handle. */ handle->mbFrameBuf[mbIdx] = 0x0; @@ -1214,6 +1245,7 @@ void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle) status_t status = kStatus_FLEXCAN_UnHandled; uint32_t result; + BaseType_t reschedule = pdFALSE; /* Store Current FlexCAN Module Error and Status. */ result = base->ESR1; @@ -1234,7 +1266,7 @@ void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle) else { /* For this implementation, we solve the Message with lowest MB index first. */ - for (result = 0; result < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); result++) + for (result = 0; result < 10/* FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) */; result++) { /* Get the lowest unhandled Message Buffer */ if ((FLEXCAN_GetMbStatusFlags(base, 1 << result)) && (FLEXCAN_IsMbIntEnabled(base, result))) @@ -1244,7 +1276,7 @@ void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle) } /* Does not find Message to deal with. */ - if (result == FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)) + if (result == 10) { break; } @@ -1323,7 +1355,8 @@ void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle) /* Calling Callback Function if has one. */ if (handle->callback != NULL) { - handle->callback(base, handle, status, result, handle->userData); + if (handle->callback(base, handle, status, result, handle->userData) == pdTRUE) + reschedule = pdTRUE; } /* Reset return status */ @@ -1341,6 +1374,7 @@ void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle) (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag | kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag)))); #endif + portYIELD_FROM_ISR(reschedule); } #if defined(CAN0) diff --git a/drivers/fsl_flexcan.h b/drivers/fsl_flexcan.h index e6baa93..40246fe 100644 --- a/drivers/fsl_flexcan.h +++ b/drivers/fsl_flexcan.h @@ -31,6 +31,8 @@ #define _FSL_FLEXCAN_H_ #include "fsl_common.h" +#include "FreeRTOS.h" +#include "task.h" /*! * @addtogroup flexcan_driver @@ -41,6 +43,11 @@ * Definitions *****************************************************************************/ +#define CAN_CTRLMODE_NORMAL 0x00 /* normal mode */ +#define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */ +#define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */ +#define CAN_CTRLMODE_3_SAMPLES 0x03 /* Triple sampling mode */ + /*! @name Driver version */ /*@{*/ /*! @brief FlexCAN driver version 2.2.0. */ @@ -400,7 +407,7 @@ typedef struct _flexcan_handle flexcan_handle_t; * If the status equals to other FlexCAN Message Buffer transfer status, the result is meaningless and should be * Ignored. */ -typedef void (*flexcan_transfer_callback_t)( +typedef BaseType_t (*flexcan_transfer_callback_t)( CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData); /*! @brief FlexCAN handle structure. */ @@ -487,6 +494,24 @@ void FLEXCAN_GetDefaultConfig(flexcan_config_t *config); */ /*! + * @brief Enter FlexCAN Freeze Mode. + * + * This function makes the FlexCAN work under Freeze Mode. + * + * @param base FlexCAN peripheral base address. + */ +void FLEXCAN_EnterFreezeMode(CAN_Type *base); + +/*! + * @brief Exit FlexCAN Freeze Mode. + * + * This function makes the FlexCAN leave Freeze Mode. + * + * @param base FlexCAN peripheral base address. + */ +void FLEXCAN_ExitFreezeMode(CAN_Type *base); + +/*! * @brief Sets the FlexCAN protocol timing characteristic. * * This function gives user settings to CAN bus timing characteristic. @@ -504,6 +529,8 @@ void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *conf void FLEXCAN_SetBitRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Bps); +void FLEXCAN_SetMode(CAN_Type *base, uint32_t mode); + /*! * @brief Sets the FlexCAN receive message buffer global mask. * |