The iPod controller that I submitted for the mbed challenge
Dependencies: mbed Motordriver PID
user_interface/async_i2c.h@0:371773dd3dd1, 2011-05-04 (annotated)
- Committer:
- networker
- Date:
- Wed May 04 15:41:13 2011 +0000
- Revision:
- 0:371773dd3dd1
first publication
Who changed what in which revision?
User | Revision | Line number | New 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 |