static _mqx_int write_cs_callback(uint32_t pre_cfg_mask, void *user_data) { VDSPI_REG_STRUCT_PTR dspi_ptr; LWGPIO_STRUCT em9301_spi_mosi; if(pre_cfg_mask & PRE_CONFIGURE_FLAG) { dspi_ptr = _bsp_get_dspi_base_address(1); dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(0xFF); /*MOSI set pin*/ lwgpio_init(&em9301_spi_mosi, BSP_EM9301_MOSI_PIN, LWGPIO_DIR_OUTPUT, LWGPIO_VALUE_NOCHANGE); lwgpio_set_functionality(&em9301_spi_mosi, 1); lwgpio_set_value(&em9301_spi_mosi, 1); /*Assert CS pin*/ dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(~0x01); lwgpio_set_functionality(&em9301_spi_mosi, 7); } return MQX_OK; }
static _mqx_int read_cs_callback(uint32_t pre_cfg_mask, void *user_data) { BleStatus status; MQX_FILE_PTR dev = (MQX_FILE_PTR)user_data; SPI_DEV_DATA_STRUCT_PTR dev_data = (SPI_DEV_DATA_STRUCT_PTR)(dev->DEV_DATA_PTR); U8 byteReceievd; VDSPI_REG_STRUCT_PTR dspi_ptr; LWGPIO_STRUCT em9301_spi_mosi; if(pre_cfg_mask & PRE_CONFIGURE_FLAG) { dspi_ptr = _bsp_get_dspi_base_address(1); dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(0xFF); lwgpio_init(&em9301_spi_mosi, BSP_EM9301_MOSI_PIN, LWGPIO_DIR_OUTPUT, LWGPIO_VALUE_NOCHANGE); lwgpio_set_functionality(&em9301_spi_mosi, 1); lwgpio_set_value(&em9301_spi_mosi, 0); /*Assert CS pin*/ dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK; dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(~0x01); lwgpio_set_functionality(&em9301_spi_mosi, 7); } else { if(dev_data->STATS.RX_PACKETS) { if(dev_data->STATS.RX_PACKETS >= EM9301_READ_BUFFER_SIZE) { status = BLETRANSPORT_UartDataReceived(hciBuffer, dev_data->STATS.RX_PACKETS); if(status == BLESTATUS_FAILED) { BLEUART_Deinit(); return BLESTATUS_FAILED; } } byteReceievd = dev_data->STATS.RX_PACKETS; status = BLETRANSPORT_UartDataReceived(hciBuffer, byteReceievd); if(SPI_OK != ioctl(dev, IO_IOCTL_SPI_CLEAR_STATS, 0)) status = BLESTATUS_FAILED; } } return status; }
/*FUNCTION**************************************************************** * * Function Name : _dspi_init * Returned Value : MQX error code * Comments : * This function initializes the SPI driver * *END*********************************************************************/ static _mqx_int _dspi_init ( /* [IN] The initialization information for the device being opened */ const void *init_data_ptr, /* [OUT] The address to store device specific information */ void **io_info_ptr_ptr ) { DSPI_INIT_STRUCT_PTR dspi_init_ptr = (DSPI_INIT_STRUCT_PTR)init_data_ptr; DSPI_INFO_STRUCT_PTR dspi_info_ptr; VDSPI_REG_STRUCT_PTR dspi_ptr; const uint32_t *vectors; uint32_t i; #if PSP_HAS_DEVICE_PROTECTION if (!_bsp_dspi_enable_access(dspi_init_ptr->CHANNEL)) { return SPI_ERROR_CHANNEL_INVALID; } #endif /* Check channel */ dspi_ptr = _bsp_get_dspi_base_address (dspi_init_ptr->CHANNEL); if (NULL == dspi_ptr) { return SPI_ERROR_CHANNEL_INVALID; } if (_bsp_dspi_io_init (dspi_init_ptr->CHANNEL) == -1) { return SPI_ERROR_CHANNEL_INVALID; } /* Initialize internal data */ dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)_mem_alloc_system_zero((uint32_t)sizeof(DSPI_INFO_STRUCT)); if (dspi_info_ptr == NULL) { return MQX_OUT_OF_MEMORY; } _mem_set_type(dspi_info_ptr, MEM_TYPE_IO_SPI_INFO_STRUCT); *io_info_ptr_ptr = (void *)dspi_info_ptr; dspi_info_ptr->DSPI_PTR = dspi_ptr; dspi_info_ptr->CHANNEL = dspi_init_ptr->CHANNEL; dspi_info_ptr->CLOCK_SOURCE = dspi_init_ptr->CLOCK_SOURCE; _dspi_init_low(dspi_info_ptr->DSPI_PTR); _lwsem_create(&dspi_info_ptr->EVENT_IO_FINISHED, 0); /* Install ISRs */ dspi_info_ptr->NUM_VECTORS = _bsp_get_dspi_vectors(dspi_info_ptr->CHANNEL, &vectors); for (i=0; i<dspi_info_ptr->NUM_VECTORS; i++) { _int_install_isr(vectors[i], _dspi_isr, dspi_info_ptr); _bsp_int_init((PSP_INTERRUPT_TABLE_INDEX)vectors[i], BSP_DSPI_INT_LEVEL, 0, TRUE); } return SPI_OK; }
/*FUNCTION**************************************************************** * * Function Name : _dspi_polled_init * Returned Value : MQX error code * Comments : * This function initializes the SPI module * *END*********************************************************************/ uint_32 _dspi_polled_init ( /* [IN] The initialization information for the device being opened */ DSPI_INIT_STRUCT_PTR dspi_init_ptr, /* [OUT] The address to store device specific information */ pointer _PTR_ io_info_ptr_ptr, /* [IN] The rest of the name of the device opened */ char_ptr open_name_ptr ) { VDSPI_REG_STRUCT_PTR dspi_ptr; DSPI_INFO_STRUCT_PTR io_info_ptr; uint_32 i; #if PSP_HAS_DEVICE_PROTECTION if (!_bsp_dspi_enable_access(dspi_init_ptr->CHANNEL)) { return SPI_ERROR_CHANNEL_INVALID; } #endif // Check channel dspi_ptr = _bsp_get_dspi_base_address (dspi_init_ptr->CHANNEL); if (NULL == dspi_ptr) { return SPI_ERROR_CHANNEL_INVALID; } if (_bsp_dspi_io_init (dspi_init_ptr->CHANNEL) == -1) { return SPI_ERROR_CHANNEL_INVALID; } // Disable and clear SPI dspi_ptr->MCR &= (~ DSPI_MCR_MDIS_MASK); dspi_ptr->MCR = DSPI_MCR_HALT_MASK | DSPI_MCR_CLR_TXF_MASK | DSPI_MCR_CLR_RXF_MASK | DSPI_MCR_DIS_RXF_MASK | DSPI_MCR_DIS_TXF_MASK; /* Initialize internal data */ io_info_ptr = (DSPI_INFO_STRUCT_PTR)_mem_alloc_system_zero((uint_32)sizeof(DSPI_INFO_STRUCT)); if (io_info_ptr == NULL) { return MQX_OUT_OF_MEMORY; } _mem_set_type (io_info_ptr,MEM_TYPE_IO_SPI_INFO_STRUCT); *io_info_ptr_ptr = io_info_ptr; io_info_ptr->DSPI_PTR = dspi_ptr; io_info_ptr->INIT = *dspi_init_ptr; io_info_ptr->RX_REQUEST = 0; io_info_ptr->RX_BUFFER = NULL; io_info_ptr->RX_IN = 0; io_info_ptr->RX_OUT = 0; io_info_ptr->RX_COUNT = 0; io_info_ptr->RX_DATA = 0; io_info_ptr->TX_BUFFER = NULL; io_info_ptr->TX_IN = 0; io_info_ptr->TX_OUT = 0; io_info_ptr->TX_COUNT = 0; io_info_ptr->TX_DATA = DSPI_PUSHR_CONT_MASK | DSPI_PUSHR_PCS(0) | DSPI_PUSHR_CTAS(0) | DSPI_PUSHR_TXDATA(0xFFFF); io_info_ptr->DMA_FLAGS = 0; io_info_ptr->CS = DSPI_PUSHR_PCS_GET(dspi_init_ptr->CS); io_info_ptr->CS_ACTIVE = 0; for (i = 0; i < DSPI_CS_COUNT; i++) { io_info_ptr->CS_CALLBACK[i] = NULL; io_info_ptr->CS_USERDATA[i] = NULL; } io_info_ptr->STATS.INTERRUPTS = 0; io_info_ptr->STATS.RX_PACKETS = 0; io_info_ptr->STATS.RX_OVERFLOWS = 0; io_info_ptr->STATS.TX_PACKETS = 0; io_info_ptr->STATS.TX_ABORTS = 0; io_info_ptr->STATS.TX_UNDERFLOWS= 0; /* Set the SPI clock baud rate divider */ dspi_ptr->CTAR[0] = DSPI_CTAR_FMSZ(7); dspi_ptr->CTAR[0] |= _dspi_find_baudrate (dspi_init_ptr->CLOCK_SPEED, dspi_init_ptr->BAUD_RATE); /* Set up SPI clock polarity and phase */ switch (dspi_init_ptr->CLOCK_POL_PHASE) { case (SPI_CLK_POL_PHA_MODE0): /* Inactive state of SPI_CLK = logic 0 */ dspi_ptr->CTAR[0] &= (~ DSPI_CTAR_CPOL_MASK); /* SPI_CLK transitions middle of bit timing */ dspi_ptr->CTAR[0] &= (~ DSPI_CTAR_CPHA_MASK); break; case (SPI_CLK_POL_PHA_MODE1): /* Inactive state of SPI_CLK = logic 0 */ dspi_ptr->CTAR[0] &= (~ DSPI_CTAR_CPOL_MASK); /* SPI_CLK transitions begining of bit timing */ dspi_ptr->CTAR[0] |= DSPI_CTAR_CPHA_MASK; break; case (SPI_CLK_POL_PHA_MODE2): /* Inactive state of SPI_CLK = logic 1 */ dspi_ptr->CTAR[0] |= DSPI_CTAR_CPOL_MASK; /* SPI_CLK transitions middle of bit timing */ dspi_ptr->CTAR[0] &= (~ DSPI_CTAR_CPHA_MASK); break; case (SPI_CLK_POL_PHA_MODE3): /* Inactive state of SPI_CLK = logic 1 */ dspi_ptr->CTAR[0] |= DSPI_CTAR_CPOL_MASK; /* SPI_CLK transitions begining of bit timing */ dspi_ptr->CTAR[0] |= DSPI_CTAR_CPHA_MASK; break; default: _mem_free (*io_info_ptr_ptr); *io_info_ptr_ptr = NULL; return SPI_ERROR_MODE_INVALID; } /* Receive FIFO overflow disable */ dspi_ptr->MCR |= DSPI_MCR_ROOE_MASK; /* Set CS0-7 inactive high */ dspi_ptr->MCR |= DSPI_MCR_PCSIS(0xFF); /* Set transfer mode */ if (dspi_init_ptr->TRANSFER_MODE == SPI_DEVICE_SLAVE_MODE) { dspi_ptr->MCR &= (~ DSPI_MCR_MSTR_MASK); } else if (dspi_init_ptr->TRANSFER_MODE == SPI_DEVICE_MASTER_MODE) { dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK; } else { _mem_free (*io_info_ptr_ptr); *io_info_ptr_ptr = NULL; return SPI_ERROR_TRANSFER_MODE_INVALID; } /* Disable interrupts */ dspi_ptr->RSER = 0; /* Clear all flags */ dspi_ptr->SR = ~ DSPI_SR_TFFF_MASK; /* Enable SPI */ dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK); return SPI_OK; }
/*FUNCTION**************************************************************** * * Function Name : _dspi_dma_init * Returned Value : MQX error code * Comments : * This function initializes the SPI driver * *END*********************************************************************/ static _mqx_int _dspi_dma_init ( /* [IN] The initialization information for the device being opened */ const void *init_data_ptr, /* [OUT] The address to store device specific information */ void **io_info_ptr_ptr ) { DSPI_DMA_INIT_STRUCT_PTR dspi_init_ptr = (DSPI_DMA_INIT_STRUCT_PTR)init_data_ptr; DSPI_DMA_INFO_STRUCT_PTR dspi_info_ptr; VDSPI_REG_STRUCT_PTR dspi_ptr; int result; #if PSP_HAS_DEVICE_PROTECTION if (!_bsp_dspi_enable_access(dspi_init_ptr->CHANNEL)) { return SPI_ERROR_CHANNEL_INVALID; } #endif /* Check channel */ dspi_ptr = _bsp_get_dspi_base_address (dspi_init_ptr->CHANNEL); if (NULL == dspi_ptr) { return SPI_ERROR_CHANNEL_INVALID; } if (_bsp_dspi_io_init (dspi_init_ptr->CHANNEL) == -1) { return SPI_ERROR_CHANNEL_INVALID; } /* Initialize internal data */ dspi_info_ptr = (DSPI_DMA_INFO_STRUCT_PTR)_mem_alloc_system_zero((uint32_t)sizeof(DSPI_DMA_INFO_STRUCT)); if (dspi_info_ptr == NULL) { return MQX_OUT_OF_MEMORY; } _mem_set_type(dspi_info_ptr, MEM_TYPE_IO_SPI_INFO_STRUCT); *io_info_ptr_ptr = (void *)dspi_info_ptr; dspi_info_ptr->DSPI_PTR = dspi_ptr; dspi_info_ptr->CHANNEL = dspi_init_ptr->CHANNEL; dspi_info_ptr->CLOCK_SOURCE = dspi_init_ptr->CLOCK_SOURCE; _dspi_init_low(dspi_info_ptr->DSPI_PTR); /* Claim DMA channels and perform setup */ if ((result = dma_channel_claim(&dspi_info_ptr->DMA_RX_CHANNEL, dspi_init_ptr->DMA_RX_CHANNEL)) != MQX_OK || (result = dma_channel_claim(&dspi_info_ptr->DMA_TX_CHANNEL, dspi_init_ptr->DMA_TX_CHANNEL)) != MQX_OK || (result = dma_channel_setup(dspi_info_ptr->DMA_RX_CHANNEL, 1, 0)) != MQX_OK || (result = dma_channel_setup(dspi_info_ptr->DMA_TX_CHANNEL, 1, 0)) != MQX_OK || (result = dma_request_source(dspi_info_ptr->DMA_RX_CHANNEL, dspi_init_ptr->DMA_RX_SOURCE)) != MQX_OK || (result = dma_request_source(dspi_info_ptr->DMA_TX_CHANNEL, dspi_init_ptr->DMA_TX_SOURCE)) != MQX_OK ) { dma_channel_release(dspi_info_ptr->DMA_RX_CHANNEL); dma_channel_release(dspi_info_ptr->DMA_TX_CHANNEL); _mem_free(dspi_info_ptr); return result; } /* Allocate cache line aligned block of memory and split it in half to form RX and TX buffer */ dspi_info_ptr->RX_BUF = _mem_alloc_system(4*PSP_CACHE_LINE_SIZE); if (dspi_info_ptr->RX_BUF == NULL) { dma_channel_release(dspi_info_ptr->DMA_RX_CHANNEL); dma_channel_release(dspi_info_ptr->DMA_TX_CHANNEL); _mem_free(dspi_info_ptr); return MQX_OUT_OF_MEMORY; } dspi_info_ptr->TX_BUF = dspi_info_ptr->RX_BUF + 2*PSP_CACHE_LINE_SIZE; _lwsem_create(&dspi_info_ptr->EVENT_IO_FINISHED, 0); dma_callback_reg(dspi_info_ptr->DMA_RX_CHANNEL, _dspi_dma_callback, dspi_info_ptr); /* Route data s to DMA */ dspi_ptr->RSER = DSPI_RSER_RFDF_DIRS_MASK | DSPI_RSER_RFDF_RE_MASK | DSPI_RSER_TFFF_DIRS_MASK | DSPI_RSER_TFFF_RE_MASK; dma_request_enable(dspi_info_ptr->DMA_RX_CHANNEL); dma_request_enable(dspi_info_ptr->DMA_TX_CHANNEL); return SPI_OK; }