summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Sliwa <dominik.sliwa@toradex.com>2018-03-12 16:35:59 +0100
committerDominik Sliwa <dominik.sliwa@toradex.com>2018-03-12 16:39:42 +0100
commit4d55f719bb2ac2875ad736e10f22a70eac7c3284 (patch)
tree7c2e423d25266a69ee2cdb71b76e78b9fad77591
parent4a48136e9c6d55ff9d9427a91ef43d44d26333d7 (diff)
can, adc fixes
CAN: -clear CANINTF_TX on read, this improves TX performance, -fix possible race-condition and implement errata 5641 ADC -allow for non-bulk read Signed-off-by: Dominik Sliwa <dominik.sliwa@toradex.com>
-rw-r--r--drivers/fsl_dspi.c17
-rw-r--r--drivers/fsl_flexcan.c11
-rw-r--r--source/adc_task.c4
-rw-r--r--source/can_task.c60
-rw-r--r--source/can_task.h2
-rw-r--r--source/com_task.c131
-rw-r--r--source/com_task.h2
-rw-r--r--source/main.c40
8 files changed, 138 insertions, 129 deletions
diff --git a/drivers/fsl_dspi.c b/drivers/fsl_dspi.c
index 0da640a..cacb52a 100644
--- a/drivers/fsl_dspi.c
+++ b/drivers/fsl_dspi.c
@@ -1486,10 +1486,23 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
/* Decrease remaining receive byte count */
--handle->remainingReceiveByteCount;
- if (handle->remainingSendByteCount == 0){
+ if (handle->remainingSendByteCount == 0 && handle->rxData){
if ( *(handle->rxData - 2) == APALIS_TK1_K20_READ_INST)
{
base->PUSHR_SLAVE = registers[dataReceived];
+ switch (dataReceived)
+ {
+ 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;
+ }
}
else
{
@@ -1505,7 +1518,7 @@ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
}
else
{
- dataSend = dataReceived;
+ dataSend = 0x44;
}
--handle->remainingSendByteCount;
diff --git a/drivers/fsl_flexcan.c b/drivers/fsl_flexcan.c
index 6c7e0bd..09add9e 100644
--- a/drivers/fsl_flexcan.c
+++ b/drivers/fsl_flexcan.c
@@ -1281,6 +1281,7 @@ void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle)
/* Get current State of Message Buffer. */
switch (handle->mbState[result])
{
+#if 0
/* Solve Rx Data Frame. */
case kFLEXCAN_StateRxData:
status = FLEXCAN_ReadRxMb(base, result, handle->mbFrameBuf[result]);
@@ -1300,19 +1301,15 @@ void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle)
}
FLEXCAN_TransferAbortReceive(base, handle, result);
break;
-
+#endif
+ /* Solve Tx Remote Frame. */
+ case kFLEXCAN_StateTxRemote: /* fall through */
/* Solve Tx Data Frame. */
case kFLEXCAN_StateTxData:
status = kStatus_FLEXCAN_TxIdle;
FLEXCAN_TransferAbortSend(base, handle, result);
break;
- /* Solve Tx Remote Frame. */
- case kFLEXCAN_StateTxRemote:
- handle->mbState[result] = kFLEXCAN_StateRxRemote;
- status = kStatus_FLEXCAN_TxSwitchToRx;
- break;
-
default:
status = kStatus_FLEXCAN_UnHandled;
break;
diff --git a/source/adc_task.c b/source/adc_task.c
index 77d07af..3bb4714 100644
--- a/source/adc_task.c
+++ b/source/adc_task.c
@@ -111,8 +111,10 @@ void adc_task(void *pvParameters)
for (i = 0; i < ADC0_CHANNEL_CNT;i ++){
channel.channelNumber = adc0_channels[i];
gen_regs.adc[i] = do_adc_conversion(ADC0, &channel);
+ registers[APALIS_TK1_K20_ADC_CH0L + 2 * i] = gen_regs.adc[i] & 0xFF;
+ registers[APALIS_TK1_K20_ADC_CH0L + 2 * i + 1] = (gen_regs.adc[i] >> 8) & 0xFF;
}
- vTaskDelay(1);
+ vTaskDelay(5);
}
}
diff --git a/source/can_task.c b/source/can_task.c
index 82b0dda..205e397 100644
--- a/source/can_task.c
+++ b/source/can_task.c
@@ -60,13 +60,31 @@ static uint8_t data_buffer[2][APALIS_TK1_CAN_RX_BUF_SIZE][CAN_TRANSFER_BUF_LEN];
static struct can_registers can_regs[2];
uint8_t resume_can;
-void generate_can_irq(uint8_t id) {
+void generate_can_irq(uint8_t id)
+{
if (id == 0)
GPIO_TogglePinsOutput(GPIOB, 1u << 8u);
else
GPIO_TogglePinsOutput(GPIOE, 1u << 26u);
}
+void can_tx_notify_task(void *pvParameters)
+{
+ uint32_t ulInterruptStatus;
+
+ while(1){
+ xTaskNotifyWait( 0x00, 0xFFFFFFFF, &ulInterruptStatus, portMAX_DELAY);
+ if (ulInterruptStatus & 0x01) {
+ registers[APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_DEV_OFFSET(0)] |= CANINTF_TX;
+ generate_can_irq(0);
+ }
+ if (ulInterruptStatus & 0x02) {
+ registers[APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_DEV_OFFSET(1)] |= CANINTF_TX;
+ generate_can_irq(1);
+ }
+ }
+}
+
static void flexcan_callback0(CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData)
{
callback_message_t * cb = (callback_message_t*) userData;
@@ -82,9 +100,7 @@ static void flexcan_callback0(CAN_Type *base, flexcan_handle_t *handle, status_t
case kStatus_FLEXCAN_TxIdle:
if (TX_MESSAGE_BUFFER_NUM0 == result)
{
- /* write status and gen irq */
- registers[APALIS_TK1_K20_CANREG] |= CANINTF_TX;
- generate_can_irq(0);
+ xTaskNotifyFromISR(can_tx_notify_task_handle, 0x01, eSetBits, &reschedule);
}
break;
@@ -109,9 +125,7 @@ static void flexcan_callback1(CAN_Type *base, flexcan_handle_t *handle, status_t
case kStatus_FLEXCAN_TxIdle:
if (TX_MESSAGE_BUFFER_NUM0 == result)
{
- /* write status and gen irq */
- registers[APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_OFFSET] |= CANINTF_TX;
- generate_can_irq(1);
+ xTaskNotifyFromISR(can_tx_notify_task_handle, 0x02, eSetBits, &reschedule);
}
break;
@@ -142,15 +156,19 @@ static void CAN0_Init()
FLEXCAN_SetRxMbGlobalMask(CAN0, FLEXCAN_RX_MB_EXT_MASK(0x00, 0, 0));
FLEXCAN_SetRxFifoGlobalMask(CAN0, FLEXCAN_RX_MB_EXT_MASK(0x00, 0, 0));
- /* Setup Tx Message Buffer. */
- FLEXCAN_SetTxMbConfig(CAN0, TX_MESSAGE_BUFFER_NUM0, true);
-
- fifoConfig.idFilterNum = 1;
+ fifoConfig.idFilterNum = 0;
fifoConfig.idFilterTable = &fifoFilter;
fifoConfig.idFilterType = kFLEXCAN_RxFifoFilterTypeC;
fifoConfig.priority = kFLEXCAN_RxFifoPrioHigh;
FLEXCAN_SetRxFifoConfig(CAN0, &fifoConfig, true);
+ /* errata #5641 */
+ FLEXCAN_SetTxMbConfig(CAN0, TX_MESSAGE_BUFFER_NUM0 - 1, true);
+
+ /* Setup Tx Message Buffer. */
+ FLEXCAN_SetTxMbConfig(CAN0, TX_MESSAGE_BUFFER_NUM0, true);
+ memset(&can_regs[0], 0x00u,sizeof(struct can_registers));
+
PRINTF("CAN0 init done \r\n");
}
@@ -175,15 +193,19 @@ static void CAN1_Init()
FLEXCAN_SetRxMbGlobalMask(CAN1, FLEXCAN_RX_MB_EXT_MASK(0x00, 0, 0));
FLEXCAN_SetRxFifoGlobalMask(CAN1, FLEXCAN_RX_MB_EXT_MASK(0x00, 0, 0));
- /* Setup Tx Message Buffer. */
- FLEXCAN_SetTxMbConfig(CAN1, TX_MESSAGE_BUFFER_NUM0, true);
-
- fifoConfig.idFilterNum = 1;
+ fifoConfig.idFilterNum = 0;
fifoConfig.idFilterTable = &fifoFilter;
fifoConfig.idFilterType = kFLEXCAN_RxFifoFilterTypeC;
fifoConfig.priority = kFLEXCAN_RxFifoPrioHigh;
FLEXCAN_SetRxFifoConfig(CAN1, &fifoConfig, true);
+ /* errata #5641 */
+ FLEXCAN_SetTxMbConfig(CAN1, TX_MESSAGE_BUFFER_NUM0 - 1, true);
+
+ /* Setup Tx Message Buffer. */
+ FLEXCAN_SetTxMbConfig(CAN1, TX_MESSAGE_BUFFER_NUM0, true);
+ memset(&can_regs[0], 0x00u,sizeof(struct can_registers));
+
PRINTF("CAN1 init done \r\n");
}
uint8_t available_data[2];
@@ -244,7 +266,9 @@ void can0_task(void *pvParameters) {
while(1)
{
+ taskENTER_CRITICAL();
FLEXCAN_TransferReceiveFifoNonBlocking(CAN0, &flexcanHandle[0], &rxXfer);
+ taskEXIT_CRITICAL();
if (xSemaphoreTake(cb_msg.sem, portMAX_DELAY) == pdTRUE) {
if (cb_msg.async_status == pdTRUE) {
cb_msg.async_status = pdFALSE;
@@ -274,7 +298,9 @@ void can1_task(void *pvParameters) {
while(1)
{
+ taskENTER_CRITICAL();
FLEXCAN_TransferReceiveFifoNonBlocking(CAN1, &flexcanHandle[1], &rxXfer);
+ taskEXIT_CRITICAL();
if (xSemaphoreTake(cb_msg.sem, portMAX_DELAY) == pdTRUE) {
if (cb_msg.async_status == pdTRUE) {
cb_msg.async_status = pdFALSE;
@@ -363,7 +389,9 @@ uint8_t can0_transmit(){
txXfer.frame = &tx_frame[0];
txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM0;
+ taskENTER_CRITICAL();
FLEXCAN_TransferSendNonBlocking(CAN0, &flexcanHandle[0], &txXfer);
+ taskEXIT_CRITICAL();
return 0;
}
@@ -373,7 +401,9 @@ uint8_t can1_transmit(){
txXfer.frame = &tx_frame[1];
txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM0;
+ taskENTER_CRITICAL();
FLEXCAN_TransferSendNonBlocking(CAN1, &flexcanHandle[1], &txXfer);
+ taskEXIT_CRITICAL();
return 0;
}
diff --git a/source/can_task.h b/source/can_task.h
index 564f073..9ad77f9 100644
--- a/source/can_task.h
+++ b/source/can_task.h
@@ -12,8 +12,10 @@
TaskHandle_t can0_task_handle;
TaskHandle_t can1_task_handle;
+TaskHandle_t can_tx_notify_task_handle;
void can0_task(void *pvParameters);
void can1_task(void *pvParameters);
+void can_tx_notify_task(void *pvParameters);
int canx_registers(dspi_transfer_t *spi_transfer, int id);
void can_calculate_available_data(uint8_t id);
diff --git a/source/com_task.c b/source/com_task.c
index 1c814df..a141c40 100644
--- a/source/com_task.c
+++ b/source/com_task.c
@@ -4,7 +4,8 @@
#include "gpio_ext.h"
#include "adc_task.h"
-uint8_t registers[APALIS_TK1_K20_LAST_REG];
+volatile uint8_t registers[APALIS_TK1_K20_LAST_REG];
+volatile uint8_t regRxHandled;
/* Put FW version at known address in binary. Make it 32-bit to have room for the future*/
const uint32_t __attribute__((section(".FwVersion"), used)) fw_version = APALIS_TK1_K20_FW_VER;
@@ -180,92 +181,82 @@ void spi_task(void *pvParameters) {
g_dspi_edma_s_handle.userData = &cb_msg;
DSPI_SlaveTransferCreateHandleEDMA(SPI2, &g_dspi_edma_s_handle, SPI_callback, &cb_msg, &dspiEdmaSlaveRxHandle, &dspiEdmaSlaveTxHandle);
#endif
+ memset(registers, 0x00, APALIS_TK1_K20_LAST_REG);
registers[APALIS_TK1_K20_REVREG] = APALIS_TK1_K20_FW_VER;
GPIO_SetPinsOutput(GPIOA, 1u << 29u); /* INT2 idle */
slaveXfer.configFlags = kDSPI_SlaveCtar0;
-while(1){
- slaveXfer.txData = NULL;/* no MISO traffic*/
- slaveXfer.rxData = slaveRxData;
- slaveXfer.dataSize = 3;
- /* Wait for instructions from SoC */
- ret = DSPI_SlaveTransferNonBlocking(SPI2, &spi_handle, &slaveXfer);
- if ( ret == kStatus_Success) {
-
- xSemaphoreTake(cb_msg.sem, portMAX_DELAY);
- slaveXfer.txData = slaveTxData;
+ while(1){
+ slaveXfer.txData = NULL;/* no MISO traffic*/
slaveXfer.rxData = slaveRxData;
-
- if (slaveRxData[0] == APALIS_TK1_K20_READ_INST)
- {
- /* clear interrupt flags on read; */
- if ( slaveRxData[1] == APALIS_TK1_K20_IRQREG)
- {
- registers[APALIS_TK1_K20_IRQREG] = 0;
- }
- }
- else
- {
- if (slaveRxData[1] <= 0x05) {
- ret = general_registers(&slaveXfer);
- } else if ((slaveRxData[1] >= APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_DEV_OFFSET(0))
- && (slaveRxData[1] <= APALIS_TK1_K20_CAN_OUT_BUF_END + APALIS_TK1_K20_CAN_DEV_OFFSET(0))) {
- ret = canx_registers(&slaveXfer, 0);
-
- } else if ((slaveRxData[1] >= APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_DEV_OFFSET(1))
- && (slaveRxData[1] <= APALIS_TK1_K20_CAN_OUT_BUF_END + APALIS_TK1_K20_CAN_DEV_OFFSET(1))) {
- ret = canx_registers(&slaveXfer, 1);
+ slaveXfer.dataSize = 3;
+ /* Wait for instructions from SoC */
+ ret = DSPI_SlaveTransferNonBlocking(SPI2, &spi_handle, &slaveXfer);
+ if ( ret == kStatus_Success) {
+
+ xSemaphoreTake(cb_msg.sem, portMAX_DELAY);
+
+ slaveXfer.txData = slaveTxData;
+ slaveXfer.rxData = slaveRxData;
+ if (slaveRxData[0] != APALIS_TK1_K20_READ_INST) {
+ if (slaveRxData[1] <= 0x05) {
+ ret = general_registers(&slaveXfer);
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_DEV_OFFSET(0))
+ && (slaveRxData[1] <= APALIS_TK1_K20_CAN_OUT_BUF_END + APALIS_TK1_K20_CAN_DEV_OFFSET(0))) {
+ ret = canx_registers(&slaveXfer, 0);
+
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_DEV_OFFSET(1))
+ && (slaveRxData[1] <= APALIS_TK1_K20_CAN_OUT_BUF_END + APALIS_TK1_K20_CAN_DEV_OFFSET(1))) {
+ ret = canx_registers(&slaveXfer, 1);
#ifdef BOARD_USES_ADC
- } else if ((slaveRxData[1] >= APALIS_TK1_K20_ADCREG) && (slaveRxData[1] <= APALIS_TK1_K20_ADC_CH3H)) {
- ret = adc_registers(&slaveXfer);
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_ADCREG) && (slaveRxData[1] <= APALIS_TK1_K20_ADC_CH3H)) {
+ ret = adc_registers(&slaveXfer);
- } else if ((slaveRxData[1] >= APALIS_TK1_K20_TSCREG) && (slaveRxData[1] <= APALIS_TK1_K20_TSC_YPH)) {
- ret = tsc_registers(&slaveXfer);
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_TSCREG) && (slaveRxData[1] <= APALIS_TK1_K20_TSC_YPH)) {
+ ret = tsc_registers(&slaveXfer);
#endif
- } else if ((slaveRxData[1] >= APALIS_TK1_K20_GPIOREG) && (slaveRxData[1] <= APALIS_TK1_K20_GPIO_STA)) {
- ret = gpio_registers(&slaveXfer);
- } else {
- /* Register not defined */
- ret = -EINVAL;
- }
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_GPIOREG) && (slaveRxData[1] <= APALIS_TK1_K20_GPIO_STA)) {
+ ret = gpio_registers(&slaveXfer);
+ } else {
+ /* Register not defined */
+ ret = -EINVAL;
+ }
- if (ret <= 0) {
- slaveTxData[0] = TK1_K20_INVAL;
- slaveTxData[1] = ret;
- slaveTxData[2] = slaveRxData[0];
- slaveTxData[3] = slaveRxData[1];
- slaveTxData[4] = slaveRxData[2];
- slaveXfer.txData = slaveTxData;
- ret = 5;
- }
+ if (ret <= 0) {
+ slaveTxData[0] = TK1_K20_INVAL;
+ slaveTxData[1] = ret;
+ slaveTxData[2] = slaveRxData[0];
+ slaveTxData[3] = slaveRxData[1];
+ slaveTxData[4] = slaveRxData[2];
+ slaveXfer.txData = slaveTxData;
+ ret = 5;
+ }
- if (slaveRxData[0] == APALIS_TK1_K20_BULK_READ_INST)
- {
- slaveXfer.dataSize = ret;
- //retry_size = slaveXfer.dataSize;
- slaveXfer.rxData = slaveRxData; /* We're not expecting any MOSI traffic, but NULL messes up stuff */
+ if (slaveRxData[0] == APALIS_TK1_K20_BULK_READ_INST)
+ {
+ slaveXfer.dataSize = ret;
+ slaveXfer.rxData = NULL; /* We're not expecting any MOSI traffic, but NULL messes up stuff */
#ifdef SPI_DMA
- __disable_irq(); // just to make sure that high can irq rate will not interfere
- DSPI_SlaveTransferEDMA(SPI2, &g_dspi_edma_s_handle, &slaveXfer);
- __enable_irq();
+ DSPI_SlaveTransferEDMA(SPI2, &g_dspi_edma_s_handle, &slaveXfer);
#else
- DSPI_SlaveTransferNonBlocking(SPI2, &spi_handle, &slaveXfer);
+ DSPI_SlaveTransferNonBlocking(SPI2, &spi_handle, &slaveXfer);
#endif
- xSemaphoreTake(cb_msg.sem, portMAX_DELAY);
- if (resume_can != 0) {
- if (resume_can == 1) {
- vTaskResume(can0_task_handle);
- can_calculate_available_data(0);
- }
- else {
- vTaskResume(can1_task_handle);
- can_calculate_available_data(1);
+ xSemaphoreTake(cb_msg.sem, portMAX_DELAY);
+ if (resume_can != 0) {
+ if (resume_can == 1) {
+ vTaskResume(can0_task_handle);
+ can_calculate_available_data(0);
+ }
+ else {
+ vTaskResume(can1_task_handle);
+ can_calculate_available_data(1);
+ }
+ resume_can = 0;
}
- resume_can = 0;
}
}
+
}
}
}
-}
diff --git a/source/com_task.h b/source/com_task.h
index 72ca858..46728ac 100644
--- a/source/com_task.h
+++ b/source/com_task.h
@@ -165,7 +165,7 @@ struct register_struct {
uint16_t tsc_yp;
} gen_regs;
-extern uint8_t registers[APALIS_TK1_K20_LAST_REG];
+extern volatile uint8_t registers[APALIS_TK1_K20_LAST_REG];
extern uint8_t resume_can;
#endif /* COM_TASK_H_ */
diff --git a/source/main.c b/source/main.c
index ad4e82b..d2f86c2 100644
--- a/source/main.c
+++ b/source/main.c
@@ -56,29 +56,6 @@
#define CONTROLLER_ID kUSB_ControllerEhci0
#endif
-/* Task priorities. */
-#define debug_task_PRIORITY 1
-#define USB_HOST_INTERRUPT_PRIORITY (5U)
-
-/* Task handles */
-
-TaskHandle_t usb_task_handle;
-#ifdef SDK_DEBUGCONSOLE
-TaskHandle_t debug_task_handle;
-#endif
-
-
-/*!
- * @brief Debug task
- */
-#ifdef SDK_DEBUGCONSOLE
-static void debug_task(void *pvParameters) {
- for (;;) {
- vTaskDelay(10000);
- PRINTF("Alive\r\n");
- }
-}
-#endif
/*!
* @brief Application entry point.
*/
@@ -107,6 +84,11 @@ int main(void) {
PRINTF("create CAN1 task error\r\n");
}
+ if(xTaskCreate(can_tx_notify_task, "CAN_tx_notify_task", 64L / sizeof(portSTACK_TYPE), NULL, 3, &can_tx_notify_task_handle) != pdPASS)
+ {
+ PRINTF("create CAN TX notify task error\r\n");
+ }
+
#ifdef BOARD_USES_ADC
if(xTaskCreate(adc_task, "ADC_task", 1000L / sizeof(portSTACK_TYPE), NULL, 2, &adc_task_handle) != pdPASS)
{
@@ -119,18 +101,10 @@ int main(void) {
}
#endif
-#ifdef SDK_DEBUGCONSOLE
- if(xTaskCreate(debug_task, "Debug_task", configMINIMAL_STACK_SIZE, NULL, debug_task_PRIORITY, &debug_task_handle) != pdPASS)
- {
- PRINTF("create hello task error\r\n");
- }
-#endif
-
- NVIC_SetPriority(CAN0_ORed_Message_buffer_IRQn, 5u);
- NVIC_SetPriority(CAN1_ORed_Message_buffer_IRQn, 5u);
+ NVIC_SetPriority(CAN0_ORed_Message_buffer_IRQn, 6u);
+ NVIC_SetPriority(CAN1_ORed_Message_buffer_IRQn, 6u);
NVIC_SetPriority(SPI2_IRQn, 5u);
NVIC_SetPriority(DMA0_IRQn, 5u);
- NVIC_SetPriorityGrouping( 0 );
vTaskStartScheduler();
for(;;) { /* Infinite loop to avoid leaving the main function */