Esempio n. 1
0
static uint32_t spi_event_check(spi_t *obj)
{
    uint32_t event = 0;
    // Get the TX FIFO underflow flag
    uint8_t U = DSPI_HAL_GetStatusFlag(obj->spi.address,kDspiTxFifoUnderflow);
    // Get the RX FIFO overflow flag
    uint8_t O = DSPI_HAL_GetStatusFlag(obj->spi.address,kDspiRxFifoOverflow);
    // Get the RX FIFO drain request flag
    uint8_t TXCTR = DSPI_HAL_GetFifoCountOrPtr(obj->spi.address, kDspiTxFifoCounter);
    // Get the number of words in the RX FIFO
    uint8_t RXCTR = DSPI_HAL_GetFifoCountOrPtr(obj->spi.address, kDspiRxFifoCounter);

    // The transfer is only complete if the TX buffer has been sent, the RX buffer has been filled, and there are no
    // values in the TX FIFO or RX FIFO
    if ((RXCTR == 0) && (TXCTR == 0) &&
        (obj->rx_buff.pos >= obj->rx_buff.length) &&
        (obj->tx_buff.pos >= obj->tx_buff.length)) {
        if (obj->spi.event & SPI_EVENT_COMPLETE) {
            event |= SPI_EVENT_COMPLETE;
        }
        event |= SPI_EVENT_INTERNAL_TRANSFER_COMPLETE; // process another transactions
    }
    // Signal an RX overflow event
    if ((obj->spi.event & SPI_EVENT_RX_OVERFLOW) && O) {
        event |= SPI_EVENT_RX_OVERFLOW;
    }
    // Signal a TX underflow event
    if ((obj->spi.event & SPI_EVENT_ERROR) && U) {
        event |= SPI_EVENT_ERROR;
    }

    return event;
}
Esempio n. 2
0
/*FUNCTION**********************************************************************
 *
 * Function Name : DSPI_DRV_MasterIRQHandler
 * Description   : Interrupt handler for DSPI master mode.
 * This handler uses the buffers stored in the dspi_master_state_t structs to transfer data.
 * This is not a public API as it is called whenever an interrupt occurs.
 *
 *END**************************************************************************/
