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>
11 #define lock_sdev(sdev) device_lock((sdev)->dev)
12 #define unlock_sdev(sdev) device_unlock((sdev)->dev)
13 #define unlock_and_wait(sdev, wq) \
20 static DEFINE_LLIST(serial_devs);
21 static int serial_idx = 0;
23 #define serial_device(dev) ((struct serial_dev*)(dev)->underlay)
26 serial_accept_one(struct serial_dev* sdev, u8_t val)
28 return !!rbuffer_put(&sdev->rxbuf, val);
32 serial_accept_buffer(struct serial_dev* sdev, void* val, size_t len)
34 return !!rbuffer_puts(&sdev->rxbuf, val, len);
38 serial_end_recv(struct serial_dev* sdev)
40 mark_device_done_read(sdev->dev);
42 pwake_one(&sdev->wq_rxdone);
46 serial_end_xmit(struct serial_dev* sdev, size_t len)
48 mark_device_done_write(sdev->dev);
51 pwake_one(&sdev->wq_txdone);
55 serial_readone_nowait(struct serial_dev* sdev, u8_t* val)
59 int rd_len = rbuffer_get(&sdev->rxbuf, (char*)val);
67 serial_readone(struct serial_dev* sdev, u8_t* val)
71 mark_device_doing_read(sdev->dev);
73 while (!rbuffer_get(&sdev->rxbuf, (char*)val)) {
74 unlock_and_wait(sdev, wq_rxdone);
81 serial_readbuf(struct serial_dev* sdev, u8_t* buf, size_t len)
85 mark_device_doing_read(sdev->dev);
88 while (!(rdlen = rbuffer_gets(&sdev->rxbuf, (char*)buf, len))) {
89 unlock_and_wait(sdev, wq_rxdone);
98 serial_readbuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len)
102 mark_device_doing_read(sdev->dev);
104 int rdlen = rbuffer_gets(&sdev->rxbuf, (char*)buf, len);
112 serial_writebuf(struct serial_dev* sdev, u8_t* buf, size_t len)
116 mark_device_doing_write(sdev->dev);
118 if (sdev->write(sdev, buf, len) == RXTX_DONE) {
122 unlock_and_wait(sdev, wq_txdone);
125 int rdlen = sdev->wr_len;
132 serial_writebuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len)
136 mark_device_doing_write(sdev->dev);
138 sdev->write(sdev, buf, len);
139 int rdlen = sdev->wr_len;
147 __serial_read(struct device* dev, void* buf, off_t fpos, size_t len)
149 return serial_readbuf(serial_device(dev), (u8_t*)buf, len);
153 __serial_read_async(struct device* dev, void* buf, off_t fpos, size_t len)
155 return serial_readbuf_nowait(
156 serial_device(dev), (u8_t*)buf, len);
160 __serial_read_page(struct device* dev, void* buf, off_t fpos)
162 return serial_readbuf(serial_device(dev), (u8_t*)buf, MEM_PAGE);
166 __serial_write(struct device* dev, void* buf, off_t fpos, size_t len)
168 return serial_writebuf(serial_device(dev), (u8_t*)buf, len);
172 __serial_write_async(struct device* dev, void* buf, off_t fpos, size_t len)
174 return serial_writebuf_nowait(
175 serial_device(dev), (u8_t*)buf, len);
179 __serial_write_page(struct device* dev, void* buf, off_t fpos)
181 return serial_writebuf(serial_device(dev), (u8_t*)buf, MEM_PAGE);
185 __serial_exec_command(struct device* dev, u32_t req, va_list args)
187 struct serial_dev* sdev = serial_device(dev);
189 if (!sdev->exec_cmd) {
193 return sdev->exec_cmd(sdev, req, args);
197 __serial_poll_event(struct device* dev)
199 struct serial_dev* sdev = serial_device(dev);
201 return sdev->dev->poll_evflags;
204 static void sdev_execmd(struct serial_dev* sdev, u32_t req, ...)
209 sdev->exec_cmd(sdev, req, args);
215 __serial_set_speed(struct device* dev, speed_t speed)
217 struct serial_dev* sdev = serial_device(dev);
220 sdev_execmd(sdev, SERIO_SETBRDIV, speed);
226 __serial_set_cntrl_mode(struct device* dev, tcflag_t cflag)
228 struct serial_dev* sdev = serial_device(dev);
231 sdev_execmd(sdev, SERIO_SETCNTRLMODE, cflag);
236 #define RXBUF_SIZE 512
239 serial_create(struct devclass* class, char* if_ident)
241 struct serial_dev* sdev = valloc(sizeof(struct serial_dev));
242 struct device* dev = device_allocseq(NULL, sdev);
243 dev->ops.read = __serial_read;
244 dev->ops.read_page = __serial_read_page;
245 dev->ops.read_async = __serial_read_async;
246 dev->ops.write_async = __serial_write_async;
247 dev->ops.write = __serial_write;
248 dev->ops.write_page = __serial_write_page;
249 dev->ops.exec_cmd = __serial_exec_command;
250 dev->ops.poll = __serial_poll_event;
253 dev->underlay = sdev;
255 struct termport_capability* tp_cap =
256 new_capability(TERMPORT_CAP, struct termport_capability);
257 tp_cap->set_speed = __serial_set_speed;
258 tp_cap->set_cntrl_mode = __serial_set_cntrl_mode;
260 waitq_init(&sdev->wq_rxdone);
261 waitq_init(&sdev->wq_txdone);
262 rbuffer_init(&sdev->rxbuf, valloc(RXBUF_SIZE), RXBUF_SIZE);
263 llist_append(&serial_devs, &sdev->sdev_list);
265 device_grant_capability(dev, cap_meta(tp_cap));
267 register_device(dev, class, "serial%d", class->variant);
269 term_create(dev, if_ident);
276 serial_get_avilable()
278 struct serial_dev *pos, *n;
279 llist_for_each(pos, n, &serial_devs, sdev_list)
281 if (!device_locked(pos->dev)) {