From 56e86c626df3dbf74c1021210636a7c5d92a49ce Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Tue, 30 Oct 2018 16:31:29 +0100 Subject: move to cmake Signed-off-by: Dominik Sliwa --- app/src/com_task.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 app/src/com_task.c (limited to 'app/src/com_task.c') diff --git a/app/src/com_task.c b/app/src/com_task.c new file mode 100644 index 0000000..d6bc97d --- /dev/null +++ b/app/src/com_task.c @@ -0,0 +1,279 @@ + +#include "com_task.h" +#include "can_task.h" +#include "gpio_ext.h" +#include "adc_task.h" + +volatile uint8_t registers[APALIS_TK1_K20_LAST_REG]; +volatile uint8_t regRxHandled; + +/* Put FW version at known address in a binary. Make it 32-bit to have room for the future */ +#ifndef TESTER_BUILD +const uint32_t __attribute__((section(".FwVersion"), used)) fw_version = APALIS_TK1_K20_FW_VER; +#else +const uint32_t __attribute__((section(".FwVersion"), used)) fw_version = APALIS_TK1_K20_TESTER_FW_VER; +#endif + +static dspi_slave_handle_t spi_handle; +static uint8_t slaveRxData[APALIS_TK1_K20_MAX_BULK + APALIS_TK1_K20_HEADER]; +static uint8_t slaveTxData[APALIS_TK1_K20_MAX_BULK + APALIS_TK1_K20_HEADER]; + +#ifdef SPI_DMA +dspi_slave_edma_handle_t g_dspi_edma_s_handle; +edma_handle_t dspiEdmaSlaveRxHandle; +edma_handle_t dspiEdmaSlaveTxHandle; +#endif + +void generate_irq(uint8_t irq) { + if (!(registers[APALIS_TK1_K20_MSQREG] & BIT(irq))) { + taskENTER_CRITICAL(); + registers[APALIS_TK1_K20_IRQREG] |= BIT(irq); + /* Toggle INT1 pin */ + GPIO_TogglePinsOutput(GPIOA, 1u << 16u); + taskEXIT_CRITICAL(); + } +} + +void clear_irq_flag(uint8_t irq) { + registers[APALIS_TK1_K20_IRQREG] &= ~irq; +} + +uint8_t get_control_reg() +{ + return registers[APALIS_TK1_K20_CTRREG]; + +} + +void set_control_reg(uint8_t value) +{ + registers[APALIS_TK1_K20_CTRREG] = value; +} + +uint8_t get_status_reg() +{ + return registers[APALIS_TK1_K20_STAREG]; + +} + +void set_status_reg(uint8_t value) +{ + registers[APALIS_TK1_K20_STAREG] = value; +} + +uint8_t get_mask_reg() +{ + return registers[APALIS_TK1_K20_MSQREG]; + +} + +void set_mask_reg(uint8_t value) +{ + registers[APALIS_TK1_K20_MSQREG] = value; +} + +uint8_t get_irq_reg() +{ + return registers[APALIS_TK1_K20_IRQREG]; + +} + +void set_irq_reg(uint8_t value) +{ + /* Clear IRQ flag on 1 */ + clear_irq_flag(value); + +} + +inline int general_registers(dspi_transfer_t * spi_transfer) +{ + uint8_t *rx_buf = spi_transfer->rxData; + + if (rx_buf[0] == APALIS_TK1_K20_WRITE_INST) { + switch (rx_buf[1]) { + case APALIS_TK1_K20_STAREG: + set_status_reg(rx_buf[2]); + return 1; + case APALIS_TK1_K20_REVREG: + return -ENOENT; + case APALIS_TK1_K20_IRQREG: + set_irq_reg(rx_buf[2]); + return 1; + case APALIS_TK1_K20_CTRREG: + set_control_reg(rx_buf[2]); + return 1; + case APALIS_TK1_K20_MSQREG: + set_mask_reg(rx_buf[2]); + return 1; + default: + return -ESRCH; + } + } + + + return -ENXIO; +} + + +inline void SPI_main_callback(status_t status, void *userData) +{ + callback_message_t * cb = (callback_message_t*) userData; + BaseType_t reschedule = pdFALSE; + + if (status == kStatus_Success) + { + xSemaphoreGiveFromISR(cb->sem, &reschedule); + } +#if 0 + if (status == kStatus_DSPI_Error) + { + __NOP(); + } +#endif + portYIELD_FROM_ISR(reschedule); +} + +static void SPI_callback(SPI_Type *base, dspi_slave_handle_t *handle, status_t status, void *userData) +{ + SPI_main_callback(status, userData); +} + +static void SPI_EDMA_callback(SPI_Type *base, dspi_slave_edma_handle_t *handle, status_t status, void *userData) +{ + SPI_main_callback(status, userData); +} + +static dspi_slave_config_t spi2_slaveConfig; + +static void SPI_init() { + gpio_pin_config_t gpio_out_config = { + kGPIO_DigitalOutput, 0, + }; + GPIO_PinInit(GPIOD, 11u, &gpio_out_config); + /* Slave config */ + spi2_slaveConfig.whichCtar = kDSPI_Ctar0; + spi2_slaveConfig.ctarConfig.bitsPerFrame = 8; + spi2_slaveConfig.ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh; + spi2_slaveConfig.ctarConfig.cpha = kDSPI_ClockPhaseSecondEdge; + spi2_slaveConfig.enableContinuousSCK = false; + spi2_slaveConfig.enableRxFifoOverWrite = true; + spi2_slaveConfig.enableModifiedTimingFormat = false; + spi2_slaveConfig.samplePoint = kDSPI_SckToSin0Clock; + PRINTF("SPI init \r\n"); + DSPI_SlaveInit(SPI2, &spi2_slaveConfig); + DSPI_SlaveTransferCreateHandle(SPI2, &spi_handle, SPI_callback, spi_handle.userData); + + /* Set dspi slave interrupt priority higher. */ + NVIC_SetPriority(SPI2_IRQn, 5U); + GPIO_ClearPinsOutput(GPIOA, 1u << 29u); /* INT2 active */ + PRINTF("SPI init done \r\n"); + +} + +void spi_task(void *pvParameters) { + callback_message_t spi_msg; + dspi_transfer_t slaveXfer; + int ret = 0; + int can_read = -1; +#ifdef SPI_DMA + uint32_t slaveRxChannel, slaveTxChannel; + edma_config_t userConfig; +#endif + + spi_msg.sem = xSemaphoreCreateBinary(); + spi_handle.userData = &spi_msg; + SPI_init(); +#ifdef SPI_DMA + slaveRxChannel = 0U; + slaveTxChannel = 1U; + + DMAMUX_Init(DMAMUX); + DMAMUX_SetSource(DMAMUX, slaveRxChannel, kDmaRequestMux0SPI2Rx); + DMAMUX_EnableChannel(DMAMUX, slaveRxChannel); + DMAMUX_SetSource(DMAMUX, slaveTxChannel, kDmaRequestMux0SPI2Tx); + DMAMUX_EnableChannel(DMAMUX, slaveTxChannel); + + EDMA_GetDefaultConfig(&userConfig); + EDMA_Init(DMA0, &userConfig); + + EDMA_CreateHandle(&dspiEdmaSlaveRxHandle, DMA0, slaveRxChannel); + EDMA_CreateHandle(&dspiEdmaSlaveTxHandle, DMA0, slaveTxChannel); + + g_dspi_edma_s_handle.userData = &spi_msg; + DSPI_SlaveTransferCreateHandleEDMA(SPI2, &g_dspi_edma_s_handle, SPI_EDMA_callback, + &spi_msg, &dspiEdmaSlaveRxHandle, &dspiEdmaSlaveTxHandle); +#endif + memset((uint8_t *)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(spi_msg.sem, portMAX_DELAY); + + if (slaveRxData[0] != APALIS_TK1_K20_READ_INST) { + taskENTER_CRITICAL(); + slaveXfer.txData = slaveTxData; + slaveXfer.rxData = slaveRxData; + if (slaveRxData[1] <= 0x05) { + ret = general_registers(&slaveXfer); +#ifndef TESTER_BUILD + } 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); + can_read = 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); + can_read = 1; +#endif +#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_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; + } + + if (ret < 0) { + PRINTF("Invalid read/write ret = %d rx[0] = 0x%x, rx[1] = 0x%x, rx[2] = 0x%x\r\n", + ret, slaveRxData[0], slaveRxData[1], slaveRxData[2]); + } + + if (slaveRxData[0] == APALIS_TK1_K20_BULK_READ_INST) { + slaveXfer.dataSize = ret; + slaveXfer.rxData = NULL; +#ifdef SPI_DMA + DSPI_SlaveTransferEDMA(SPI2, &g_dspi_edma_s_handle, &slaveXfer); +#else + DSPI_SlaveTransferNonBlocking(SPI2, &spi_handle, &slaveXfer); +#endif + taskEXIT_CRITICAL(); + xSemaphoreTake(spi_msg.sem, portMAX_DELAY); + + if (can_read >= 0) { + can_spi_read_complete(can_read); + can_read = -1; + } + } else { + taskEXIT_CRITICAL(); + } + } + } else { + /* Something went wrong, retry */ + DSPI_SlaveTransferAbort(SPI2, &spi_handle); + } + } +} -- cgit v1.2.3