The iPod controller that I submitted for the mbed challenge
Dependencies: mbed Motordriver PID
user_interface/async_i2c.h
- Committer:
- networker
- Date:
- 2011-05-04
- Revision:
- 0:371773dd3dd1
File content as of revision 0:371773dd3dd1:
#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