|
@@ -0,0 +1,136 @@
|
|
|
|
+#include "bus.h"
|
|
|
|
+#include "timer.h"
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+void file_produce(file_t* f, char x)
|
|
|
|
+{
|
|
|
|
+ f->buffer[f->t]=x;
|
|
|
|
+ f->t=(f->t+1)%1024;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+char file_consume(file_t* f)
|
|
|
|
+{
|
|
|
|
+ char x;
|
|
|
|
+ while(f->t==f->q) micro_sleep(10);
|
|
|
|
+ x=f->buffer[f->q];
|
|
|
|
+ f->q=(f->q+1)%1024;
|
|
|
|
+ return x;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int file_size(file_t* f)
|
|
|
|
+{
|
|
|
|
+ return (f->t>=f->q)?f->t-f->q:1024-f->q+f->t;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void file_init(file_t* file)
|
|
|
|
+{
|
|
|
|
+ file->t=file->q=0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+void bus_init_recv(bus_t* bus, int d, int clk, int ack)
|
|
|
|
+{
|
|
|
|
+ bus->data=d;
|
|
|
|
+ bus->clk=clk;
|
|
|
|
+ bus->ack=ack;
|
|
|
|
+ bus->ismaster=0;
|
|
|
|
+ file_init(&bus->buffer);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+void bus_init_send(bus_t* bus, int d, int clk, int ack)
|
|
|
|
+{
|
|
|
|
+ bus->data=d;
|
|
|
|
+ bus->clk=clk;
|
|
|
|
+ bus->ack=ack;
|
|
|
|
+ bus->ismaster=1;
|
|
|
|
+ file_init(&bus->buffer);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+void _bus_write(bus_t* bus, char x)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ if(!bus->ismaster) return;
|
|
|
|
+ for(i=0; i<8; i++)
|
|
|
|
+ {
|
|
|
|
+ while(read_pin(bus->ack)) micro_sleep(10);
|
|
|
|
+ write_pin(bus->data, (x&(1<<i))?1:0);
|
|
|
|
+ write_pin(bus->clk, 1);
|
|
|
|
+ while(!read_pin(bus->ack)) micro_sleep(10);
|
|
|
|
+ write_pin(bus->clk, 0);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+char _bus_read(bus_t* bus)
|
|
|
|
+{
|
|
|
|
+ int x=0, i, j=0;
|
|
|
|
+ if(bus->ismaster) return -1;
|
|
|
|
+
|
|
|
|
+ for(i=0; i<8; i++)
|
|
|
|
+ {
|
|
|
|
+ write_pin(bus->ack, 0);
|
|
|
|
+ while(!read_pin(bus->clk)) micro_sleep(10);
|
|
|
|
+ j=read_pin(bus->data);
|
|
|
|
+ x+=j<<i;
|
|
|
|
+ write_pin(bus->ack, 1);
|
|
|
|
+ micro_sleep(50);
|
|
|
|
+ write_pin(bus->ack, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return x;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void* bus_send_thread(void* _bus)
|
|
|
|
+{
|
|
|
|
+ bus_t* bus = (bus_t*)_bus;
|
|
|
|
+ if(!bus->ismaster) return NULL;
|
|
|
|
+ while(1)
|
|
|
|
+ {
|
|
|
|
+ while(!file_size(&bus->buffer)) micro_sleep(10);
|
|
|
|
+ _bus_write(bus, file_consume(&bus->buffer));
|
|
|
|
+ }
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void* bus_recv_thread(void* _bus)
|
|
|
|
+{
|
|
|
|
+ bus_t* bus = (bus_t*)_bus;
|
|
|
|
+ if(bus->ismaster) return NULL;
|
|
|
|
+ while(1)
|
|
|
|
+ {
|
|
|
|
+ file_produce(&bus->buffer, _bus_read(bus));
|
|
|
|
+ }
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void bus_write(bus_t* bus, const void* x, int length)
|
|
|
|
+{
|
|
|
|
+ const uint8_t *iter=(const uint8_t*)x;
|
|
|
|
+ int i;
|
|
|
|
+ if(!bus->ismaster) return;
|
|
|
|
+
|
|
|
|
+ for(i=0; i<length; i++)
|
|
|
|
+ file_produce(&bus->buffer, iter[i]);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void bus_read(bus_t* bus, void* x, int length)
|
|
|
|
+{
|
|
|
|
+ uint8_t *iter=(uint8_t*)x;
|
|
|
|
+ int i;
|
|
|
|
+ if(bus->ismaster) return;
|
|
|
|
+ for(i=0; i<length; i++)
|
|
|
|
+ iter[i]=file_consume(&bus->buffer);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+void bus_write_sync(bus_t* bus, const void* x, int length)
|
|
|
|
+{
|
|
|
|
+ const uint8_t *iter=(const uint8_t*)x;
|
|
|
|
+ int i;
|
|
|
|
+ if(!bus->ismaster) return;
|
|
|
|
+
|
|
|
|
+ for(i=0; i<length; i++)
|
|
|
|
+ _bus_write(bus, iter[i]);
|
|
|
|
+
|
|
|
|
+}
|