The iPod controller that I submitted for the mbed challenge
Dependencies: mbed Motordriver PID
Diff: user_interface/async_i2c.h
- 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