feat: serial device interfacing
[lunaix-os.git] / lunaix-os / kernel / ds / fifo.c
index 1e72e8da4b7d401d94812596da15f8447e12a3bf..5ecddad57b00a6c70bd78dd3629b9cb4e505e957 100644 (file)
@@ -15,6 +15,16 @@ fifo_init(struct fifo_buf* buf, void* data_buffer, size_t buf_size, int flags)
     mutex_init(&buf->lock);
 }
 
+void
+fifo_clear(struct fifo_buf* fbuf)
+{
+    mutex_lock(&fbuf->lock);
+    fbuf->rd_pos = 0;
+    fbuf->wr_pos = 0;
+    fbuf->free_len = fbuf->size;
+    mutex_unlock(&fbuf->lock);
+}
+
 int
 fifo_backone(struct fifo_buf* fbuf)
 {
@@ -34,7 +44,7 @@ fifo_backone(struct fifo_buf* fbuf)
 }
 
 size_t
-fifo_putone(struct fifo_buf* fbuf, uint8_t data)
+fifo_putone(struct fifo_buf* fbuf, u8_t data)
 {
     mutex_lock(&fbuf->lock);
 
@@ -43,7 +53,7 @@ fifo_putone(struct fifo_buf* fbuf, uint8_t data)
         return 0;
     }
 
-    uint8_t* dest = fbuf->data;
+    u8_t* dest = fbuf->data;
     dest[fbuf->wr_pos] = data;
     fbuf->wr_pos = (fbuf->wr_pos + 1) % fbuf->size;
     fbuf->free_len--;
@@ -53,11 +63,62 @@ fifo_putone(struct fifo_buf* fbuf, uint8_t data)
     return 1;
 }
 
+size_t
+fifo_readone_async(struct fifo_buf* fbuf, u8_t* data)
+{
+    if (fbuf->free_len == fbuf->size) {
+        return 0;
+    }
+
+    u8_t* dest = fbuf->data;
+    *data = dest[fbuf->rd_pos];
+    fbuf->rd_pos = (fbuf->rd_pos + 1) % fbuf->size;
+    fbuf->free_len++;
+
+    return 1;
+}
+
+size_t
+fifo_readone(struct fifo_buf* fbuf, u8_t* data)
+{
+    mutex_lock(&fbuf->lock);
+    size_t retval = fifo_readone_async(fbuf, data);
+    mutex_unlock(&fbuf->lock);
+
+    return retval;
+}
+
+void
+fifo_set_rdptr(struct fifo_buf* fbuf, size_t rdptr)
+{
+    fbuf->rd_pos = rdptr;
+    if (rdptr <= fbuf->wr_pos) {
+        fbuf->free_len = fbuf->size - fbuf->wr_pos + rdptr;
+    } else {
+        fbuf->free_len = rdptr - fbuf->wr_pos;
+    }
+}
+
+void
+fifo_set_wrptr(struct fifo_buf* fbuf, size_t wrptr)
+{
+    fbuf->wr_pos = wrptr;
+    if (wrptr <= fbuf->rd_pos) {
+        fbuf->free_len = fbuf->size - fbuf->rd_pos + wrptr;
+    } else {
+        fbuf->free_len = wrptr - fbuf->rd_pos;
+    }
+}
+
 size_t
 fifo_write(struct fifo_buf* fbuf, void* data, size_t count)
 {
     size_t wr_count = 0, wr_pos = fbuf->wr_pos;
 
+    if (!count) {
+        return 0;
+    }
+
     mutex_lock(&fbuf->lock);
 
     if (!fbuf->free_len) {