void DRV_SPI0_Initialize(void) { PLIB_SPI_Disable(SPI_ID_1); PLIB_SPI_MasterEnable(SPI_ID_1); PLIB_SPI_SlaveSelectEnable(SPI_ID_1); PLIB_SPI_StopInIdleDisable(SPI_ID_1); PLIB_SPI_ClockPolaritySelect(SPI_ID_1, SPI_CLOCK_POLARITY_IDLE_LOW); PLIB_SPI_OutputDataPhaseSelect(SPI_ID_1, SPI_OUTPUT_DATA_PHASE_ON_IDLE_TO_ACTIVE_CLOCK); PLIB_SPI_InputSamplePhaseSelect(SPI_ID_1, SPI_INPUT_SAMPLING_PHASE_IN_MIDDLE); PLIB_SPI_CommunicationWidthSelect(SPI_ID_1, SPI_COMMUNICATION_WIDTH_8BITS); PLIB_SPI_FramedCommunicationDisable( SPI_ID_1 ); PLIB_SPI_AudioProtocolDisable(SPI_ID_1); PLIB_SPI_FIFOEnable( SPI_ID_1 ); PLIB_SPI_BaudRateSet(SPI_ID_1, SYS_CLK_PeripheralFrequencyGet(CLK_BUS_PERIPHERAL_2), 1000000); PLIB_SPI_Enable(SPI_ID_1); }
int32_t DRV_SPI_SetupHardware(struct DRV_SPI_DRIVER_OBJECT * driverObject, const DRV_SPI_INIT * const init) { const register SPI_MODULE_ID spiId = init->spiId; /* disable the SPI*/ PLIB_SPI_Disable(spiId); /* Set up Master or Slave Mode*/ if (init->spiMode == DRV_SPI_MODE_MASTER) { PLIB_SPI_MasterEnable ( spiId ); } else if (init->spiMode == DRV_SPI_MODE_SLAVE) { PLIB_SPI_SlaveEnable ( spiId ); } else { SYS_ASSERT(false, "\r\nInvalid SPI Configuration."); return -1; } /* Set up if the SPI is allowed to run while the rest of the CPU is in idle mode*/ if (init->allowIdleRun) { PLIB_SPI_StopInIdleDisable( spiId ); } else { PLIB_SPI_StopInIdleEnable( spiId ); } /* Set up close Polarity and output data phase*/ switch(init->clockMode) { case DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_RISE: PLIB_SPI_ClockPolaritySelect( spiId, SPI_CLOCK_POLARITY_IDLE_LOW ); PLIB_SPI_OutputDataPhaseSelect( spiId, SPI_OUTPUT_DATA_PHASE_ON_IDLE_TO_ACTIVE_CLOCK ); break; case DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_FALL: PLIB_SPI_ClockPolaritySelect( spiId, SPI_CLOCK_POLARITY_IDLE_LOW ); PLIB_SPI_OutputDataPhaseSelect( spiId, SPI_OUTPUT_DATA_PHASE_ON_ACTIVE_TO_IDLE_CLOCK ); break; case DRV_SPI_CLOCK_MODE_IDLE_HIGH_EDGE_FALL: //TODO: Make sure these are right PLIB_SPI_ClockPolaritySelect( spiId, SPI_CLOCK_POLARITY_IDLE_HIGH ); PLIB_SPI_OutputDataPhaseSelect( spiId, SPI_OUTPUT_DATA_PHASE_ON_IDLE_TO_ACTIVE_CLOCK ); break; case DRV_SPI_CLOCK_MODE_IDLE_HIGH_EDGE_RISE: PLIB_SPI_ClockPolaritySelect( spiId, SPI_CLOCK_POLARITY_IDLE_HIGH ); PLIB_SPI_OutputDataPhaseSelect( spiId, SPI_OUTPUT_DATA_PHASE_ON_ACTIVE_TO_IDLE_CLOCK ); break; default: SYS_ASSERT(false, "\r\nInvalid SPI Configuration."); return -1; } // Set up the Input Sample Phase PLIB_SPI_InputSamplePhaseSelect ( spiId, init->inputSamplePhase); //Enable the SSx Pin on slave side if needed if(init->spiMode == DRV_SPI_MODE_SLAVE && (init->spiProtocolType == DRV_SPI_PROTOCOL_TYPE_FRAMED || init->spiSlaveSSPin)) { PLIB_SPI_PinEnable(spiId, SPI_PIN_SLAVE_SELECT); } else { PLIB_SPI_PinDisable(spiId, SPI_PIN_SLAVE_SELECT); } /* Communication Width Selection */ PLIB_SPI_CommunicationWidthSelect ( spiId, init->commWidth ); /* Baudrate selection */ PLIB_SPI_BaudRateSet( spiId , SYS_CLK_PeripheralFrequencyGet(init->spiClk), init->baudRate ); driverObject->currentBaudRate = init->baudRate; driverObject->baudRate = init->baudRate; switch (init->spiProtocolType) { case DRV_SPI_PROTOCOL_TYPE_STANDARD: PLIB_SPI_FramedCommunicationDisable( spiId ); break; case DRV_SPI_PROTOCOL_TYPE_FRAMED: #if defined (PLIB_SPI_ExistsFrameSyncPulseDirection) if (PLIB_SPI_ExistsFrameSyncPulseDirection(spiId)) { PLIB_SPI_FrameSyncPulseDirectionSelect(spiId, init->framePulseDirection); } #endif #if defined (PLIB_SPI_ExistsFrameSyncPulsePolarity) if (PLIB_SPI_ExistsFrameSyncPulsePolarity(spiId)) { PLIB_SPI_FrameSyncPulsePolaritySelect(spiId, init->framePulsePolarity); } #endif #if defined (PLIB_SPI_ExistsFrameSyncPulseEdge) if (PLIB_SPI_ExistsFrameSyncPulseEdge(spiId)) { PLIB_SPI_FrameSyncPulseEdgeSelect(spiId, init->framePulseEdge); } #endif #if defined (PLIB_SPI_ExistsFrameSyncPulseWidth) if (PLIB_SPI_ExistsFrameSyncPulseWidth(spiId)) { PLIB_SPI_FrameSyncPulseWidthSelect(spiId, init->framePulseWidth); } #endif #if defined (PLIB_SPI_ExistsFrameSyncPulseCounter) if (PLIB_SPI_ExistsFrameSyncPulseCounter(spiId)) { PLIB_SPI_FrameSyncPulseCounterSelect(spiId, init->frameSyncPulse); } #endif PLIB_SPI_FramedCommunicationEnable( spiId ); break; case DRV_SPI_PROTOCOL_TYPE_AUDIO: PLIB_SPI_FramedCommunicationDisable( spiId ); { SYS_ASSERT(false, "\r\nInvalid SPI Configuration."); return -1; } break; default: SYS_ASSERT(false, "\r\nInvalid SPI Configuration."); return -1; } if (PLIB_SPI_ExistsFIFOControl( spiId )) { PLIB_SPI_FIFODisable( spiId ); } PLIB_SPI_BufferClear( spiId ); PLIB_SPI_ReceiverOverflowClear ( spiId ); // Note: We do not enable the SPI here, that will be done by the first client. return 0; }
SYS_MODULE_OBJ DRV_SPI0_Initialize(void) { DRV_SPI_OBJ *dObj = (DRV_SPI_OBJ*)NULL; dObj = &gDrvSPI0Obj; /* Disable the SPI module to configure it*/ PLIB_SPI_Disable ( SPI_ID_1 ); /* Set up Master or Slave Mode*/ PLIB_SPI_MasterEnable ( SPI_ID_1 ); PLIB_SPI_PinDisable(SPI_ID_1, SPI_PIN_SLAVE_SELECT); /* Set up if the SPI is allowed to run while the rest of the CPU is in idle mode*/ PLIB_SPI_StopInIdleDisable( SPI_ID_1 ); /* Set up clock Polarity and output data phase*/ PLIB_SPI_ClockPolaritySelect( SPI_ID_1, SPI_CLOCK_POLARITY_IDLE_LOW ); PLIB_SPI_OutputDataPhaseSelect( SPI_ID_1, SPI_OUTPUT_DATA_PHASE_ON_IDLE_TO_ACTIVE_CLOCK ); /* Set up the Input Sample Phase*/ PLIB_SPI_InputSamplePhaseSelect ( SPI_ID_1, SPI_INPUT_SAMPLING_PHASE_IN_MIDDLE); /* Communication Width Selection */ PLIB_SPI_CommunicationWidthSelect ( SPI_ID_1, SPI_COMMUNICATION_WIDTH_8BITS ); /* Baud rate selection */ PLIB_SPI_BaudRateSet( SPI_ID_1 , SYS_CLK_PeripheralFrequencyGet(CLK_BUS_PERIPHERAL_2), 1000000 ); /* Protocol selection */ PLIB_SPI_FramedCommunicationDisable( SPI_ID_1 ); #if defined (PLIB_SPI_ExistsAudioProtocolControl) if (PLIB_SPI_ExistsAudioProtocolControl(SPI_ID_1)) { PLIB_SPI_AudioProtocolDisable(SPI_ID_1); } #endif /* Buffer type selection */ #if defined (PLIB_SPI_ExistsFIFOControl) if (PLIB_SPI_ExistsFIFOControl( SPI_ID_1 )) { PLIB_SPI_FIFODisable( SPI_ID_1 ); } #endif PLIB_SPI_BufferClear( SPI_ID_1 ); PLIB_SPI_ReceiverOverflowClear ( SPI_ID_1 ); /* Initialize Queue only once for all instances of SPI driver*/ if (DRV_SPI_SYS_QUEUE_Initialize(&qmInitData, &hQueueManager) != DRV_SPI_SYS_QUEUE_SUCCESS) { SYS_ASSERT(false, "\r\nSPI Driver: Could not create queuing system."); return SYS_MODULE_OBJ_INVALID; } /* Update the Queue parameters. */ qInitData.maxElements = 10; //Queue size qInitData.reserveElements = 1; //Mininmum number of job queues reserved /* Create Queue for this instance of SPI */ if (DRV_SPI_SYS_QUEUE_CreateQueue(hQueueManager, &qInitData, &dObj->queue) != DRV_SPI_SYS_QUEUE_SUCCESS) { SYS_ASSERT(false, "\r\nSPI Driver: Could not set up driver instance queue."); return SYS_MODULE_OBJ_INVALID; } /* Update the SPI OBJECT parameters. */ dObj->operationStarting = NULL; dObj->operationEnded = NULL; SYS_INT_SourceDisable(INT_SOURCE_SPI_1_TRANSMIT); SYS_INT_SourceDisable(INT_SOURCE_SPI_1_RECEIVE); SYS_INT_SourceEnable(INT_SOURCE_SPI_1_ERROR); /* Clear all interrupt sources */ SYS_INT_SourceStatusClear(INT_SOURCE_SPI_1_TRANSMIT); SYS_INT_SourceStatusClear(INT_SOURCE_SPI_1_RECEIVE); SYS_INT_SourceStatusClear(INT_SOURCE_SPI_1_ERROR); /* Enable the Module */ PLIB_SPI_Enable(SPI_ID_1); return (SYS_MODULE_OBJ)DRV_SPI_INDEX_0 ; }