void DSPI_DRV_MasterIRQHandler(uint32_t instance)
{
    /* instantiate local variable of type dspi_master_state_t and point to global state */
    dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance];

    SPI_Type *base = g_dspiBase[instance];

    /* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */
    if(dspiState->remainingReceiveByteCount)
    {
        /* Check read buffer.*/
        uint16_t wordReceived; /* Maximum supported data bit length in master mode is 16-bits */

        /* If bits/frame is greater than one byte */
        if (dspiState->bitsPerFrame > 8)
        {
            while (DSPI_HAL_GetStatusFlag(base, kDspiRxFifoDrainRequest))
            {
                wordReceived = DSPI_HAL_ReadData(base);
                /* clear the rx fifo drain request, needed for non-DMA applications as this flag
                 * will remain set even if the rx fifo is empty. By manually clearing this flag, it
                 * either remain clear if no more data is in the fifo, or it will set if there is
                 * more data in the fifo.
                 */
                DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest);

                /* Store read bytes into rx buffer only if a buffer pointer was provided */
                if(dspiState->receiveBuffer)
                {
                    /* For the last word received, if there is an extra byte due to the odd transfer
                     * byte count, only save the the last byte and discard the upper byte
                     */
                    if ((dspiState->remainingReceiveByteCount == 2) && (dspiState->extraByte))
                    {
                        *dspiState->receiveBuffer = wordReceived; /* Write first data byte */
                    }
                    else
                    {
                        *dspiState->receiveBuffer = wordReceived; /* Write first data byte */
                        ++dspiState->receiveBuffer; /* increment to next data byte */
                        *dspiState->receiveBuffer = wordReceived >> 8; /* Write second data byte */
                        ++dspiState->receiveBuffer; /* increment to next data byte */
                    }
                }
                dspiState->remainingReceiveByteCount -= 2;

                if (dspiState->remainingReceiveByteCount == 0)
                {
                    break;
                }
            } /* End of RX FIFO drain while loop */
        }
        /* Optimized for bits/frame less than or equal to one byte. */
        else
        {
            while (DSPI_HAL_GetStatusFlag(base, kDspiRxFifoDrainRequest))
Esempio n. 3
0
/**
 * Read SPI frames out of the RX FIFO
 * Continues reading frames out of the RX FIFO until the following condition is met:
 * o There are no more frames in the FIFO
 * OR BOTH OF:
 * o At least as many frames as the TX buffer have been received
 * o At least as many frames as the RX buffer have been received
 * This way, RX overflows are not generated when the TX buffer size exceeds the RX buffer size
 * @param[in] obj The SPI object on which to operate
 * @return Returns the number of frames extracted from the RX FIFO
 */
static uint32_t spi_master_read_asynch(spi_t *obj)
{
    uint32_t ndata = 0;
    // Calculate the maximum number of frames to receive
    uint32_t txRemaining = obj->tx_buff.length - min(obj->rx_buff.pos, obj->tx_buff.length);
    uint32_t rxRemaining = obj->rx_buff.length - min(obj->rx_buff.pos, obj->rx_buff.length);
    uint32_t maxRx = max(txRemaining, rxRemaining);
    // Receive frames until the maximum is reached or the RX FIFO is empty
    while ((ndata < maxRx) && DSPI_HAL_GetStatusFlag(obj->spi.address, kDspiRxFifoDrainRequest)) {
        spi_buffer_rx_read(obj);
        ndata++;
    }
    // Return the number of frames received
    return ndata;
}
Esempio n. 4
0
/**
 * Send words from the SPI TX buffer until the send limit is reached or the TX FIFO is full
 * TxLimit is provided to ensure that the number of SPI frames (words) in flight can be managed.
 * @param[in] obj     The SPI object on which to operate
 * @param[in] TxLimit The maximum number of words to send
 * @return The number of SPI frames that have been transfered
 */
static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t TxLimit)
{
    uint32_t ndata = 0;
    // Determine the number of frames to send
    uint32_t txRemaining = obj->tx_buff.length - min(obj->tx_buff.pos, obj->tx_buff.length);
    uint32_t rxRemaining = obj->rx_buff.length - min(obj->tx_buff.pos, obj->rx_buff.length);
    uint32_t maxTx = max(txRemaining, rxRemaining);
    maxTx = min(maxTx, TxLimit);
    // Send words until the FIFO is full or the send limit is reached
    while ((ndata < maxTx) && DSPI_HAL_GetStatusFlag(obj->spi.address, kDspiTxFifoFillRequest)) {
        spi_buffer_tx_write(obj);
        ndata++;
    }
    //Return the number of frames that have been sent
    return ndata;
}
Esempio n. 5
0
/*!
 * @brief DSPI master Polling.
 *
 * Thid function uses DSPI master to send an array to slave
 * and receive the array back from slave,
 * thencompare whether the two buffers are the same.
 */
