⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dspi.c

📁 Freescale MCF5445evb 参考测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*! * \file    dspi.c * \brief   Driver for the DSPI module * \version $Revision: 1.3 $ * \author  Michael Norman * * \todo    add DMA support * \todo    add slave support * \todo    add support for advanced options (MTFE, FRZ, etc.) */#include "common.h"#include "clock.h"#include "queue.h"#include "dspi.h"/********************************************************************//*! Driver data  */struct spi_driver_data drv_data = {    .status = SPI_DRIVER_IDLE,};/********************************************************************//*! * \brief   Initialize the DSPI module for Master mode * \return  Zero for success; Non-zero otherwise. */intspi_master_init(void){    /* Initialize the driver data struct */    memset(&drv_data, 0, sizeof(struct spi_driver_data));    queue_init(&drv_data.queue);    /* Enable pins for DSPI mode - chip-selects are enabled later */    MCF_GPIO_PAR_DSPI = 0        | MCF_GPIO_PAR_DSPI_SIN_SIN        | MCF_GPIO_PAR_DSPI_SOUT_SOUT        | MCF_GPIO_PAR_DSPI_SCK_SCK;	/* Configure DSPI module */    MCF_DSPI_DMCR = 0           /* clear halt bit */        | MCF_DSPI_DMCR_MSTR    /* master mode */        | MCF_DSPI_DMCR_CLRTXF  /* clear Tx FIFO */        | MCF_DSPI_DMCR_CLRRXF; /* clear Rx FIFO */	/* Enable desired interrupts in DSPI module */    MCF_DSPI_DRSER = 0        | MCF_DSPI_DRSER_EOQFE;    /*  | MCF_DSPI_DRSER_RFDFS        | MCF_DSPI_DRSER_RFDFE        | MCF_DSPI_DRSER_RFOFE        | MCF_DSPI_DRSER_TFFFS        | MCF_DSPI_DRSER_TFFFE        | MCF_DSPI_DRSER_TFUFE        | MCF_DSPI_DRSER_TCFE; */    /* Enable DSPI interrupts in interrupt controller */    MCF_INTC1_ICR33 = MCF_INTC_ICR_IL(0x01);	MCF_INTC1_ICR34 = MCF_INTC_ICR_IL(0x01);	MCF_INTC1_ICR35 = MCF_INTC_ICR_IL(0x01);	MCF_INTC1_ICR36 = MCF_INTC_ICR_IL(0x01);	MCF_INTC1_ICR37 = MCF_INTC_ICR_IL(0x01);	MCF_INTC1_ICR38 = MCF_INTC_ICR_IL(0x01);	MCF_INTC1_ICR39 = MCF_INTC_ICR_IL(0x01);	MCF_INTC1_IMRH &= ~(0        | MCF_INTC_IMRH_INT_MASK33        | MCF_INTC_IMRH_INT_MASK34        | MCF_INTC_IMRH_INT_MASK35        | MCF_INTC_IMRH_INT_MASK36        | MCF_INTC_IMRH_INT_MASK37        | MCF_INTC_IMRH_INT_MASK38        | MCF_INTC_IMRH_INT_MASK39);    mcf5xxx_set_handler (128 + 33, (ADDRESS) spi_master_irq_handler);    mcf5xxx_set_handler (128 + 34, (ADDRESS) spi_master_irq_handler);    mcf5xxx_set_handler (128 + 35, (ADDRESS) spi_master_irq_handler);    mcf5xxx_set_handler (128 + 36, (ADDRESS) spi_master_irq_handler);    mcf5xxx_set_handler (128 + 37, (ADDRESS) spi_master_irq_handler);    mcf5xxx_set_handler (128 + 38, (ADDRESS) spi_master_irq_handler);    mcf5xxx_set_handler (128 + 39, (ADDRESS) spi_master_irq_handler);	return 0;}/********************************************************************//*! * \brief   Initialize SPI slave device interface * \todo    finish this! * \param   device SPI Device */intspi_master_device_init (SPI_DEVICE *device){    int i, j, temp;    uint32 ctar = 0;    int fbus = clock_get_fbus();    /* Enable appropriate pin for DSPI CS use */    switch (device->cs) {        case 0:            MCF_GPIO_PAR_DSPI |= MCF_GPIO_PAR_DSPI_PCS0_PCS0;            if (device->cs_is) MCF_DSPI_DMCR |= MCF_DSPI_DMCR_PCSIS0;            break;        case 1:            MCF_GPIO_PAR_DSPI |= MCF_GPIO_PAR_DSPI_PCS1_PCS1;            if (device->cs_is) MCF_DSPI_DMCR |= MCF_DSPI_DMCR_PCSIS1;            break;        case 2:            MCF_GPIO_PAR_DSPI |= MCF_GPIO_PAR_DSPI_PCS2_PCS2;            if (device->cs_is) MCF_DSPI_DMCR |= MCF_DSPI_DMCR_PCSIS2;            break;        case 5:            MCF_GPIO_PAR_DSPI |= MCF_GPIO_PAR_DSPI_PCS5_PCS5;            if (device->cs_is) MCF_DSPI_DMCR |= MCF_DSPI_DMCR_PCSIS5;            break;        default:            ASSERT(0);    }        /* frame size */    ASSERT ((device->frame_size >= 4) && (device->frame_size <= 16));    ctar |= MCF_DSPI_DCTAR_FMSZ(device->frame_size - 1);        /* clock polarity and phase */    switch (device->mode) {        case SPI_MODE_0:            ctar |= 0                | MCF_DSPI_DCTAR_CPOL_LOW                | MCF_DSPI_DCTAR_CPHA_LATCH_RISING;            break;        case SPI_MODE_1:            ctar |= 0                | MCF_DSPI_DCTAR_CPOL_LOW                | MCF_DSPI_DCTAR_CPHA_LATCH_FALLING;            break;        case SPI_MODE_2:            ctar |= 0                | MCF_DSPI_DCTAR_CPOL_HIGH                | MCF_DSPI_DCTAR_CPHA_LATCH_RISING;            break;        case SPI_MODE_3:            ctar |= 0                | MCF_DSPI_DCTAR_CPOL_HIGH                | MCF_DSPI_DCTAR_CPHA_LATCH_FALLING;            break;        default:            ASSERT(0);    }        /* first bit */    if (device->fbit == SPI_FBIT_LSB)        ctar |= MCF_DSPI_DCTAR_LSBFE;        /* chip-select assertion to first clk edge delay */    temp = (device->delay_csclk * (fbus / 1000)) / 1000000;    ASSERT(temp < 65536); /* need to implement prescaler in this case */    if (temp > 2)    {        /* Round scaler up to nearest power of two */        temp = (temp * 2) - 1;        for (i = 0, j = temp; j != 1; j >>= 1, i++) {};        ctar |= MCF_DSPI_DCTAR_CSSCK(i - 1);    }    else    {        ctar |= MCF_DSPI_DCTAR_CSSCK(0);    }        /* last clk edge to chip-select deassertion delay */    temp = (device->delay_clkcs * (fbus / 1000)) / 1000000;    ASSERT(temp < 65536); /* need to implement prescaler in this case */    if (temp > 2)    {        /* Round scaler up to nearest power of two */        temp = (temp * 2) - 1;        for (i = 0, j = temp; j != 1; j >>= 1, i++) {};        ctar |= MCF_DSPI_DCTAR_ASC(i - 1);    }    else    {        ctar |= MCF_DSPI_DCTAR_ASC(0);    }        /* chip-select deassertion to chip-select assertion delay */    temp = (device->delay_cscs * (fbus / 1000)) / 1000000;    ASSERT(temp < 65536); /* need to implement prescaler in this case */    if (temp > 2)    {        /* Round scaler up to nearest power of two */        temp = (temp * 2) - 1;        for (i = 0, j = temp; j != 1; j >>= 1, i++) {};        ctar |= MCF_DSPI_DCTAR_DT(i - 1);    }    else    {        ctar |= MCF_DSPI_DCTAR_DT(0);    }        /* baud rate (assume PBR = 00 and DBR = 1; BR = fbus / baud ) */    temp = fbus / device->baud;    ASSERT(temp < 65536); /* need to implement prescaler in this case */    if (temp > 2)    {        /* Round scaler up to nearest power of two */        temp = (temp * 2) - 1;        for (i = 0, j = temp; j != 1; j >>= 1, i++) {};        ctar |= 0            | MCF_DSPI_DCTAR_DBR            | MCF_DSPI_DCTAR_BR(i - 1);    }    else    {        ctar |= 0            | MCF_DSPI_DCTAR_DBR            | MCF_DSPI_DCTAR_BR(0);    }        /*      * Store the transfer attributes in the register corresponding to the CS      * This isn't required, but done here to simplify the driver.     */    MCF_DSPI_DCTAR(device->cs) = ctar;}/********************************************************************//*! * Write to SPI slave. * \param   spi_device  SPI device to communicate with * \param   buffer      Buffer holding data to be written * \param   length      Number of bytes to write * \param   wait        Wait for the command to complete? * \return  Zero for success; Non-zero otherwise. *  * Write the buffer to the specified SPI device.  This will stall to wait for  * the DSPI to be available if it is busy with another transfer */intspi_master_write(SPI_DEVICE *device, uint8 *tx_buf, int length){    SPI_MSG_CHAIN m;    SPI_MSG_LINK l;        memset(&m, 0, sizeof(SPI_MSG_CHAIN));    m.device    = device;    m.link      = &l;    memset(&l, 0, sizeof(SPI_MSG_LINK));    l.tx_buf    = tx_buf;    l.length    = length;    l.next      = NULL;        /* Queue it up */    spi_master_enqueue(&m);        /* Wait for the transfer to finish */    while (m.status != SPI_MSG_CHAIN_DONE) {};    	return 0;}/********************************************************************//*! * Read from SPI slave. * \param   spi_device  SPI device to communicate with * \param   buffer      Buffer to hold read data * \param   length      Number of bytes to read * \return  Zero for success; Non-zero otherwise. *  * Read data from a SPI device into the receive buffer. This will stall to wait * for the DSPI to be available if it is busy with another transfer. */intspi_master_read(SPI_DEVICE *device, uint8 *rx_buf, int length){    SPI_MSG_CHAIN m;    SPI_MSG_LINK l;        memset(&m, 0, sizeof(SPI_MSG_CHAIN));    m.device    = device;    m.link      = &l;    memset(&l, 0, sizeof(SPI_MSG_LINK));    l.tx_buf    = rx_buf;    l.length    = length;    l.next      = NULL;        /* Queue it up */    spi_master_enqueue(&m);        /* Wait for the transfer to finish */    while (m.status != SPI_MSG_CHAIN_DONE) {};    	return 0;}/********************************************************************//*! * Perform a synchronous, full duplex transfer to/from an SPI slave * \param   dev     SPI device to communicate with

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -