/////////////////////////////////////////////////////////////////////////////////// // File : spi_driver.h // Date : 31/08/2012 // Author : cesar fuguet // Copyright (c) UPMC-LIP6 /////////////////////////////////////////////////////////////////////////////////// #ifndef BOOT_SPI_UTILS #define BOOT_SPI_UTILS //#include #include /////////////////////////////////////////////////////////////////////////////// // SPI structure definition /////////////////////////////////////////////////////////////////////////////// struct boot_spi_dev { // RX/TX registers of the SPI controller unsigned int rx_tx[4]; // control register of the SPI controller unsigned int ctrl; // divider register for the SPI controller generated clock signal unsigned int divider; // slave select register of the SPI controller unsigned int ss; // SPI-DMA registers unsigned int dma_base; unsigned int dma_baseh; unsigned int dma_count; }; void spi_put_tx(struct boot_spi_dev * spi, unsigned char byte, int index); inline volatile unsigned char spi_get_rx(struct boot_spi_dev * spi, int index); unsigned int spi_get_data(struct boot_spi_dev * spi, paddr_t buffer, unsigned int count); inline void spi_ss_assert(struct boot_spi_dev * spi, int index); inline void spi_ss_deassert(struct boot_spi_dev * spi, int index); void _spi_init ( struct boot_spi_dev * spi, int spi_freq , int sys_freq , int char_len , int tx_edge , int rx_edge ); /////////////////////////////////////////////////////////////////////////////// // SPI macros and constants /////////////////////////////////////////////////////////////////////////////// #define SPI_TX_POSEDGE 1 // MOSI is changed on neg edge #define SPI_TX_NEGEDGE 0 // MOSI is changed on pos edge #define SPI_RX_POSEDGE 1 // MISO is latched on pos edge #define SPI_RX_NEGEDGE 0 // MISO is latched on neg edge #define SPI_CTRL_ASS_EN ( 1 << 13 ) // Auto Slave Sel Assertion #define SPI_CTRL_IE_EN ( 1 << 12 ) // Interrupt Enable #define SPI_CTRL_LSB_EN ( 1 << 11 ) // LSB are sent first #define SPI_CTRL_TXN_EN ( 1 << 10 ) // MOSI is changed on neg edge #define SPI_CTRL_RXN_EN ( 1 << 9 ) // MISO is latched on neg edge #define SPI_CTRL_GO_BSY ( 1 << 8 ) // Start the transfer #define SPI_CTRL_DMA_BSY ( 1 << 16 ) // DMA in progress #define SPI_CTRL_CHAR_LEN_MASK ( 0xFF ) // Bits transmited in 1 transfer #define SPI_RXTX_MASK ( 0xFF ) // Mask for the an RX/TX value #define SPI_DMA_COUNT_READ ( 1 << 0 ) // operation is a read (else write) /////////////////////////////////////////////////////////////////////////////// // SPI_IS_BUSY() // This macro checks the GO_BSY and DMA_BSY bits of the SPI controller which // indicates an ongoing transfer. // // Returns 1 if there is an unfinished transfer /////////////////////////////////////////////////////////////////////////////// #define SPI_IS_BUSY(x) \ ((ioread32(&x->ctrl) & (SPI_CTRL_GO_BSY|SPI_CTRL_DMA_BSY)) != 0) ? 1 : 0 #endif /////////////////////////////////////////////////////////////////////////////////// // Read an 32 bits memory mapped hardware register /////////////////////////////////////////////////////////////////////////////////// static inline unsigned int ioread32(void * addr) { return *(volatile unsigned int *) addr; } /////////////////////////////////////////////////////////////////////////////////// // Read an 16 bits memory mapped hardware register /////////////////////////////////////////////////////////////////////////////////// static inline unsigned short ioread16(void * addr) { return *(volatile unsigned short *) addr; } /////////////////////////////////////////////////////////////////////////////////// // Read an 8 bits memory mapped hardware register /////////////////////////////////////////////////////////////////////////////////// static inline unsigned char ioread8(void * addr) { return *(volatile unsigned char *) addr; } /////////////////////////////////////////////////////////////////////////////////// // Write an 32 bits memory mapped hardware register /////////////////////////////////////////////////////////////////////////////////// static inline void iowrite32(void * addr, unsigned int value) { *(volatile unsigned int *) addr = value; asm volatile("sync" ::: "memory"); } /////////////////////////////////////////////////////////////////////////////////// // Write an 16 bits memory mapped hardware register /////////////////////////////////////////////////////////////////////////////////// static inline void iowrite16(void * addr, unsigned short value) { *(volatile unsigned short *) addr = value; asm volatile("sync" ::: "memory"); } /////////////////////////////////////////////////////////////////////////////////// // Write an 8 bits memory mapped hardware register /////////////////////////////////////////////////////////////////////////////////// static inline void iowrite8(void * addr, unsigned char value) { *(volatile unsigned char *) addr = value; asm volatile("sync" ::: "memory"); } // Local Variables: // tab-width: 4 // c-basic-offset: 4 // c-file-offsets:((innamespace . 0)(inline-open . 0)) // indent-tabs-mode: nil // End: // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4