int main(void)
{
    uint32_t i;
    uint32_t loopCount = 1;
    SPI_Type * dspiBaseAddr = (SPI_Type*)SPI0_BASE;
    uint32_t dspiSourceClock;
    uint32_t calculatedBaudRate;
    dspi_device_t masterDevice;
    dspi_command_config_t commandConfig = 
    {
        .isChipSelectContinuous = false,
        .whichCtar              = kDspiCtar0,
        .whichPcs               = kDspiPcs0,
        .clearTransferCount     = true,
        .isEndOfQueue           = false
    };

    // Init hardware
    hardware_init();
    // Init OSA layer, used in DSPI_DRV_MasterTransferBlocking.
    OSA_Init();
    // Call this function to initialize the console UART.  This function
    // enables the use of STDIO functions (printf, scanf, etc.)
    dbg_uart_init();
    // Print a note.
    printf("\r\n DSPI board to board polling example");
    printf("\r\n This example run on instance 0 ");
    printf("\r\n Be sure DSPI0-DSPI0 are connected ");

    // Configure SPI pins.
    configure_spi_pins(DSPI_MASTER_INSTANCE);

    // Enable DSPI clock.
    CLOCK_SYS_EnableSpiClock(DSPI_MASTER_INSTANCE);
    // Initialize the DSPI module registers to default value, which disables the module
    DSPI_HAL_Init(dspiBaseAddr);
    // Set to master mode.
    DSPI_HAL_SetMasterSlaveMode(dspiBaseAddr, kDspiMaster);
    // Configure for continuous SCK operation
    DSPI_HAL_SetContinuousSckCmd(dspiBaseAddr, false);
    // Configure for peripheral chip select polarity
    DSPI_HAL_SetPcsPolarityMode(dspiBaseAddr, kDspiPcs0, kDspiPcs_ActiveLow);
    // Disable FIFO operation.
    DSPI_HAL_SetFifoCmd(dspiBaseAddr, false, false);
    // Initialize the configurable delays: PCS-to-SCK, prescaler = 0, scaler = 1
    DSPI_HAL_SetDelay(dspiBaseAddr, kDspiCtar0, 0, 1, kDspiPcsToSck);
    // DSPI system enable
    DSPI_HAL_Enable(dspiBaseAddr);

    // Configure baudrate.
    masterDevice.dataBusConfig.bitsPerFrame = 8;
    masterDevice.dataBusConfig.clkPhase     = kDspiClockPhase_FirstEdge;
    masterDevice.dataBusConfig.clkPolarity  = kDspiClockPolarity_ActiveHigh;
    masterDevice.dataBusConfig.direction    = kDspiMsbFirst;

    DSPI_HAL_SetDataFormat(dspiBaseAddr, kDspiCtar0, &masterDevice.dataBusConfig);
    // Get DSPI source clock.
    dspiSourceClock = CLOCK_SYS_GetSpiFreq(DSPI_MASTER_INSTANCE);
    calculatedBaudRate = DSPI_HAL_SetBaudRate(dspiBaseAddr, kDspiCtar0, TRANSFER_BAUDRATE, dspiSourceClock);
    printf("\r\n Transfer at baudrate %lu \r\n", calculatedBaudRate);

    while(1)
    {
        // Initialize the transmit buffer.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            sendBuffer[i] = i + loopCount;
        }

        // Print out transmit buffer.
        printf("\r\n Master transmit:");
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Print 16 numbers in a line.
            if ((i & 0x0F) == 0)
            {
                printf("\r\n    ");
            }
            printf(" %02X", sendBuffer[i]);
        }

        // Reset the receive buffer.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            receiveBuffer[i] = 0;
        }

        // Restart the transfer by stop then start again, this will clear out the shift register
        DSPI_HAL_StopTransfer(dspiBaseAddr);
        // Flush the FIFOs
        DSPI_HAL_SetFlushFifoCmd(dspiBaseAddr, true, true);
        // Clear status flags that may have been set from previous transfers.
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxComplete);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiEndOfQueue);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoUnderflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoFillRequest);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoOverflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoDrainRequest);
        // Clear the transfer count.
        DSPI_HAL_PresetTransferCount(dspiBaseAddr, 0);
        // Start the transfer process in the hardware
        DSPI_HAL_StartTransfer(dspiBaseAddr);
        // Send the data to slave.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Write data to PUSHR
            DSPI_HAL_WriteDataMastermodeBlocking(dspiBaseAddr, &commandConfig, sendBuffer[i]);
            // Delay to wait slave is ready.
            OSA_TimeDelay(1);
        }

        // Delay to wait slave is ready.
        OSA_TimeDelay(10);

        // Restart the transfer by stop then start again, this will clear out the shift register
        DSPI_HAL_StopTransfer(dspiBaseAddr);
        // Flush the FIFOs
        DSPI_HAL_SetFlushFifoCmd(dspiBaseAddr, true, true);
        //Clear status flags that may have been set from previous transfers.
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxComplete);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiEndOfQueue);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoUnderflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoFillRequest);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoOverflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoDrainRequest);
        // Clear the transfer count.
        DSPI_HAL_PresetTransferCount(dspiBaseAddr, 0);
        // Start the transfer process in the hardware
        DSPI_HAL_StartTransfer(dspiBaseAddr);
        // Receive the data from slave.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Write command to PUSHR.
            DSPI_HAL_WriteDataMastermodeBlocking(dspiBaseAddr, &commandConfig, 0);
            // Check RFDR flag
            while (DSPI_HAL_GetStatusFlag(dspiBaseAddr, kDspiRxFifoDrainRequest)== false)
            {}
            // Read data from POPR
            receiveBuffer[i] = DSPI_HAL_ReadData(dspiBaseAddr);
            // Clear RFDR flag
            DSPI_HAL_ClearStatusFlag(dspiBaseAddr,kDspiRxFifoDrainRequest);
            // Delay to wait slave is ready.
            OSA_TimeDelay(1);
        }

        // Print out receive buffer.
        printf("\r\n Master receive:");
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Print 16 numbers in a line.
            if ((i & 0x0F) == 0)
            {
                printf("\r\n    ");
            }
            printf(" %02X", receiveBuffer[i]);
        }

        // Check receiveBuffer.
        for (i = 0; i < TRANSFER_SIZE; ++i)
        {
            if (receiveBuffer[i] != sendBuffer[i])
            {
                // Master received incorrect.
                printf("\r\n ERROR: master received incorrect ");
                return -1;
            }
        }

        printf("\r\n DSPI Master Sends/ Recevies Successfully");
        // Wait for press any key.
        printf("\r\n Press any key to run again");
        getchar();
        // Increase loop count to change transmit buffer.
        loopCount++;
    }
}
Esempio n. 6
0
/*!
 * @brief DSPI slave Polling.
 *
 * This function sends back received buffer from master through DSPI interface.
 */
