The iPod controller that I submitted for the mbed challenge

Dependencies:   mbed Motordriver PID

Revision:
0:371773dd3dd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/user_interface/async_i2c.h	Wed May 04 15:41:13 2011 +0000
@@ -0,0 +1,101 @@
+#ifndef ASYNC_I2C_H
+#define ASYNC_I2C_H
+
+enum i2c_status { i2c_ok, i2c_busy, i2c_nack, i2c_pending};
+class async_i2c;
+
+class i2c_buffer {
+    async_i2c* _intf;
+    char _adr;
+    char *_data;
+    int _size;
+    i2c_buffer *_next;
+    bool _copy;
+    bool (*notification)(i2c_buffer*);
+    i2c_status stat;
+public:
+    i2c_buffer(async_i2c* intf, char adr, char* data, int size, bool copy=false, i2c_buffer *next=0): _intf(intf), _adr(adr), _data(data), _size(size), _copy(copy), _next(next) {
+        if (copy) {
+            _data = new char[size];
+            memcpy(_data, data, size);
+        }
+        stat = i2c_pending;
+        notification = 0;
+    }
+    ~i2c_buffer() {
+        if (_copy) delete[] _data;
+        _data = 0;
+        if (_next) delete _next;
+    }
+    void set_notification(bool (*fun)(i2c_buffer*)) {
+        if (stat==i2c_pending) notification = fun;
+        else fun(this);
+    }
+    //notify is the callback when the transfer has finished
+    bool notify() {
+        bool result = true;
+        i2c_buffer *buf = _next;
+        if (notification)
+            result = notification(this);
+        if (_intf && _next){
+            _intf->process(_next);
+            }
+        else
+            _intf->releasybusy();
+        return result;
+    }
+    friend async_i2c;
+};
+
+class async_i2c: public I2C { //for now based on the sync i2c and hence not async, in the future should be bare metal and completely async
+public:
+    typedef void trans_end(i2c_status stat, char *data, bool stop);
+private:
+    bool busy, _stop;
+    trans_end *_we, *_re;
+    i2c_status _stat;
+    void process(i2c_buffer*);
+public:
+    async_i2c(PinName sda, PinName scl): I2C(sda, scl) {
+        busy = false;
+        _stop = true;
+        _we = 0;
+        _re = 0;
+        _stat = i2c_ok;
+    }
+    void frequency(int rate) {
+        I2C::frequency(rate);
+    }
+    i2c_status write(char address, char *data, int size, bool stop=true);
+    i2c_status read(char address, char *data, int size, bool stop=true);
+    i2c_buffer* write(char address, char *data, int size, bool copy=false, i2c_buffer *b=0);
+    i2c_buffer* read(char address, char *data, int size, bool copy=false, i2c_buffer *b=0);
+    i2c_buffer* read(char address, char reg, char *data, int size, bool copy=false);
+    void write_end(trans_end *cb) {
+        _we = cb;
+    }
+    void read_end(trans_end *cb) {
+        _re = cb;
+    }
+    bool isbusy() {
+        return busy;
+    }
+
+protected:
+    bool testbusy() {
+        __disable_irq();
+        if (busy && _stop) {
+            __enable_irq();
+            return true;
+        }
+        busy = true;
+        __enable_irq();
+        return false;
+    }
+    void releasebusy(bool stop=true) {
+        _stop = stop;
+        if (stop) busy = false;
+    }
+};
+
+#endif
\ No newline at end of file