示例#1
0
//--------------------------------
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);
	}
}
示例#2
0
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);
}
示例#3
0
/*!
 *  @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);
}
示例#4
0
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);
}