int main(void)
{
    uint32_t i;
    SPI_Type * dspiBaseAddr = (SPI_Type*)SPI0_BASE;
    dspi_slave_user_config_t slaveConfig;

    // Init hardware
    hardware_init();
    // Init OSA layer, used in DSPI_DRV_MasterTransferBlocking.
    OSA_Init();
    // Call this function to initialize the console UART.  This function
    // enables the use of STDIO functions (printf, scanf, etc.)
    dbg_uart_init();
    // Configure SPI pins.
    configure_spi_pins(DSPI_SLAVE_INSTANCE);

    // Print a note.
    printf("\r\n DSPI board to board polling example");
    printf("\r\n This example run on instance 0 ");
    printf("\r\n Be sure DSPI0-DSPI0 are connected ");

    // Enable clock for DSPI
    CLOCK_SYS_EnableSpiClock(DSPI_SLAVE_INSTANCE);
    // Reset the DSPI module, which also disables the DSPI module
    DSPI_HAL_Init(dspiBaseAddr);
    // Set to slave mode.
    DSPI_HAL_SetMasterSlaveMode(dspiBaseAddr, kDspiSlave);
    // Set data format
    slaveConfig.dataConfig.clkPhase     = kDspiClockPhase_FirstEdge;
    slaveConfig.dataConfig.clkPolarity  = kDspiClockPolarity_ActiveHigh;
    slaveConfig.dataConfig.bitsPerFrame = 8;
    DSPI_HAL_SetDataFormat(dspiBaseAddr, kDspiCtar0, &(slaveConfig.dataConfig));
    // DSPI system enable
    DSPI_HAL_Enable(dspiBaseAddr);
    // Disable FIFO operation.
    DSPI_HAL_SetFifoCmd(dspiBaseAddr, false, false);

    while(1)
    {
         printf("\r\n Slave example is running...");
        // Reset the receive buffer.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            receiveBuffer[i] = 0;
        }

        // Restart the transfer by stop then start again, this will clear out the shift register
        DSPI_HAL_StopTransfer(dspiBaseAddr);
        // Flush the FIFOs
        DSPI_HAL_SetFlushFifoCmd(dspiBaseAddr, true, true);
        // Clear status flags that may have been set from previous transfers
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxComplete);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiEndOfQueue);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoUnderflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoFillRequest);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoOverflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoDrainRequest);
        // Clear the transfer count
        DSPI_HAL_PresetTransferCount(dspiBaseAddr, 0);
        // Start the transfer process in the hardware
        DSPI_HAL_StartTransfer(dspiBaseAddr);
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
                // Check RFDR flag
                while (DSPI_HAL_GetStatusFlag(dspiBaseAddr, kDspiRxFifoDrainRequest)== false)
                {}
                // Read data from POPR
                receiveBuffer[i] = DSPI_HAL_ReadData(dspiBaseAddr);
                // Clear RFDR flag
                DSPI_HAL_ClearStatusFlag(dspiBaseAddr,kDspiRxFifoDrainRequest);
        }

        // Restart the transfer by stop then start again, this will clear out the shift register
        DSPI_HAL_StopTransfer(dspiBaseAddr);
        // Flush the FIFOs
        DSPI_HAL_SetFlushFifoCmd(dspiBaseAddr, true, true);
        // Clear status flags that may have been set from previous transfers
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxComplete);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiEndOfQueue);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoUnderflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoFillRequest);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoOverflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoDrainRequest);
        // Clear the transfer count
        DSPI_HAL_PresetTransferCount(dspiBaseAddr, 0);
        // Start the transfer process in the hardware
        DSPI_HAL_StartTransfer(dspiBaseAddr);
        // Send the data to slave.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Write data to PUSHR
            DSPI_HAL_WriteDataSlavemodeBlocking(dspiBaseAddr, receiveBuffer[i]);
        }

        // Print out receive buffer.
        printf("\r\n Slave receive:");
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Print 16 numbers in a line.
            if ((i & 0x0F) == 0)
            {
                printf("\r\n    ");
            }
            printf(" %02X", receiveBuffer[i]);
        }
    }
}
Esempio n. 7
0
/*!
 * @brief Fill up the TX FIFO with data.
 * This function fills up the TX FIFO with initial data for start of transfers where it will
 * first clear the transfer count.  Otherwise, if the TX FIFO fill is part of an ongoing transfer
 * then do not clear the transfer count.  The param "isInitialData" is used to determine if this
 * is an initial data fill.
 * This is not a public API as it is called from other driver functions.
 */
