1 #include <lunaix/device.h>
2 #include <lunaix/mm/valloc.h>
3 #include <lunaix/spike.h>
4 #include <lunaix/status.h>
6 #include <sys/mm/mempart.h>
8 #include <hal/serial.h>
10 static DEFINE_LLIST(serial_devs);
11 static int serial_idx = 0;
13 #define serial_device(dev) ((struct serial_dev*)(dev)->underlay)
16 serial_accept_one(struct serial_dev* sdev, u8_t val)
18 return !!fifo_putone(&sdev->rxbuf, val);
22 serial_accept_buffer(struct serial_dev* sdev, void* val, size_t len)
24 return !!fifo_write(&sdev->rxbuf, val, len);
28 serial_end_recv(struct serial_dev* sdev)
30 pwake_one(&sdev->wq_rxdone);
34 serial_end_xmit(struct serial_dev* sdev, size_t len)
37 pwake_one(&sdev->wq_txdone);
41 serial_readone_nowait(struct serial_dev* sdev, u8_t* val)
43 mutex_lock(&sdev->lock);
45 int rd_len = fifo_readone(&sdev->rxbuf, val);
47 mutex_unlock(&sdev->lock);
53 serial_readone(struct serial_dev* sdev, u8_t* val)
55 mutex_lock(&sdev->lock);
57 while (!fifo_readone(&sdev->rxbuf, val)) {
58 pwait(&sdev->wq_rxdone);
61 mutex_unlock(&sdev->lock);
65 serial_readbuf(struct serial_dev* sdev, u8_t* buf, size_t len)
67 mutex_lock(&sdev->lock);
70 while (!(rdlen = fifo_read(&sdev->rxbuf, buf, len))) {
71 pwait(&sdev->wq_rxdone);
74 mutex_unlock(&sdev->lock);
80 serial_readbuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len)
82 mutex_lock(&sdev->lock);
84 int rdlen = fifo_read(&sdev->rxbuf, buf, len);
86 mutex_unlock(&sdev->lock);
92 serial_writebuf(struct serial_dev* sdev, u8_t* buf, size_t len)
94 mutex_lock(&sdev->lock);
96 if (sdev->write(sdev, buf, len) == RXTX_DONE) {
100 pwait(&sdev->wq_txdone);
103 int rdlen = sdev->wr_len;
104 mutex_unlock(&sdev->lock);
110 serial_writebuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len)
112 mutex_lock(&sdev->lock);
114 sdev->write(sdev, buf, len);
115 int rdlen = sdev->wr_len;
117 mutex_unlock(&sdev->lock);
123 __serial_read(struct device* dev, void* buf, size_t offset, size_t len)
125 return serial_readbuf(serial_device(dev), &((u8_t*)buf)[offset], len);
129 __serial_read_page(struct device* dev, void* buf, size_t offset)
131 return serial_readbuf(serial_device(dev), &((u8_t*)buf)[offset], MEM_PAGE);
135 __serial_write(struct device* dev, void* buf, size_t offset, size_t len)
137 return serial_writebuf(serial_device(dev), &((u8_t*)buf)[offset], len);
141 __serial_write_page(struct device* dev, void* buf, size_t offset)
143 return serial_writebuf(serial_device(dev), &((u8_t*)buf)[offset], MEM_PAGE);
147 __serial_exec_command(struct device* dev, u32_t req, va_list args)
149 struct serial_dev* sdev = serial_device(dev);
151 if (!sdev->exec_cmd) {
155 return sdev->exec_cmd(sdev, req, args);
158 #define RXBUF_SIZE 512
161 serial_create(struct devclass* class)
163 struct serial_dev* sdev = valloc(sizeof(struct serial_dev));
165 device_addseq(NULL, class, sdev, "ttyS%d", serial_idx++);
166 dev->ops.read = __serial_read;
167 dev->ops.read_page = __serial_read_page;
168 dev->ops.write = __serial_write;
169 dev->ops.write_page = __serial_write_page;
170 dev->ops.exec_cmd = __serial_exec_command;
173 dev->underlay = sdev;
175 waitq_init(&sdev->wq_rxdone);
176 waitq_init(&sdev->wq_txdone);
177 fifo_init(&sdev->rxbuf, valloc(RXBUF_SIZE), RXBUF_SIZE, 0);
178 llist_append(&serial_devs, &sdev->sdev_list);
179 // llist_init_head(&sdev->cmds);
185 serial_get_avilable()
187 struct serial_dev *pos, *n;
188 llist_for_each(pos, n, &serial_devs, sdev_list)
190 if (!mutex_on_hold(&pos->lock)) {