summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Sliwa <dominik.sliwa@toradex.com>2017-04-05 14:00:11 +0200
committerDominik Sliwa <dominik.sliwa@toradex.com>2017-04-05 14:03:38 +0200
commitb3bc06bef795fdc57254729c74c04e2732a6092d (patch)
tree1582cb5edd1f6ebcdfed12d3bc43c62364fd2751
parent23a27e51577ded4d070794b864585829c69cdc56 (diff)
Apalis_TK1_K20: CAN support and version change
Includes CAN support and fw version bump to 0.9 Signed-off-by: Dominik Sliwa <dominik.sliwa@toradex.com>
-rw-r--r--source/can_task.c233
-rw-r--r--source/can_task.h17
-rw-r--r--source/com_task.c15
-rw-r--r--source/com_task.h65
-rw-r--r--source/main.c3
5 files changed, 299 insertions, 34 deletions
diff --git a/source/can_task.c b/source/can_task.c
new file mode 100644
index 0000000..de57090
--- /dev/null
+++ b/source/can_task.c
@@ -0,0 +1,233 @@
+
+#include "can_task.h"
+#include "com_task.h"
+#include "fsl_flexcan.h"
+
+#define RX_MESSAGE_BUFFER_NUM0 (9)
+#define TX_MESSAGE_BUFFER_NUM0 (8)
+#define RX_MESSAGE_BUFFER_NUM1 (7)
+#define TX_MESSAGE_BUFFER_NUM1 (6)
+
+static flexcan_handle_t flexcanHandle[2];
+static uint32_t txIdentifier[2];
+static uint32_t rxIdentifier[2];
+static volatile bool txComplete[2] = {false, false};
+static volatile bool rxComplete[2] = {false, false};
+
+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;
+ BaseType_t reschedule = pdFALSE;
+
+ switch (status)
+ {
+ case kStatus_FLEXCAN_RxIdle:
+ if (RX_MESSAGE_BUFFER_NUM0 == result)
+ {
+ xSemaphoreGiveFromISR(cb->sem, &reschedule);
+ }
+ break;
+
+ case kStatus_FLEXCAN_TxIdle:
+ if (TX_MESSAGE_BUFFER_NUM0 == result)
+ {
+ }
+ break;
+
+ default:
+ break;
+ }
+ portYIELD_FROM_ISR(reschedule);
+}
+
+static void flexcan_callback1(CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData)
+{
+ callback_message_t * cb = (callback_message_t*) userData;
+ BaseType_t reschedule = pdFALSE;
+
+ switch (status)
+ {
+ case kStatus_FLEXCAN_RxIdle:
+ if (RX_MESSAGE_BUFFER_NUM1 == result)
+ {
+ xSemaphoreGiveFromISR(cb->sem, &reschedule);
+ }
+ break;
+
+ case kStatus_FLEXCAN_TxIdle:
+ if (TX_MESSAGE_BUFFER_NUM1 == result)
+ {
+ }
+ break;
+
+ default:
+ break;
+ }
+ portYIELD_FROM_ISR(reschedule);
+}
+
+static void CAN_Init()
+{
+ flexcan_config_t flexcanConfig;
+ flexcan_rx_mb_config_t mbConfig;
+
+ txIdentifier[0] = 0x321;
+ rxIdentifier[0] = 0x123;
+ txIdentifier[1] = 0x123;
+ rxIdentifier[1] = 0x321;
+
+ /* Get FlexCAN module default Configuration. */
+ /*
+ * flexcanConfig.clkSrc = kFLEXCAN_ClkSrcOsc;
+ * flexcanConfig.baudRate = 125000U;
+ * flexcanConfig.maxMbNum = 16;
+ * flexcanConfig.enableLoopBack = false;
+ * flexcanConfig.enableSelfWakeup = false;
+ * flexcanConfig.enableIndividMask = false;
+ * flexcanConfig.enableDoze = false;
+ */
+ FLEXCAN_GetDefaultConfig(&flexcanConfig);
+
+ /* Init FlexCAN module. */
+ flexcanConfig.clkSrc = kFLEXCAN_ClkSrcPeri;
+ FLEXCAN_Init(CAN0, &flexcanConfig, CLOCK_GetFreq(kCLOCK_BusClk));
+
+ /* Create FlexCAN handle structure and set call back function. */
+ FLEXCAN_TransferCreateHandle(CAN0, &flexcanHandle[0], flexcan_callback0, flexcanHandle[0].userData);
+
+ /* Set Rx Masking mechanism. */
+ FLEXCAN_SetRxMbGlobalMask(CAN0, FLEXCAN_RX_MB_STD_MASK(rxIdentifier[0], 0, 0));
+
+ /* Setup Rx Message Buffer. */
+ mbConfig.format = kFLEXCAN_FrameFormatStandard;
+ mbConfig.type = kFLEXCAN_FrameTypeData;
+ mbConfig.id = FLEXCAN_ID_STD(rxIdentifier[0]);
+ FLEXCAN_SetRxMbConfig(CAN0, RX_MESSAGE_BUFFER_NUM0, &mbConfig, true);
+
+ /* Setup Tx Message Buffer. */
+ FLEXCAN_SetTxMbConfig(CAN0, TX_MESSAGE_BUFFER_NUM0, true);
+
+ /* Get FlexCAN module default Configuration. */
+ /*
+ * flexcanConfig.clkSrc = kFLEXCAN_ClkSrcOsc;
+ * flexcanConfig.baudRate = 125000U;
+ * flexcanConfig.maxMbNum = 16;
+ * flexcanConfig.enableLoopBack = false;
+ * flexcanConfig.enableSelfWakeup = false;
+ * flexcanConfig.enableIndividMask = false;
+ * flexcanConfig.enableDoze = false;
+ */
+ FLEXCAN_GetDefaultConfig(&flexcanConfig);
+
+ /* Init FlexCAN module. */
+ flexcanConfig.clkSrc = kFLEXCAN_ClkSrcPeri;
+ FLEXCAN_Init(CAN1, &flexcanConfig, CLOCK_GetFreq(kCLOCK_BusClk));
+
+ /* Create FlexCAN handle structure and set call back function. */
+ FLEXCAN_TransferCreateHandle(CAN1, &flexcanHandle[1], flexcan_callback1, flexcanHandle[1].userData);
+
+ /* Set Rx Masking mechanism. */
+ FLEXCAN_SetRxMbGlobalMask(CAN1, FLEXCAN_RX_MB_STD_MASK(rxIdentifier[1], 0, 0));
+
+ /* Setup Rx Message Buffer. */
+ mbConfig.format = kFLEXCAN_FrameFormatStandard;
+ mbConfig.type = kFLEXCAN_FrameTypeData;
+ mbConfig.id = FLEXCAN_ID_STD(rxIdentifier[1]);
+ FLEXCAN_SetRxMbConfig(CAN1, RX_MESSAGE_BUFFER_NUM1, &mbConfig, true);
+
+ mbConfig.format = kFLEXCAN_FrameFormatExtend;
+ mbConfig.type = kFLEXCAN_FrameTypeRemote;
+ mbConfig.id = FLEXCAN_ID_STD(txIdentifier[1]);
+ FLEXCAN_SetRxMbConfig(CAN1, RX_MESSAGE_BUFFER_NUM1, &mbConfig, true);
+
+
+ /* Setup Tx Message Buffer. */
+ FLEXCAN_SetTxMbConfig(CAN1, TX_MESSAGE_BUFFER_NUM1, true);
+ PRINTF("CAN init done \r\n");
+}
+
+
+void can_test_task(void *pvParameters) {
+ flexcan_frame_t txFrame, rxFrame;
+ flexcan_mb_transfer_t txXfer, rxXfer;
+ callback_message_t cb_msg[2];
+
+ cb_msg[0].sem = xSemaphoreCreateBinary();
+ cb_msg[1].sem = xSemaphoreCreateBinary();
+ flexcanHandle[0].userData = (void *) &cb_msg[0];
+ flexcanHandle[1].userData = (void *) &cb_msg[1];
+ CAN_Init();
+
+ vTaskSuspend(NULL);
+ rxXfer.frame = &rxFrame;
+ rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM1;
+ FLEXCAN_TransferReceiveNonBlocking(CAN1, &flexcanHandle[1], &rxXfer);
+
+ txFrame.format = kFLEXCAN_FrameFormatStandard;
+ txFrame.type = kFLEXCAN_FrameTypeData;
+ txFrame.id = FLEXCAN_ID_STD(0x321);
+ txFrame.length = 8;
+ txFrame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x11) | CAN_WORD0_DATA_BYTE_1(0x22) | CAN_WORD0_DATA_BYTE_2(0x33) |
+ CAN_WORD0_DATA_BYTE_3(0x44);
+ txFrame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x55) | CAN_WORD1_DATA_BYTE_5(0x66) | CAN_WORD1_DATA_BYTE_6(0x77) |
+ CAN_WORD1_DATA_BYTE_7(0x88);
+ txXfer.frame = &txFrame;
+ txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM0;
+
+ PRINTF("\r\nCAN0->CAN1 ");
+
+ FLEXCAN_TransferSendNonBlocking(CAN0, &flexcanHandle[0], &txXfer);
+ if (xSemaphoreTake(cb_msg[1].sem, 1000u) == pdFALSE)
+ {
+ PRINTF("FAIL!\r\n");
+ FLEXCAN_TransferAbortSend(CAN0, &flexcanHandle[0], txXfer.mbIdx);
+ FLEXCAN_TransferAbortReceive(CAN1, &flexcanHandle[1], rxXfer.mbIdx);
+ }
+ else
+ {
+ PRINTF("SUCCESS!\r\n");
+ }
+
+ rxXfer.frame = &rxFrame;
+ rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM0;
+ FLEXCAN_TransferReceiveNonBlocking(CAN0, &flexcanHandle[0], &rxXfer);
+
+ txFrame.format = kFLEXCAN_FrameFormatStandard;
+ txFrame.type = kFLEXCAN_FrameTypeData;
+ txFrame.id = FLEXCAN_ID_STD(0x123);
+ txFrame.length = 8;
+ txFrame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x11) | CAN_WORD0_DATA_BYTE_1(0x22) | CAN_WORD0_DATA_BYTE_2(0x33) |
+ CAN_WORD0_DATA_BYTE_3(0x44);
+ txFrame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x55) | CAN_WORD1_DATA_BYTE_5(0x66) | CAN_WORD1_DATA_BYTE_6(0x77) |
+ CAN_WORD1_DATA_BYTE_7(0x88);
+ txXfer.frame = &txFrame;
+ txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM1;
+
+ PRINTF("CAN1->CAN0 ");
+
+ FLEXCAN_TransferSendNonBlocking(CAN1, &flexcanHandle[1], &txXfer);
+ if (xSemaphoreTake(cb_msg[0].sem, 1000u ) == pdFALSE)
+ {
+ PRINTF("FAIL!\r\n");
+ FLEXCAN_TransferAbortSend(CAN1, &flexcanHandle[0], txXfer.mbIdx);
+ FLEXCAN_TransferAbortReceive(CAN0, &flexcanHandle[1], rxXfer.mbIdx);
+ }
+ else
+ {
+ PRINTF("SUCCESS!\r\n");
+ }
+
+ vSemaphoreDelete(cb_msg[0].sem);
+ vSemaphoreDelete(cb_msg[1].sem);
+
+ vTaskResume(spi_task_handle);
+ vTaskDelete(NULL);
+}
+
+int can0_registers(uint8_t *rx_buf, uint8_t *tx_buf){
+ return -EIO;
+}
+
+int can1_registers(uint8_t *rx_buf, uint8_t *tx_buf){
+ return -EIO;
+}
diff --git a/source/can_task.h b/source/can_task.h
new file mode 100644
index 0000000..9857e96
--- /dev/null
+++ b/source/can_task.h
@@ -0,0 +1,17 @@
+/*
+ * can_task.h
+ */
+
+#ifndef SOURCE_CAN_TASK_H_
+#define SOURCE_CAN_TASK_H_
+
+/* FreeRTOS kernel includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+TaskHandle_t can_task_handle;
+void can_test_task(void *pvParameters);
+int can0_registers(uint8_t *rx_buf, uint8_t *tx_buf);
+int can1_registers(uint8_t *rx_buf, uint8_t *tx_buf);
+
+#endif /* SOURCE_CAN_TASK_H_ */
diff --git a/source/com_task.c b/source/com_task.c
index 348c3e1..457066c 100644
--- a/source/com_task.c
+++ b/source/com_task.c
@@ -1,15 +1,15 @@
#include "com_task.h"
+#include "can_task.h"
#include "gpio_ext.h"
#include "adc_task.h"
/* Put FW version at known address in binary. Make it 32-bit to have room for the future*/
const uint32_t __attribute__((section(".FwVersion"))) fw_version = APALIS_TK1_K20_FW_VER;
-#define MAX_TRANSFER_SIZE 32U
static dspi_slave_handle_t spi_handle;
-static uint8_t slaveRxData[MAX_TRANSFER_SIZE] = {0U};
-static uint8_t slaveTxData[MAX_TRANSFER_SIZE] = {0U};
+static uint8_t slaveRxData[APALIS_TK1_K20_MAX_BULK] = {0U};
+static uint8_t slaveTxData[APALIS_TK1_K20_MAX_BULK] = {0U};
void generate_irq(uint8_t irq) {
gen_regs.irq = gen_regs.irq | BIT(irq);
@@ -67,7 +67,7 @@ void set_irq_reg(uint8_t value)
}
-int inline general_registers(uint8_t *rx_buf, uint8_t * tx_buf) {
+inline int general_registers(uint8_t *rx_buf, uint8_t * tx_buf) {
if (rx_buf[0] == APALIS_TK1_K20_READ_INST) {
switch (rx_buf[1]) {
@@ -173,6 +173,13 @@ void spi_task(void *pvParameters) {
xSemaphoreTake(cb_msg.sem, portMAX_DELAY);
if (slaveRxData[1] <= 0x05) {
ret = general_registers(slaveRxData, &slaveTxData[1]);
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_DEV_OFFSET(0))
+ && (slaveRxData[1] <= APALIS_TK1_K20_CAN_OUT_FIF0_END + APALIS_TK1_K20_CAN_DEV_OFFSET(0))) {
+ ret = can0_registers(slaveRxData, &slaveTxData[1]);
+
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_CANREG + APALIS_TK1_K20_CAN_DEV_OFFSET(1))
+ && (slaveRxData[1] <= APALIS_TK1_K20_CAN_OUT_FIF0_END + APALIS_TK1_K20_CAN_DEV_OFFSET(1))) {
+ ret = can1_registers(slaveRxData, &slaveTxData[1]);
#ifdef BOARD_USES_ADC
} else if ((slaveRxData[1] >= APALIS_TK1_K20_ADCREG) && (slaveRxData[1] <= APALIS_TK1_K20_ADC_CH3H)) {
ret = adc_registers(slaveRxData, &slaveTxData[1]);
diff --git a/source/com_task.h b/source/com_task.h
index 14c742e..fb6b679 100644
--- a/source/com_task.h
+++ b/source/com_task.h
@@ -51,44 +51,49 @@ void spi_task(void *pvParameters);
/* CAN Registers */
#define APALIS_TK1_K20_CANREG 0x10 /* CAN control & status register RW */
-#define APALIS_TK1_K20_CAN_BAUD_REG 0x11 /* CAN Baud set register RW */
-#define APALIS_TK1_K20_CAN_IN_BUF_CNT 0x12 /* CAN IN BUF Received Data Count RO */
-#define APALIS_TK1_K20_CAN_IN_BUF 0x13 /* CAN IN BUF RO */
-#define APALIS_TK1_K20_CAN_OUT_BUF_CNT 0x14 /* CAN OUT BUF Data Count WO, must be written before bulk write to APALIS_TK1_K20_CAN0_OUT_BUF_CNT */
-#define APALIS_TK1_K20_CAN_OUT_FIF0 0x15 /* CAN OUT BUF WO */
-
-#define APALIS_TK1_K20_CAN_DEV_OFFSET(x) (x ? 0:0x10)
+#define APALIS_TK1_K20_CANERR 0x11 /* Error register RW */
+#define APALIS_TK1_K20_CAN_BAUD_REG 0x12 /* CAN Baud set register RW */
+#define APALIS_TK1_K20_CAN_BIT_1 0x13 /* CAN Bittiming register 1 RW */
+#define APALIS_TK1_K20_CAN_BIT_2 0x14 /* CAN Bittiming register 2 RW */
+#define APALIS_TK1_K20_CAN_IN_BUF_CNT 0x15 /* CAN IN BUF Received Data Count RO */
+#define APALIS_TK1_K20_CAN_IN_BUF 0x16 /* CAN IN BUF RO */
+/* buffer size is 14 bytes */
+#define APALIS_TK1_K20_CAN_OUT_BUF_CNT 0x25 /* CAN OUT BUF Data Count WO */
+#define APALIS_TK1_K20_CAN_OUT_FIF0 0x26 /* CAN OUT BUF WO */
+/* buffer size is 14 bytes */
+#define APALIS_TK1_K20_CAN_OUT_FIF0_END 0x35 /* CAN OUT BUF END */
+#define APALIS_TK1_K20_CAN_DEV_OFFSET(x) (x ? 0 : 0x30)
/* ADC Registers */
-#define APALIS_TK1_K20_ADCREG 0x30 /* ADC control & status register RW */
-#define APALIS_TK1_K20_ADC_CH0L 0x31 /* ADC Channel 0 LSB RO */
-#define APALIS_TK1_K20_ADC_CH0H 0x32 /* ADC Channel 0 MSB RO */
-#define APALIS_TK1_K20_ADC_CH1L 0x33 /* ADC Channel 1 LSB RO */
-#define APALIS_TK1_K20_ADC_CH1H 0x34 /* ADC Channel 1 MSB RO */
-#define APALIS_TK1_K20_ADC_CH2L 0x35 /* ADC Channel 2 LSB RO */
-#define APALIS_TK1_K20_ADC_CH2H 0x36 /* ADC Channel 2 MSB RO */
-#define APALIS_TK1_K20_ADC_CH3L 0x37 /* ADC Channel 3 LSB RO */
-#define APALIS_TK1_K20_ADC_CH3H 0x38 /* ADC Channel 3 MSB RO */
+#define APALIS_TK1_K20_ADCREG 0x70 /* ADC control & status register RW */
+#define APALIS_TK1_K20_ADC_CH0L 0x71 /* ADC Channel 0 LSB RO */
+#define APALIS_TK1_K20_ADC_CH0H 0x72 /* ADC Channel 0 MSB RO */
+#define APALIS_TK1_K20_ADC_CH1L 0x73 /* ADC Channel 1 LSB RO */
+#define APALIS_TK1_K20_ADC_CH1H 0x74 /* ADC Channel 1 MSB RO */
+#define APALIS_TK1_K20_ADC_CH2L 0x75 /* ADC Channel 2 LSB RO */
+#define APALIS_TK1_K20_ADC_CH2H 0x76 /* ADC Channel 2 MSB RO */
+#define APALIS_TK1_K20_ADC_CH3L 0x77 /* ADC Channel 3 LSB RO */
+#define APALIS_TK1_K20_ADC_CH3H 0x78 /* ADC Channel 3 MSB RO */
/* Bulk read of LSB register can be use to read entire 16-bit in one command */
/* TSC Register */
-#define APALIS_TK1_K20_TSCREG 0x40 /* TSC control & status register RW */
-#define APALIS_TK1_K20_TSC_XML 0x41 /* TSC X- data LSB RO */
-#define APALIS_TK1_K20_TSC_XMH 0x42 /* TSC X- data MSB RO */
-#define APALIS_TK1_K20_TSC_XPL 0x43 /* TSC X+ data LSB RO */
-#define APALIS_TK1_K20_TSC_XPH 0x44 /* TSC X+ data MSB RO */
-#define APALIS_TK1_K20_TSC_YML 0x45 /* TSC Y- data LSB RO */
-#define APALIS_TK1_K20_TSC_YMH 0x46 /* TSC Y- data MSB RO */
-#define APALIS_TK1_K20_TSC_YPL 0x47 /* TSC Y+ data LSB RO */
-#define APALIS_TK1_K20_TSC_YPH 0x48 /* TSC Y+ data MSB RO */
+#define APALIS_TK1_K20_TSCREG 0x80 /* TSC control & status register RW */
+#define APALIS_TK1_K20_TSC_XML 0x81 /* TSC X- data LSB RO */
+#define APALIS_TK1_K20_TSC_XMH 0x82 /* TSC X- data MSB RO */
+#define APALIS_TK1_K20_TSC_XPL 0x83 /* TSC X+ data LSB RO */
+#define APALIS_TK1_K20_TSC_XPH 0x84 /* TSC X+ data MSB RO */
+#define APALIS_TK1_K20_TSC_YML 0x85 /* TSC Y- data LSB RO */
+#define APALIS_TK1_K20_TSC_YMH 0x86 /* TSC Y- data MSB RO */
+#define APALIS_TK1_K20_TSC_YPL 0x87 /* TSC Y+ data LSB RO */
+#define APALIS_TK1_K20_TSC_YPH 0x88 /* TSC Y+ data MSB RO */
/* Bulk read of LSB register can be use to read entire 16-bit in one command */
#define APALIS_TK1_K20_TSC_ENA BIT(0)
-#define APALIS_TK1_K20_TSC_ENA_MASK 0xFE
+#define APALIS_TK1_K20_TSC_ENA_MASK BIT(0)
/* GPIO Registers */
-#define APALIS_TK1_K20_GPIOREG 0x50 /* GPIO control & status register RW */
-#define APALIS_TK1_K20_GPIO_NO 0x51 /* currently configured GPIO RW */
-#define APALIS_TK1_K20_GPIO_STA 0x52 /* Status register for the APALIS_TK1_K20_GPIO_NO GPIO RW */
+#define APALIS_TK1_K20_GPIOREG 0x90 /* GPIO control & status register RW */
+#define APALIS_TK1_K20_GPIO_NO 0x91 /* currently configured GPIO RW */
+#define APALIS_TK1_K20_GPIO_STA 0x92 /* Status register for the APALIS_TK1_K20_GPIO_NO GPIO RW */
/* MSB | 0 ... 0 | VALUE | Output-1 / Input-0 | LSB */
#define APALIS_TK1_K20_GPIO_STA_OE BIT(0)
#define APALIS_TK1_K20_GPIO_STA_VAL BIT(1)
@@ -101,7 +106,7 @@ void spi_task(void *pvParameters);
#define APALIS_TK1_K20_TSC_IRQ 4
#define APALIS_TK1_K20_GPIO_IRQ 5
-#define APALIS_TK1_K20_FW_VER 0x05
+#define APALIS_TK1_K20_FW_VER 0x09
#define FW_MINOR (APALIS_TK1_K20_FW_VER & 0x0F)
#define FW_MAJOR ((APALIS_TK1_K20_FW_VER & 0xF0) >> 8)
diff --git a/source/main.c b/source/main.c
index e035d4e..341627d 100644
--- a/source/main.c
+++ b/source/main.c
@@ -39,6 +39,7 @@
#include "clock_config.h"
#include "fsl_debug_console.h"
#include "com_task.h"
+#include "can_task.h"
#include "adc_task.h"
/* FreeRTOS kernel includes. */
@@ -113,6 +114,8 @@ int main(void) {
}
#endif
+ NVIC_SetPriority(CAN0_ORed_Message_buffer_IRQn, 5u);
+ NVIC_SetPriority(CAN1_ORed_Message_buffer_IRQn, 5u);
NVIC_SetPriorityGrouping( 0 );
vTaskStartScheduler();