static void DSPI_DRV_MasterFillupTxFifo(uint32_t instance)
{
    /* instantiate local variable of type dspi_master_state_t and point to global state */
    dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance];
    SPI_Type *base = g_dspiBase[instance];
    dspi_command_config_t command;  /* create an instance of the data command struct*/
    uint32_t cmd; /* Command word to be OR'd with data word */
    uint16_t wordToSend = 0;
    /* Declare variables for storing volatile data later in the code */
    uint32_t remainingReceiveByteCount, remainingSendByteCount;

    /* Before sending the data, we first need to initialize the data command struct
     * Configure the data command attributes for the desired PCS, CTAR, and continuous PCS
     * which are derived from the run-time state struct
     */
    command.whichPcs = dspiState->whichPcs;
    command.whichCtar = dspiState->whichCtar;
    command.isChipSelectContinuous = dspiState->isChipSelectContinuous;
    command.isEndOfQueue = 0;
    command.clearTransferCount = 0;

    /* "Build" the command word. Only do this once since the commad word members don't
     * change until the last word sent (which is when the end of queue flag gets set).
     */
    cmd = DSPI_HAL_GetFormattedCommand(base, &command);

    /* Store the DSPI state struct volatile member variables into temporary
     * non-volatile variables to allow for MISRA compliant calculations
     */
    remainingSendByteCount = dspiState->remainingSendByteCount;
    remainingReceiveByteCount = dspiState->remainingReceiveByteCount;

    /* Architectural note: When developing the TX FIFO fill functionality, it was found that to
     * achieve more efficient run-time performance, it was better to first check the bits/frame
     * setting and then proceed with the FIFO fill management process, rather than to clutter the
     * FIFO fill process with continual checks of the bits/frame setting.
     */

    /* If bits/frame is greater than one byte */
    if (dspiState->bitsPerFrame > 8)
    {
        /* Fill the fifo until it is full or until the send word count is 0 or until the difference
         * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth.
         * The reason for checking the difference is to ensure we only send as much as the
         * RX FIFO can receive.
         * For this case where bitsPerFrame > 8, each entry in the FIFO contains 2 bytes of the
         * send data, hence the difference between the remainingReceiveByteCount and
         * remainingSendByteCount must be divided by 2 to convert this difference into a
         * 16-bit (2 byte) value.
         */
        while((DSPI_HAL_GetStatusFlag(base, kDspiTxFifoFillRequest) == 1) &&
              ((remainingReceiveByteCount - remainingSendByteCount)/2 <
                g_dspiFifoSize[instance]))
        {
            /* On the last word to be sent, set the end of queue flag in the data command struct
             * and ensure that the CONT bit in the PUSHR is also cleared even if it was cleared to
             * begin with. If CONT is set it means continuous chip select operation and to ensure
             * the chip select is de-asserted, this bit must be cleared on the last data word.
             */
            if (dspiState->remainingSendByteCount == 2)
            {
                command.isEndOfQueue = 1;
                command.isChipSelectContinuous = 0;
                cmd = DSPI_HAL_GetFormattedCommand(base, &command);

                /* If there is an extra byte to send due to an odd byte count, prepare the final
                 * wordToSend here
                 */
                if (dspiState->sendBuffer)
                {
                    if (dspiState->extraByte)
                    {
                        wordToSend = *(dspiState->sendBuffer);
                    }
                    else
                    {
                        wordToSend = *(dspiState->sendBuffer);
                        ++dspiState->sendBuffer; /* increment to next data byte */
                        wordToSend |= (unsigned)(*(dspiState->sendBuffer)) << 8U;
                    }
                }
            }
            /* For all words except the last word */
            else
            {
                /* If a send buffer was provided, the word comes from there. Otherwise we just send
                 * a zero (initialized above).
                 */
                if (dspiState->sendBuffer)
                {
                    wordToSend = *(dspiState->sendBuffer);
                    ++dspiState->sendBuffer; /* increment to next data byte */
                    wordToSend |= (unsigned)(*(dspiState->sendBuffer)) << 8U;
                    ++dspiState->sendBuffer; /* increment to next data byte */
                }
            }
            DSPI_HAL_WriteCmdDataMastermode(base, cmd|wordToSend);

            /* Try to clear the TFFF; if the TX FIFO is full this will clear */
            DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest);

            dspiState->remainingSendByteCount -= 2; /* decrement remainingSendByteCount by 2 */

            /* exit loop if send count is zero, else update local variables for next loop */
            if (dspiState->remainingSendByteCount == 0)
            {
                break;
            }
            else
            {
                /* Store the DSPI state struct volatile member variables into temporary
                 * non-volatile variables to allow for MISRA compliant calculations
                 */
                remainingSendByteCount = dspiState->remainingSendByteCount;
            }
        } /* End of TX FIFO fill while loop */
    }
    /* Optimized for bits/frame less than or equal to one byte. */
    else
    {
        /* Fill the fifo until it is full or until the send word count is 0 or until the difference
         * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth.
         * The reason for checking the difference is to ensure we only send as much as the
         * RX FIFO can receive.
         */
        while((DSPI_HAL_GetStatusFlag(base, kDspiTxFifoFillRequest) == 1) &&
              ((remainingReceiveByteCount - remainingSendByteCount) <
                g_dspiFifoSize[instance]))
        {
            /* On the last word to be sent, set the end of queue flag in the data command struct
             * and ensure that the CONT bit in the PUSHR is also cleared even if it was cleared to
             * begin with. If CONT is set it means continuous chip select operation and to ensure
             * the chip select is de-asserted, this bit must be cleared on the last data word.
             */
            if (dspiState->remainingSendByteCount == 1)
            {
                command.isEndOfQueue = 1;
                command.isChipSelectContinuous = 0;
                cmd = DSPI_HAL_GetFormattedCommand(base, &command);
            }

            /* If a send buffer was provided, the word comes from there. Otherwise we just send
             * a zero (initialized above).
             */
            if (dspiState->sendBuffer)
            {
                wordToSend = *(dspiState->sendBuffer);
                ++dspiState->sendBuffer; /* increment to next data word*/
            }
            DSPI_HAL_WriteCmdDataMastermode(base, cmd|wordToSend);

            /* Try to clear the TFFF; if the TX FIFO is full this will clear */
            DSPI_HAL_ClearStatusFlag(base, kDspiTxFifoFillRequest);

            --dspiState->remainingSendByteCount; /* decrement remainingSendByteCount*/

            /* exit loop if send count is zero, else update local variables for next loop */
            if (dspiState->remainingSendByteCount == 0)
            {
                break;
            }
            else
            {
                /* Store the DSPI state struct volatile member variables into temporary
                 * non-volatile variables to allow for MISRA compliant calculations
                 */
                remainingSendByteCount = dspiState->remainingSendByteCount;
            }
        } /* End of TX FIFO fill while loop */
    }
}
Esempio n. 8
0
static inline int spi_readable(spi_t * obj) {
    return DSPI_HAL_GetStatusFlag(obj->spi.address, kDspiRxFifoDrainRequest);
}
Esempio n. 9
0
static inline int spi_writeable(spi_t * obj) {
    return DSPI_HAL_GetStatusFlag(obj->spi.address, kDspiTxFifoFillRequest);
}
Esempio n. 10
0
uint16_t SpiInOut(Spi_t *obj, uint16_t outData)
{
    uint16_t data = 0x00;

    if ((obj == NULL) || (obj->Spi) == NULL) {
        while (1)
            ;
    }

    if (obj->isSlave) {

    } else {
        dspi_command_config_t
        commandConfig =
        {
            .isChipSelectContinuous = false,
            .whichCtar = kDspiCtar0,
            .whichPcs = kDspiPcs0,
            .clearTransferCount = true,
            .isEndOfQueue = false
        };
        if (outData != 0x00) {
            // Restart the transfer by stop then start again, this will clear out the shift register
            DSPI_HAL_StopTransfer(obj->Spi);
            // Flush the FIFOs
            DSPI_HAL_SetFlushFifoCmd(obj->Spi, true, true);
            // Clear status flags that may have been set from previous transfers.
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiTxComplete);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiEndOfQueue);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiTxFifoUnderflow);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiTxFifoFillRequest);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiRxFifoOverflow);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiRxFifoDrainRequest);
            // Clear the transfer count.
            DSPI_HAL_PresetTransferCount(obj->Spi, 0);
            // Start the transfer process in the hardware
            DSPI_HAL_StartTransfer(obj->Spi);
            // Send the data to slave.
            // Write data to PUSHR
            DSPI_HAL_WriteDataMastermode(obj->Spi, &commandConfig, outData);
        } else {
            // Restart the transfer by stop then start again, this will clear out the shift register
            DSPI_HAL_StopTransfer(obj->Spi);
            // Flush the FIFOs
            DSPI_HAL_SetFlushFifoCmd(obj->Spi, true, true);
            //Clear status flags that may have been set from previous transfers.
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiTxComplete);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiEndOfQueue);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiTxFifoUnderflow);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiTxFifoFillRequest);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiRxFifoOverflow);
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiRxFifoDrainRequest);
            // Clear the transfer count.
            DSPI_HAL_PresetTransferCount(obj->Spi, 0);
            // Start the transfer process in the hardware
            DSPI_HAL_StartTransfer(obj->Spi);
            // Write command to PUSHR.
            DSPI_HAL_WriteDataMastermode(obj->Spi, &commandConfig, 0);
            // Check RFDR flag
            while (DSPI_HAL_GetStatusFlag(obj->Spi, kDspiRxFifoDrainRequest) == false) {
            }
            // Read data from POPR
            data = DSPI_HAL_ReadData(obj->Spi);
            // Clear RFDR flag
            DSPI_HAL_ClearStatusFlag(obj->Spi, kDspiRxFifoDrainRequest);
        }
    }
    return data;
}
Esempio n. 11
0
/*FUNCTION**********************************************************************
 *
 * Function Name : DSPI_DRV_SlaveIRQHandler
 * Description   : DSPI Slave Generic IRQ handler.
 *
 * This handler check errors of driver and it puts data into Tx FIFO, gets data
 * from Rx FIFO whenever data transmitting/received.
 *
 *END**************************************************************************/
