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_dma_cs_deassert * Returned Value : * Comments : * Deactivates chip select signals. * *END*********************************************************************/ static _mqx_int _dspi_dma_cs_deassert ( /* [IN] The address of the device registers */ void *io_info_ptr ) { DSPI_DMA_INFO_STRUCT_PTR dspi_info_ptr = (DSPI_DMA_INFO_STRUCT_PTR)io_info_ptr; VDSPI_REG_STRUCT_PTR dspi_ptr = dspi_info_ptr->DSPI_PTR; dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(0xFF); return MQX_OK; }
static void fsl_dspi_cfg_cs_active_state(struct fsl_dspi_priv *priv, uint cs, uint state) { uint mcr_val; dspi_halt(priv, 1); mcr_val = dspi_read32(priv->flags, &priv->regs->mcr); if (state & SPI_CS_HIGH) /* CSx inactive state is low */ mcr_val &= ~DSPI_MCR_PCSIS(cs); else /* CSx inactive state is high */ mcr_val |= DSPI_MCR_PCSIS(cs); dspi_write32(priv->flags, &priv->regs->mcr, mcr_val); dspi_halt(priv, 0); }
/*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_setparam * Returned Value : * Comments : * Set parameters for following transfers. * *END*********************************************************************/ static _mqx_int _dspi_setparam ( /* [IN] Device specific context structure */ void *io_info_ptr, /* [IN] Parameters to set */ SPI_PARAM_STRUCT_PTR params ) { DSPI_INFO_STRUCT_PTR dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)io_info_ptr; VDSPI_REG_STRUCT_PTR dspi_ptr = dspi_info_ptr->DSPI_PTR; BSP_CLOCK_CONFIGURATION clock_config; uint32_t clock_speed; uint32_t ctar; uint32_t cpol_invert; /* Transfer mode */ if ((params->ATTR & SPI_ATTR_TRANSFER_MODE_MASK) != SPI_ATTR_MASTER_MODE) return SPI_ERROR_TRANSFER_MODE_INVALID; /* Set master mode */ dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK; clock_config = _bsp_get_clock_configuration(); /* Check the parameter against most recent values to avoid time consuming baudrate finding routine */ if ((dspi_info_ptr->CLOCK_CONFIG != clock_config) || (dspi_info_ptr->BAUDRATE != params->BAUDRATE)) { dspi_info_ptr->CLOCK_CONFIG = clock_config; dspi_info_ptr->BAUDRATE = params->BAUDRATE; /* Find configuration of prescalers best matching the desired value */ clock_speed = _bsp_get_clock(dspi_info_ptr->CLOCK_CONFIG, dspi_info_ptr->CLOCK_SOURCE); _dspi_find_baudrate(clock_speed, dspi_info_ptr->BAUDRATE, &(dspi_info_ptr->CTAR_TIMING)); } /* Set up prescalers */ ctar = dspi_info_ptr->CTAR_TIMING; /* Set up transfer parameters */ _dspi_ctar_params(params, &ctar); /* Check whether it is necessary to invert idle clock polarity */ cpol_invert = (dspi_ptr->CTAR[0] ^ ctar) & DSPI_CTAR_CPOL_MASK; /* Store to register */ dspi_ptr->CTAR[0] = ctar; dspi_info_ptr->DUMMY_PATTERN = params->DUMMY_PATTERN; dspi_info_ptr->ATTR = params->ATTR; if (cpol_invert) { /* Dummy transfer with inactive CS to invert idle clock polarity */ dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(0xFF); _dspi_tx_rx(io_info_ptr, NULL, NULL, (params->FRAMESIZE+7)/8); } /* Set CS signals */ //dspi_ptr->MCR = (dspi_ptr->MCR & ~DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(~(params->CS)); return SPI_OK; }