The iPod controller that I submitted for the mbed challenge

Dependencies:   mbed Motordriver PID

Committer:
networker
Date:
Wed May 04 15:41:13 2011 +0000
Revision:
0:371773dd3dd1
first publication

Who changed what in which revision?

UserRevisionLine numberNew contents of line
networker 0:371773dd3dd1 1 #ifndef ASYNC_I2C_H
networker 0:371773dd3dd1 2 #define ASYNC_I2C_H
networker 0:371773dd3dd1 3
networker 0:371773dd3dd1 4 enum i2c_status { i2c_ok, i2c_busy, i2c_nack, i2c_pending};
networker 0:371773dd3dd1 5 class async_i2c;
networker 0:371773dd3dd1 6
networker 0:371773dd3dd1 7 class i2c_buffer {
networker 0:371773dd3dd1 8 async_i2c* _intf;
networker 0:371773dd3dd1 9 char _adr;
networker 0:371773dd3dd1 10 char *_data;
networker 0:371773dd3dd1 11 int _size;
networker 0:371773dd3dd1 12 i2c_buffer *_next;
networker 0:371773dd3dd1 13 bool _copy;
networker 0:371773dd3dd1 14 bool (*notification)(i2c_buffer*);
networker 0:371773dd3dd1 15 i2c_status stat;
networker 0:371773dd3dd1 16 public:
networker 0:371773dd3dd1 17 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) {
networker 0:371773dd3dd1 18 if (copy) {
networker 0:371773dd3dd1 19 _data = new char[size];
networker 0:371773dd3dd1 20 memcpy(_data, data, size);
networker 0:371773dd3dd1 21 }
networker 0:371773dd3dd1 22 stat = i2c_pending;
networker 0:371773dd3dd1 23 notification = 0;
networker 0:371773dd3dd1 24 }
networker 0:371773dd3dd1 25 ~i2c_buffer() {
networker 0:371773dd3dd1 26 if (_copy) delete[] _data;
networker 0:371773dd3dd1 27 _data = 0;
networker 0:371773dd3dd1 28 if (_next) delete _next;
networker 0:371773dd3dd1 29 }
networker 0:371773dd3dd1 30 void set_notification(bool (*fun)(i2c_buffer*)) {
networker 0:371773dd3dd1 31 if (stat==i2c_pending) notification = fun;
networker 0:371773dd3dd1 32 else fun(this);
networker 0:371773dd3dd1 33 }
networker 0:371773dd3dd1 34 //notify is the callback when the transfer has finished
networker 0:371773dd3dd1 35 bool notify() {
networker 0:371773dd3dd1 36 bool result = true;
networker 0:371773dd3dd1 37 i2c_buffer *buf = _next;
networker 0:371773dd3dd1 38 if (notification)
networker 0:371773dd3dd1 39 result = notification(this);
networker 0:371773dd3dd1 40 if (_intf && _next){
networker 0:371773dd3dd1 41 _intf->process(_next);
networker 0:371773dd3dd1 42 }
networker 0:371773dd3dd1 43 else
networker 0:371773dd3dd1 44 _intf->releasybusy();
networker 0:371773dd3dd1 45 return result;
networker 0:371773dd3dd1 46 }
networker 0:371773dd3dd1 47 friend async_i2c;
networker 0:371773dd3dd1 48 };
networker 0:371773dd3dd1 49
networker 0:371773dd3dd1 50 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
networker 0:371773dd3dd1 51 public:
networker 0:371773dd3dd1 52 typedef void trans_end(i2c_status stat, char *data, bool stop);
networker 0:371773dd3dd1 53 private:
networker 0:371773dd3dd1 54 bool busy, _stop;
networker 0:371773dd3dd1 55 trans_end *_we, *_re;
networker 0:371773dd3dd1 56 i2c_status _stat;
networker 0:371773dd3dd1 57 void process(i2c_buffer*);
networker 0:371773dd3dd1 58 public:
networker 0:371773dd3dd1 59 async_i2c(PinName sda, PinName scl): I2C(sda, scl) {
networker 0:371773dd3dd1 60 busy = false;
networker 0:371773dd3dd1 61 _stop = true;
networker 0:371773dd3dd1 62 _we = 0;
networker 0:371773dd3dd1 63 _re = 0;
networker 0:371773dd3dd1 64 _stat = i2c_ok;
networker 0:371773dd3dd1 65 }
networker 0:371773dd3dd1 66 void frequency(int rate) {
networker 0:371773dd3dd1 67 I2C::frequency(rate);
networker 0:371773dd3dd1 68 }
networker 0:371773dd3dd1 69 i2c_status write(char address, char *data, int size, bool stop=true);
networker 0:371773dd3dd1 70 i2c_status read(char address, char *data, int size, bool stop=true);
networker 0:371773dd3dd1 71 i2c_buffer* write(char address, char *data, int size, bool copy=false, i2c_buffer *b=0);
networker 0:371773dd3dd1 72 i2c_buffer* read(char address, char *data, int size, bool copy=false, i2c_buffer *b=0);
networker 0:371773dd3dd1 73 i2c_buffer* read(char address, char reg, char *data, int size, bool copy=false);
networker 0:371773dd3dd1 74 void write_end(trans_end *cb) {
networker 0:371773dd3dd1 75 _we = cb;
networker 0:371773dd3dd1 76 }
networker 0:371773dd3dd1 77 void read_end(trans_end *cb) {
networker 0:371773dd3dd1 78 _re = cb;
networker 0:371773dd3dd1 79 }
networker 0:371773dd3dd1 80 bool isbusy() {
networker 0:371773dd3dd1 81 return busy;
networker 0:371773dd3dd1 82 }
networker 0:371773dd3dd1 83
networker 0:371773dd3dd1 84 protected:
networker 0:371773dd3dd1 85 bool testbusy() {
networker 0:371773dd3dd1 86 __disable_irq();
networker 0:371773dd3dd1 87 if (busy && _stop) {
networker 0:371773dd3dd1 88 __enable_irq();
networker 0:371773dd3dd1 89 return true;
networker 0:371773dd3dd1 90 }
networker 0:371773dd3dd1 91 busy = true;
networker 0:371773dd3dd1 92 __enable_irq();
networker 0:371773dd3dd1 93 return false;
networker 0:371773dd3dd1 94 }
networker 0:371773dd3dd1 95 void releasebusy(bool stop=true) {
networker 0:371773dd3dd1 96 _stop = stop;
networker 0:371773dd3dd1 97 if (stop) busy = false;
networker 0:371773dd3dd1 98 }
networker 0:371773dd3dd1 99 };
networker 0:371773dd3dd1 100
networker 0:371773dd3dd1 101 #endif