void DSPI_DRV_SlaveIRQHandler(uint32_t instance)
{
    SPI_Type *base = g_dspiBase[instance];
    dspi_slave_state_t *dspiState = (dspi_slave_state_t *)g_dspiStatePtr[instance];
    uint8_t nBytes;

    /* Calculate number of bytes in a frame */
    nBytes = dspiState->bitsPerFrame >> 3;      /* Number of bytes is bits/frame divide 8 */
    if ((dspiState->bitsPerFrame & 0x07) != 0)  /* Bits/frame module 8 is not zero */
    {
        nBytes += 1;
    }

    /* Because SPI protocol is synchronous, the number of bytes that that slave received from the
     * master is the actual number of bytes that the slave transmitted to the master. So we only
     * monitor the received size to know when the transfer is complete.
     */
    if (dspiState->remainingReceiveByteCount > 0)
    {
        /* Read data if remaining receive byte > 0 */
        uint32_t dataReceived;
        uint32_t dataSend = 0;

        while (DSPI_HAL_GetStatusFlag(base, kDspiRxFifoDrainRequest))
        {
            /* Have received data in the buffer. */
            dataReceived = DSPI_HAL_ReadData(base);
            /* clear the rx fifo drain request, needed for non-DMA applications as this flag
             * will remain set even if the rx fifo is empty. By manually clearing this flag, it
             * either remain clear if no more data is in the fifo, or it will set if there is
             * more data in the fifo.
             */
            DSPI_HAL_ClearStatusFlag(base, kDspiRxFifoDrainRequest);

            /* If bits/frame is one byte */
            if (nBytes == 1)
            {
                if (dspiState->receiveBuffer)
                {
                    /* Receive buffer is not null, store data into it */
                    *dspiState->receiveBuffer = dataReceived;
                    ++dspiState->receiveBuffer;
                }
                if (dspiState->sendBuffer)
                {
                    dataSend = *dspiState->sendBuffer;
                    ++dspiState->sendBuffer;
                }

                /* Descrease remaining receive byte count */
                --dspiState->remainingReceiveByteCount;
                --dspiState->remainingSendByteCount;
            }
            /* If bits/frame is 2 bytes */
            else
            {
                /* With multibytes frame receiving, we only receive till the received size
                 * matches user request. Other bytes will be ignored.
                 */
                if (dspiState->receiveBuffer)
                {
                    /* Receive buffer is not null, store first byte into it */
                    *dspiState->receiveBuffer = dataReceived;
                    ++dspiState->receiveBuffer;

                    if (--dspiState->remainingReceiveByteCount > 0)
                    {
                        /* Receive buffer is not null, store second byte into it */
                        *dspiState->receiveBuffer = dataReceived >> 8;
                        ++dspiState->receiveBuffer;
                    }

                    /* Decrease remaining receive byte count */
                    --dspiState->remainingReceiveByteCount;
                }
                else
                {