i2c对比spi-帧结构

来源:互联网 发布:网络销售怎么找客户 编辑:程序博客网 时间:2024/06/05 04:45
我要啦免费统计spi
/** * struct spi_transfer - a read/write buffer pair * @tx_buf: data to be written (dma-safe memory), or NULL * @rx_buf: data to be read (dma-safe memory), or NULL * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped * @len: size of rx and tx buffers (in bytes) * @speed_hz: Select a speed other than the device default for this *      transfer. If 0 the default (from @spi_device) is used. * @bits_per_word: select a bits_per_word other than the device default *      for this transfer. If 0 the default (from @spi_device) is used. * @cs_change: affects chipselect after this transfer completes * @delay_usecs: microseconds to delay after this transfer before *(optionally) changing the chipselect status, then starting *the next transfer or completing this @spi_message. * @transfer_list: transfers are sequenced through @spi_message.transfers * * SPI transfers always write the same number of bytes as they read. * Protocol drivers should always provide @rx_buf and/or @tx_buf. * In some cases, they may also want to provide DMA addresses for * the data being transferred; that may reduce overhead, when the * underlying driver uses dma. * * If the transmit buffer is null, zeroes will be shifted out * while filling @rx_buf.  If the receive buffer is null, the data * shifted in will be discarded.  Only "len" bytes shift out (or in). * It's an error to try to shift out a partial word.  (For example, by * shifting out three bytes with word size of sixteen or twenty bits; * the former uses two bytes per word, the latter uses four bytes.) * * In-memory data values are always in native CPU byte order, translated * from the wire byte order (big-endian except with SPI_LSB_FIRST).  So * for example when bits_per_word is sixteen, buffers are 2N bytes long * (@len = 2N) and hold N sixteen bit words in CPU byte order. * * When the word size of the SPI transfer is not a power-of-two multiple * of eight bits, those in-memory words include extra bits.  In-memory * words are always seen by protocol drivers as right-justified, so the * undefined (rx) or unused (tx) bits are always the most significant bits. * * All SPI transfers start with the relevant chipselect active.  Normally * it stays selected until after the last transfer in a message.  Drivers * can affect the chipselect signal using cs_change. * * (i) If the transfer isn't the last one in the message, this flag is * used to make the chipselect briefly go inactive in the middle of the * message.  Toggling chipselect in this way may be needed to terminate * a chip command, letting a single spi_message perform all of group of * chip transactions together. * * (ii) When the transfer is the last one in the message, the chip may * stay selected until the next transfer.  On multi-device SPI busses * with nothing blocking messages going to other devices, this is just * a performance hint; starting a message to another device deselects * this one.  But in other cases, this can be used to ensure correctness. * Some devices need protocol transactions to be built from a series of * spi_message submissions, where the content of one message is determined * by the results of previous messages and where the whole transaction * ends when the chipselect goes intactive. * * The code that submits an spi_message (and its spi_transfers) * to the lower layers is responsible for managing its memory. * Zero-initialize every field you don't set up explicitly, to * insulate against future API updates.  After you submit a message * and its transfers, ignore them until its completion callback. */struct spi_transfer {/* it's ok if tx_buf == rx_buf (right?) * for MicroWire, one buffer must be null * buffers must work with dma_*map_single() calls, unless *   spi_message.is_dma_mapped reports a pre-existing mapping */const void*tx_buf;void*rx_buf;unsignedlen;dma_addr_ttx_dma;dma_addr_trx_dma;unsignedcs_change:1;u8bits_per_word;u16delay_usecs;u32speed_hz;struct list_head transfer_list;};/** * struct spi_message - one multi-segment SPI transaction * @transfers: list of transfer segments in this transaction * @spi: SPI device to which the transaction is queued * @is_dma_mapped: if true, the caller provided both dma and cpu virtual *    addresses for each transfer buffer * @complete: called to report transaction completions * @context: the argument to complete() when it's called * @actual_length: the total number of bytes that were transferred in all *    successful segments * @status: zero for success, else negative errno * @queue: for use by whichever driver currently owns the message * @state: for use by whichever driver currently owns the message * * A @spi_message is used to execute an atomic sequence of data transfers, * each represented by a struct spi_transfer.  The sequence is "atomic" * in the sense that no other spi_message may use that SPI bus until that * sequence completes.  On some systems, many such sequences can execute as * as single programmed DMA transfer.  On all systems, these messages are * queued, and might complete after transactions to other devices.  Messages * sent to a given spi_device are alway executed in FIFO order. * * The code that submits an spi_message (and its spi_transfers) * to the lower layers is responsible for managing its memory. * Zero-initialize every field you don't set up explicitly, to * insulate against future API updates.  After you submit a message * and its transfers, ignore them until its completion callback. */struct spi_message {    struct list_head    transfers;    struct spi_device    *spi;    unsigned        is_dma_mapped:1;    /* REVISIT:  we might want a flag affecting the behavior of the     * last transfer ... allowing things like "read 16 bit length L"     * immediately followed by "read L bytes".  Basically imposing     * a specific message scheduling algorithm.     *     * Some controller drivers (message-at-a-time queue processing)     * could provide that as their default scheduling algorithm.  But     * others (with multi-message pipelines) could need a flag to     * tell them about such special cases.     */    /* completion is reported through a callback */    void            (*complete)(void *context);    void            *context;    unsigned        actual_length;    int            status;    /* for optional use by whatever driver currently owns the     * spi_message ...  between calls to spi_async and then later     * complete(), that's the spi_master controller driver.     */    struct list_head    queue;    void            *state;};
spi_transfer是传输的基本元素,将n个spi_transfer加入到spi_message,然后启动传输
使用如下函数发送spi_message
    spi_message_add_tail(&t, &m);
    ret = spi_sync(spi, &m);
