Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
arnoz
Date:
Fri Oct 01 08:19:46 2021 +0000
Revision:
116:7a67265d7c19
Parent:
77:0b96f6867312
- Correct information regarding your last merge

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 77:0b96f6867312 1 // Circular buffer for incoming reports. We write reports in the IRQ
mjr 77:0b96f6867312 2 // handler, and we read reports in the main loop in normal application
mjr 77:0b96f6867312 3 // (non-IRQ) context.
mjr 77:0b96f6867312 4 //
mjr 77:0b96f6867312 5 // The design is organically safe for IRQ threading; there are no critical
mjr 77:0b96f6867312 6 // sections. The IRQ context has exclusive access to the write pointer,
mjr 77:0b96f6867312 7 // and the application context has exclusive access to the read pointer,
mjr 77:0b96f6867312 8 // so there are no test-and-set or read-and-modify race conditions.
mjr 77:0b96f6867312 9
mjr 77:0b96f6867312 10 #ifndef _CIRCBUF_H_
mjr 77:0b96f6867312 11 #define _CIRCBUF_H_
mjr 77:0b96f6867312 12
mjr 77:0b96f6867312 13 // Circular buffer with a fixed buffer size
mjr 77:0b96f6867312 14 template<class T, int cnt> class CircBuf
mjr 77:0b96f6867312 15 {
mjr 77:0b96f6867312 16 public:
mjr 77:0b96f6867312 17 CircBuf()
mjr 77:0b96f6867312 18 {
mjr 77:0b96f6867312 19 iRead = iWrite = 0;
mjr 77:0b96f6867312 20 }
mjr 77:0b96f6867312 21
mjr 77:0b96f6867312 22 // Read an item from the buffer. Returns true if an item was available,
mjr 77:0b96f6867312 23 // false if the buffer was empty. (Called in the main loop, in application
mjr 77:0b96f6867312 24 // context.)
mjr 77:0b96f6867312 25 bool read(T &result)
mjr 77:0b96f6867312 26 {
mjr 77:0b96f6867312 27 if (iRead != iWrite)
mjr 77:0b96f6867312 28 {
mjr 77:0b96f6867312 29 //{uint8_t *d = buf[iRead].data; printf("circ read [%02x %02x %02x %02x %02x %02x %02x %02x]\r\n", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]);}
mjr 77:0b96f6867312 30 memcpy(&result, &buf[iRead], sizeof(T));
mjr 77:0b96f6867312 31 iRead = advance(iRead);
mjr 77:0b96f6867312 32 return true;
mjr 77:0b96f6867312 33 }
mjr 77:0b96f6867312 34 else
mjr 77:0b96f6867312 35 return false;
mjr 77:0b96f6867312 36 }
mjr 77:0b96f6867312 37
mjr 77:0b96f6867312 38 // is an item ready to read?
mjr 77:0b96f6867312 39 bool readReady() const { return iRead != iWrite; }
mjr 77:0b96f6867312 40
mjr 77:0b96f6867312 41 // Write an item to the buffer. (Called in the IRQ handler, in interrupt
mjr 77:0b96f6867312 42 // context.)
mjr 77:0b96f6867312 43 bool write(const T &item)
mjr 77:0b96f6867312 44 {
mjr 77:0b96f6867312 45 int nxt = advance(iWrite);
mjr 77:0b96f6867312 46 if (nxt != iRead)
mjr 77:0b96f6867312 47 {
mjr 77:0b96f6867312 48 memcpy(&buf[iWrite], &item, sizeof(T));
mjr 77:0b96f6867312 49 iWrite = nxt;
mjr 77:0b96f6867312 50 return true;
mjr 77:0b96f6867312 51 }
mjr 77:0b96f6867312 52 else
mjr 77:0b96f6867312 53 return false;
mjr 77:0b96f6867312 54 }
mjr 77:0b96f6867312 55
mjr 77:0b96f6867312 56 private:
mjr 77:0b96f6867312 57 int advance(int i)
mjr 77:0b96f6867312 58 {
mjr 77:0b96f6867312 59 ++i;
mjr 77:0b96f6867312 60 return i < cnt ? i : 0;
mjr 77:0b96f6867312 61 }
mjr 77:0b96f6867312 62
mjr 77:0b96f6867312 63 int iRead;
mjr 77:0b96f6867312 64 int iWrite;
mjr 77:0b96f6867312 65 T buf[cnt];
mjr 77:0b96f6867312 66 };
mjr 77:0b96f6867312 67
mjr 77:0b96f6867312 68 // Circular buffer with a variable buffer size
mjr 77:0b96f6867312 69 template<class T> class CircBufV
mjr 77:0b96f6867312 70 {
mjr 77:0b96f6867312 71 public:
mjr 77:0b96f6867312 72 CircBufV(int cnt)
mjr 77:0b96f6867312 73 {
mjr 77:0b96f6867312 74 buf = new T[cnt];
mjr 77:0b96f6867312 75 this->cnt = cnt;
mjr 77:0b96f6867312 76 iRead = iWrite = 0;
mjr 77:0b96f6867312 77 }
mjr 77:0b96f6867312 78
mjr 77:0b96f6867312 79 ~CircBufV()
mjr 77:0b96f6867312 80 {
mjr 77:0b96f6867312 81 delete[] buf;
mjr 77:0b96f6867312 82 }
mjr 77:0b96f6867312 83
mjr 77:0b96f6867312 84 // Read an item from the buffer. Returns true if an item was available,
mjr 77:0b96f6867312 85 // false if the buffer was empty. (Called in the main loop, in application
mjr 77:0b96f6867312 86 // context.)
mjr 77:0b96f6867312 87 bool read(T &result)
mjr 77:0b96f6867312 88 {
mjr 77:0b96f6867312 89 if (iRead != iWrite)
mjr 77:0b96f6867312 90 {
mjr 77:0b96f6867312 91 //{uint8_t *d = buf[iRead].data; printf("circ read [%02x %02x %02x %02x %02x %02x %02x %02x]\r\n", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]);}
mjr 77:0b96f6867312 92 memcpy(&result, &buf[iRead], sizeof(T));
mjr 77:0b96f6867312 93 iRead = advance(iRead);
mjr 77:0b96f6867312 94 return true;
mjr 77:0b96f6867312 95 }
mjr 77:0b96f6867312 96 else
mjr 77:0b96f6867312 97 return false;
mjr 77:0b96f6867312 98 }
mjr 77:0b96f6867312 99
mjr 77:0b96f6867312 100 // is an item ready to read?
mjr 77:0b96f6867312 101 bool readReady() const { return iRead != iWrite; }
mjr 77:0b96f6867312 102
mjr 77:0b96f6867312 103 // Write an item to the buffer. (Called in the IRQ handler, in interrupt
mjr 77:0b96f6867312 104 // context.)
mjr 77:0b96f6867312 105 bool write(const T &item)
mjr 77:0b96f6867312 106 {
mjr 77:0b96f6867312 107 int nxt = advance(iWrite);
mjr 77:0b96f6867312 108 if (nxt != iRead)
mjr 77:0b96f6867312 109 {
mjr 77:0b96f6867312 110 memcpy(&buf[iWrite], &item, sizeof(T));
mjr 77:0b96f6867312 111 iWrite = nxt;
mjr 77:0b96f6867312 112 return true;
mjr 77:0b96f6867312 113 }
mjr 77:0b96f6867312 114 else
mjr 77:0b96f6867312 115 return false;
mjr 77:0b96f6867312 116 }
mjr 77:0b96f6867312 117
mjr 77:0b96f6867312 118 private:
mjr 77:0b96f6867312 119 int advance(int i)
mjr 77:0b96f6867312 120 {
mjr 77:0b96f6867312 121 ++i;
mjr 77:0b96f6867312 122 return i < cnt ? i : 0;
mjr 77:0b96f6867312 123 }
mjr 77:0b96f6867312 124
mjr 77:0b96f6867312 125 int iRead;
mjr 77:0b96f6867312 126 int iWrite;
mjr 77:0b96f6867312 127 int cnt;
mjr 77:0b96f6867312 128 T *buf;
mjr 77:0b96f6867312 129 };
mjr 77:0b96f6867312 130
mjr 77:0b96f6867312 131 #endif