00001
00038 #include <assert.h>
00039 #include <bitops.h>
00040 #include <spi.h>
00041 #include <board/spi.h>
00042
00053 void spi_polled_next_buffer(struct workqueue_task *task)
00054 {
00055 struct spi_master_polled *spim_poll =
00056 container_of(task, struct spi_master_polled, poll_next_buffer);
00057 struct spi_master *spim = &spim_poll->base;
00058 size_t len = 0;
00059 uint8_t tx_byte = 0;
00060
00061 if (test_bit(SPI_OP_READ, &spim_poll->op)) {
00062 if (slist_node_is_last(spim_poll->read_buf_list,
00063 &spim_poll->read_buffer->node))
00064 goto done;
00065 spim_poll->read_buffer =
00066 buf_list_peek_next(spim_poll->read_buffer);
00067 spim_poll->read_data = spim_poll->read_buffer->addr.ptr;
00068 len = spim_poll->read_buffer->len;
00069 }
00070 if (test_bit(SPI_OP_WRITE, &spim_poll->op)) {
00071 if (slist_node_is_last(spim_poll->write_buf_list,
00072 &spim_poll->write_buffer->node))
00073 goto done;
00074 spim_poll->write_buffer =
00075 buf_list_peek_next(spim_poll->write_buffer);
00076 tx_byte = *(uint8_t *)spim_poll->write_buffer->addr.ptr;
00077 spim_poll->write_data =
00078 (uint8_t *)spim_poll->write_buffer->addr.ptr + 1;
00079 len = spim_poll->write_buffer->len;
00080 }
00081 spi_polled_start(spim, tx_byte, len);
00082 return;
00083
00084 done:
00085 spim->residue = 0;
00086 spim->status = STATUS_OK;
00087 workqueue_add_task(&main_workqueue, spim->nwq.current);
00088 }
00089
00094 void spi_polled_write_buf_list(struct spi_master *spim, struct slist *buf_list)
00095 {
00096 struct spi_master_polled *spim_poll = spi_master_polled_of(spim);
00097 struct buffer *buffer;
00098 const uint8_t *write;
00099
00100 buffer = buf_list_peek_head(buf_list);
00101 write = buffer->addr.ptr;
00102 spim_poll->op = (1 << SPI_OP_WRITE) | (1 << SPI_OP_BUFFER);
00103 spim_poll->write_data = write + 1;
00104 spim_poll->write_buffer = buffer;
00105 spim_poll->write_buf_list = buf_list;
00106 spi_polled_start(spim, *write, buffer->len);
00107 }
00108
00113 void spi_polled_read_buf_list(struct spi_master *spim, struct slist *buf_list)
00114 {
00115 struct spi_master_polled *spim_poll = spi_master_polled_of(spim);
00116 struct buffer *buffer;
00117
00118 buffer = buf_list_peek_head(buf_list);
00119 spim_poll->op = (1 << SPI_OP_READ) | (1 << SPI_OP_BUFFER);
00120 spim_poll->read_data = buffer->addr.ptr;
00121 spim_poll->read_buffer = buffer;
00122 spim_poll->read_buf_list = buf_list;
00123 spi_polled_start(spim, 0, buffer->len);
00124 }
00125
00130 void spi_polled_exchange_buf_list(struct spi_master *spim,
00131 struct slist *write_buf_list,
00132 struct slist *read_buf_list)
00133 {
00134 struct spi_master_polled *spim_poll = spi_master_polled_of(spim);
00135 struct buffer *write_buffer;
00136 struct buffer *read_buffer;
00137 const uint8_t *write;
00138
00139 assert(!slist_is_empty(write_buf_list));
00140 assert(!slist_is_empty(read_buf_list));
00141
00142 write_buffer = buf_list_peek_head(write_buf_list);
00143 read_buffer = buf_list_peek_head(read_buf_list);
00144
00145 assert(write_buffer->len == read_buffer->len);
00146
00147 write = write_buffer->addr.ptr;
00148 spim_poll->op = (1 << SPI_OP_WRITE) | (1 << SPI_OP_READ) |
00149 (1 << SPI_OP_BUFFER);
00150 spim_poll->write_data = write + 1;
00151 spim_poll->read_data = read_buffer->addr.ptr;
00152 spim_poll->write_buffer = write_buffer;
00153 spim_poll->write_buf_list = write_buf_list;
00154 spim_poll->read_buffer = write_buffer;
00155 spim_poll->read_buf_list = write_buf_list;
00156 spi_polled_start(spim, *write, write_buffer->len);
00157 }
00158