其调用spi_s3c64xx.c的s3c64xx_spi_transfer-----s3c64xx_spi_work----handle_msg----wait_for_xfer收发数据

i2c

/** * struct i2c_msg - an I2C transaction segment beginning with START * @addr: Slave address, either seven or ten bits.  When this is a ten *bit address, I2C_M_TEN must be set in @flags and the adapter *must support I2C_FUNC_10BIT_ADDR. * @flags: I2C_M_RD is handled by all adapters.  No other flags may be *provided unless the adapter exported the relevant I2C_FUNC_* *flags through i2c_check_functionality(). * @len: Number of data bytes in @buf being read from or written to the *I2C slave address.  For read transactions where I2C_M_RECV_LEN *is set, the caller guarantees that this buffer can hold up to *32 bytes in addition to the initial length byte sent by the *slave (plus, if used, the SMBus PEC); and this value will be *incremented by the number of block data bytes received. * @buf: The buffer into which data is read, or from which it's written. * * An i2c_msg is the low level representation of one segment of an I2C * transaction.  It is visible to drivers in the @i2c_transfer() procedure, * to userspace from i2c-dev, and to I2C adapter drivers through the * @i2c_adapter.@master_xfer() method. * * Except when I2C "protocol mangling" is used, all I2C adapters implement * the standard rules for I2C transactions.  Each transaction begins with a * START.  That is followed by the slave address, and a bit encoding read * versus write.  Then follow all the data bytes, possibly including a byte * with SMBus PEC.  The transfer terminates with a NAK, or when all those * bytes have been transferred and ACKed.  If this is the last message in a * group, it is followed by a STOP.  Otherwise it is followed by the next * @i2c_msg transaction segment, beginning with a (repeated) START. * * Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then * passing certain @flags may have changed those standard protocol behaviors. * Those flags are only for use with broken/nonconforming slaves, and with * adapters which are known to support the specific mangling options they * need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR). */struct i2c_msg {__u16 addr;/* slave address*/__u16 flags;#define I2C_M_TEN0x0010/* this is a ten bit chip address */#define I2C_M_RD0x0001/* read data, from slave to master */#define I2C_M_NOSTART0x4000/* if I2C_FUNC_PROTOCOL_MANGLING */#define I2C_M_REV_DIR_ADDR0x2000/* if I2C_FUNC_PROTOCOL_MANGLING */#define I2C_M_IGNORE_NAK0x1000/* if I2C_FUNC_PROTOCOL_MANGLING */#define I2C_M_NO_RD_ACK0x0800/* if I2C_FUNC_PROTOCOL_MANGLING */#define I2C_M_RECV_LEN0x0400/* length will be first received byte */__u16 len;/* msg length*/__u8 *buf;/* pointer to msg data*/};

使用如下函数发送i2c_msg
ret = i2c_transfer(adap, &msg, num);
其调用i2c-s3c2410.c的s3c24xx_i2c_xfer---s3c24xx_i2c_doxfer---s3c24xx_i2c_message_start()和中断处理函数共同收发数据。

原创粉丝点击