From b3bc06bef795fdc57254729c74c04e2732a6092d Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Wed, 5 Apr 2017 14:00:11 +0200 Subject: Apalis_TK1_K20: CAN support and version change Includes CAN support and fw version bump to 0.9 Signed-off-by: Dominik Sliwa --- source/can_task.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ source/can_task.h | 17 ++++ source/com_task.c | 15 +++- source/com_task.h | 65 ++++++++------- source/main.c | 3 + 5 files changed, 299 insertions(+), 34 deletions(-) create mode 100644 source/can_task.c create mode 100644 source/can_task.h 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(); -- cgit v1.2.3