//-------------------------------- void ssi_peripheral::Initialize() { MAP_SysCtlPeripheralEnable(m_rSpecification.m_nSSIPeripheral); MAP_SysCtlPeripheralEnable(m_rSpecification.m_nGPIOPeripheral); // Assign the SSI signals to the appropriate pins MAP_GPIOPinConfigure(m_rSpecification.m_nSSIPinRx); MAP_GPIOPinConfigure(m_rSpecification.m_nSSIPinClk); MAP_GPIOPinConfigure(m_rSpecification.m_nSSIPinTx); if (m_rSpecification.m_nSSIPinFss) { MAP_GPIOPinConfigure(m_rSpecification.m_nSSIPinFss); } // Set the GPIO AFSEL bits for the appropriate pins MAP_GPIOPinTypeSSI(m_rSpecification.m_nGPIOBase, m_rSpecification.m_nGPIOPins); // Set pull-up on the SSI Rx pin GPIOPadConfigSet(m_rSpecification.m_nGPIOBase, m_rSpecification.m_nGPIOInputPin, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); // Set standard on the SSI output pins GPIOPadConfigSet(m_rSpecification.m_nGPIOBase, m_rSpecification.m_nGPIOOutputPins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); // Configure the SSI peripheral SSIConfigSetExpClk(m_rSpecification.m_nSSIBase, SysCtlClockGet(), m_nProtocol, SSI_MODE_MASTER, m_nBitRate, 16); // Enable the SSI module. MAP_SSIEnable(m_rSpecification.m_nSSIBase); // Read any residual data from the SSI port. while (MAP_SSIDataGetNonBlocking(m_rSpecification.m_nSSIBase, &m_nDataRx[0])) { } m_bEmpty = true; // Enable the SSI interrupt switch (m_nDevice) { case ssi_peripheral::SSI0: g_pTheSSI0 = this; break; case ssi_peripheral::SSI1: g_pTheSSI1 = this; break; case ssi_peripheral::SSI2: g_pTheSSI2 = this; break; case ssi_peripheral::SSI3: g_pTheSSI3 = this; break; default: break; } SSIIntDisable(m_rSpecification.m_nSSIBase, SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR); SSIIntClear(m_rSpecification.m_nSSIBase, SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR); (*((volatile uint32_t *) m_rSpecification.m_nSSI_CR1_R)) |= SSI_CR1_EOT; /* switch tx interrupt to eot int */ if (m_bNonBlocking) { SSIIntEnable(m_rSpecification.m_nSSIBase, SSI_TXFF); /* SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR */ MAP_IntEnable(m_rSpecification.m_nInterrupt); } }
void Spi::enableInterrupts(void) { // Register the interrupt handler InterruptHandler::getInstance().setInterruptHandler(this); // Enable the SPI interrupt SSIIntEnable(config_.base, (SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR)); // Enable the SPI interrupt IntEnable(config_.interrupt); }
/*! * @brief Function for transferring using the SPI interface. * * The function will enable the SPI and UDMA modules and disallow * the device from going into standby. * * In ::SPI_MODE_BLOCKING, SPI_transfer will block task execution until the transfer * has ended. * * In ::SPI_MODE_CALLBACK, SPI_transfer does not block task execution, but calls a * callback function specified by transferCallback when the transfer has ended. * * @pre SPICC26XXDMA_open() has to be called first. * Calling context: Hwi and Swi (only if using ::SPI_MODE_CALLBACK), Task * * @param handle A SPI handle returned from SPICC26XXDMA_open() * * @param *transaction Pointer to transaction struct * * @return True if transfer is successful and false if not * * @sa SPICC26XXDMA_open(), SPICC26XXDMA_transferCancel() */ bool SPICC26XXDMA_transfer(SPI_Handle handle, SPI_Transaction *transaction) { unsigned int key; SPICC26XX_Object *object; SPICC26XX_HWAttrs const *hwAttrs; /* Get the pointer to the object and hwAttr*/ object = handle->object; hwAttrs = handle->hwAttrs; /* This is a limitation by the uDMA controller */ Assert_isTrue(transaction->count <= 1024, NULL); if (transaction->count == 0) { return (false); } /* Make sure that the buffers are aligned properly */ if (object->frameSize == SPICC26XXDMA_16bit) { Assert_isTrue(!((unsigned long)transaction->txBuf & 0x1), NULL); Assert_isTrue(!((unsigned long)transaction->rxBuf & 0x1), NULL); } /* Disable preemption while checking if a transfer is in progress */ key = Hwi_disable(); if (object->currentTransaction) { Hwi_restore(key); Log_error1("SPI:(%p) transaction still in progress", ((SPICC26XX_HWAttrs const *)(handle->hwAttrs))->baseAddr); /* Flag that the transfer failed to start */ transaction->status = SPI_TRANSFER_FAILED; /* Transfer is in progress */ return (false); } /* Make sure to flag that a transaction is now active */ transaction->status = SPI_TRANSFER_STARTED; object->currentTransaction = transaction; Hwi_restore(key); /* In slave mode, optionally enable callback on CSN de-assert */ if (object->returnPartial) { PIN_setInterrupt(object->pinHandle, object->csnPin | PIN_IRQ_POSEDGE); } /* Enable the SPI module */ SSIEnable(hwAttrs->baseAddr); /* Setup DMA transfer. */ SPICC26XXDMA_configDMA(handle, transaction); /* Enable the RX overrun interrupt in the SSI module */ SSIIntEnable(hwAttrs->baseAddr, SSI_RXOR); /* Set constraints to guarantee transaction */ threadSafeConstraintSet((uint32_t)(transaction->txBuf)); if (object->transferMode == SPI_MODE_BLOCKING) { Log_print1(Diags_USER1, "SPI:(%p) transfer pending on transferComplete " "semaphore", ((SPICC26XX_HWAttrs const *)(handle->hwAttrs))->baseAddr); if (!Semaphore_pend(Semaphore_handle(&(object->transferComplete)), object->transferTimeout)) { /* Cancel the transfer, if we experience a timeout */ SPICC26XXDMA_transferCancel(handle); /* * SPICC26XXDMA_transferCancel peforms a callback which posts a * transferComplete semaphore. This call consumes this extra post. */ Semaphore_pend(Semaphore_handle(&(object->transferComplete)), BIOS_NO_WAIT); return (false); } } return (true); }
void SPI_spi0_slave_init(void) { unsigned long tmpbuf; // The SSI0 peripheral must be enabled for use. SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0); // // For this example SSI0 is used with PortA[5:2]. GPIO port A needs to be // enabled so these pins can be used. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Configure the pin muxing for SSI0 functions on port A2, A3, A4, and A5. // This step is not necessary if your part does not support pin muxing. // GPIOPinConfigure(GPIO_PA2_SSI0CLK); GPIOPinConfigure(GPIO_PA3_SSI0FSS); GPIOPinConfigure(GPIO_PA4_SSI0RX); GPIOPinConfigure(GPIO_PA5_SSI0TX); // // Configure the GPIO settings for the SSI pins. // The pins are assigned as follows: // PA5 - SSI0Tx // PA4 - SSI0Rx // PA3 - SSI0Fss // PA2 - SSI0CLK // GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2); // // Configure and enable the SSI port for SPI master mode. Use SSI0, // system clock supply, idle clock level low and active low clock in // freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data. // SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE_OD, 1000000, 8); // // Enable the SSI0 module. // SSIEnable(SSI0_BASE); // // Emputy the SSI rx FIFO // while (SSIDataGetNonBlocking(SSI0_BASE, &tmpbuf)) {} // // Register SPI Int Handler // SSIIntRegister(SSI0_BASE, SPI_spi0_int_handler); // // Enable the SSI interrupt. // IntEnable(INT_SSI0); SSIIntEnable(SSI0_BASE, SSI_RXFF|SSI_RXTO|SSI_RXOR); }