Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Committer:
Bigcheese
Date:
Sun Mar 02 06:33:08 2014 +0000
Revision:
3:f151d08d335c
Parent:
2:1df0b61d3b5a
Bunch of stuff. Need to locally merge in updated USB changes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Michael J. Spencer 2:1df0b61d3b5a 1 #include "HeapRing.h"
Michael J. Spencer 2:1df0b61d3b5a 2
Michael J. Spencer 2:1df0b61d3b5a 3 #include <cstdlib>
Michael J. Spencer 2:1df0b61d3b5a 4
Michael J. Spencer 2:1df0b61d3b5a 5 #include "cmsis.h"
Michael J. Spencer 2:1df0b61d3b5a 6
Michael J. Spencer 2:1df0b61d3b5a 7 /*
Michael J. Spencer 2:1df0b61d3b5a 8 * constructors
Michael J. Spencer 2:1df0b61d3b5a 9 */
Michael J. Spencer 2:1df0b61d3b5a 10
Michael J. Spencer 2:1df0b61d3b5a 11 template<class kind> HeapRing<kind>::HeapRing()
Michael J. Spencer 2:1df0b61d3b5a 12 {
Michael J. Spencer 2:1df0b61d3b5a 13 head_i = tail_i = length = 0;
Michael J. Spencer 2:1df0b61d3b5a 14 ring = NULL;
Michael J. Spencer 2:1df0b61d3b5a 15 }
Michael J. Spencer 2:1df0b61d3b5a 16
Michael J. Spencer 2:1df0b61d3b5a 17 template<class kind> HeapRing<kind>::HeapRing(unsigned int length)
Michael J. Spencer 2:1df0b61d3b5a 18 {
Michael J. Spencer 2:1df0b61d3b5a 19 head_i = tail_i = 0;
Michael J. Spencer 2:1df0b61d3b5a 20 ring = new kind[length];
Michael J. Spencer 2:1df0b61d3b5a 21 // TODO: handle allocation failure
Michael J. Spencer 2:1df0b61d3b5a 22 this->length = length;
Michael J. Spencer 2:1df0b61d3b5a 23 }
Michael J. Spencer 2:1df0b61d3b5a 24
Michael J. Spencer 2:1df0b61d3b5a 25 /*
Michael J. Spencer 2:1df0b61d3b5a 26 * destructor
Michael J. Spencer 2:1df0b61d3b5a 27 */
Michael J. Spencer 2:1df0b61d3b5a 28
Michael J. Spencer 2:1df0b61d3b5a 29 template<class kind> HeapRing<kind>::~HeapRing()
Michael J. Spencer 2:1df0b61d3b5a 30 {
Michael J. Spencer 2:1df0b61d3b5a 31 head_i = tail_i = length = 0;
Michael J. Spencer 2:1df0b61d3b5a 32 if (ring)
Michael J. Spencer 2:1df0b61d3b5a 33 delete [] ring;
Michael J. Spencer 2:1df0b61d3b5a 34 ring = NULL;
Michael J. Spencer 2:1df0b61d3b5a 35 }
Michael J. Spencer 2:1df0b61d3b5a 36
Michael J. Spencer 2:1df0b61d3b5a 37 /*
Michael J. Spencer 2:1df0b61d3b5a 38 * index accessors (protected)
Michael J. Spencer 2:1df0b61d3b5a 39 */
Michael J. Spencer 2:1df0b61d3b5a 40
Michael J. Spencer 2:1df0b61d3b5a 41 template<class kind> unsigned int HeapRing<kind>::next(unsigned int item)
Michael J. Spencer 2:1df0b61d3b5a 42 {
Michael J. Spencer 2:1df0b61d3b5a 43 if (length == 0)
Michael J. Spencer 2:1df0b61d3b5a 44 return 0;
Michael J. Spencer 2:1df0b61d3b5a 45
Michael J. Spencer 2:1df0b61d3b5a 46 if (++item >= length)
Michael J. Spencer 2:1df0b61d3b5a 47 return 0;
Michael J. Spencer 2:1df0b61d3b5a 48
Michael J. Spencer 2:1df0b61d3b5a 49 return item;
Michael J. Spencer 2:1df0b61d3b5a 50 }
Michael J. Spencer 2:1df0b61d3b5a 51
Michael J. Spencer 2:1df0b61d3b5a 52 template<class kind> unsigned int HeapRing<kind>::prev(unsigned int item)
Michael J. Spencer 2:1df0b61d3b5a 53 {
Michael J. Spencer 2:1df0b61d3b5a 54 if (length == 0)
Michael J. Spencer 2:1df0b61d3b5a 55 return 0;
Michael J. Spencer 2:1df0b61d3b5a 56
Michael J. Spencer 2:1df0b61d3b5a 57 if (item == 0)
Michael J. Spencer 2:1df0b61d3b5a 58 return (length - 1);
Michael J. Spencer 2:1df0b61d3b5a 59 else
Michael J. Spencer 2:1df0b61d3b5a 60 return (item - 1);
Michael J. Spencer 2:1df0b61d3b5a 61 }
Michael J. Spencer 2:1df0b61d3b5a 62
Michael J. Spencer 2:1df0b61d3b5a 63 /*
Michael J. Spencer 2:1df0b61d3b5a 64 * reference accessors
Michael J. Spencer 2:1df0b61d3b5a 65 */
Michael J. Spencer 2:1df0b61d3b5a 66
Michael J. Spencer 2:1df0b61d3b5a 67 template<class kind> kind& HeapRing<kind>::head()
Michael J. Spencer 2:1df0b61d3b5a 68 {
Michael J. Spencer 2:1df0b61d3b5a 69 return ring[head_i];
Michael J. Spencer 2:1df0b61d3b5a 70 }
Michael J. Spencer 2:1df0b61d3b5a 71
Michael J. Spencer 2:1df0b61d3b5a 72 template<class kind> kind& HeapRing<kind>::tail()
Michael J. Spencer 2:1df0b61d3b5a 73 {
Michael J. Spencer 2:1df0b61d3b5a 74 return ring[tail_i];
Michael J. Spencer 2:1df0b61d3b5a 75 }
Michael J. Spencer 2:1df0b61d3b5a 76
Michael J. Spencer 2:1df0b61d3b5a 77 template<class kind> kind& HeapRing<kind>::item(unsigned int i)
Michael J. Spencer 2:1df0b61d3b5a 78 {
Michael J. Spencer 2:1df0b61d3b5a 79 return ring[i];
Michael J. Spencer 2:1df0b61d3b5a 80 }
Michael J. Spencer 2:1df0b61d3b5a 81
Michael J. Spencer 2:1df0b61d3b5a 82 template<class kind> void HeapRing<kind>::push_front(kind& item)
Michael J. Spencer 2:1df0b61d3b5a 83 {
Michael J. Spencer 2:1df0b61d3b5a 84 ring[head_i] = item;
Michael J. Spencer 2:1df0b61d3b5a 85 head_i = next(head_i);
Michael J. Spencer 2:1df0b61d3b5a 86 }
Michael J. Spencer 2:1df0b61d3b5a 87
Michael J. Spencer 2:1df0b61d3b5a 88 template<class kind> kind& HeapRing<kind>::pop_back()
Michael J. Spencer 2:1df0b61d3b5a 89 {
Michael J. Spencer 2:1df0b61d3b5a 90 kind& r = ring[tail_i];
Michael J. Spencer 2:1df0b61d3b5a 91 tail_i = next(tail_i);
Michael J. Spencer 2:1df0b61d3b5a 92 return r;
Michael J. Spencer 2:1df0b61d3b5a 93 }
Michael J. Spencer 2:1df0b61d3b5a 94
Michael J. Spencer 2:1df0b61d3b5a 95 /*
Michael J. Spencer 2:1df0b61d3b5a 96 * pointer accessors
Michael J. Spencer 2:1df0b61d3b5a 97 */
Michael J. Spencer 2:1df0b61d3b5a 98
Michael J. Spencer 2:1df0b61d3b5a 99 template<class kind> kind* HeapRing<kind>::head_ref()
Michael J. Spencer 2:1df0b61d3b5a 100 {
Michael J. Spencer 2:1df0b61d3b5a 101 return &ring[head_i];
Michael J. Spencer 2:1df0b61d3b5a 102 }
Michael J. Spencer 2:1df0b61d3b5a 103
Michael J. Spencer 2:1df0b61d3b5a 104 template<class kind> kind* HeapRing<kind>::tail_ref()
Michael J. Spencer 2:1df0b61d3b5a 105 {
Michael J. Spencer 2:1df0b61d3b5a 106 return &ring[tail_i];
Michael J. Spencer 2:1df0b61d3b5a 107 }
Michael J. Spencer 2:1df0b61d3b5a 108
Michael J. Spencer 2:1df0b61d3b5a 109 template<class kind> kind* HeapRing<kind>::item_ref(unsigned int i)
Michael J. Spencer 2:1df0b61d3b5a 110 {
Michael J. Spencer 2:1df0b61d3b5a 111 return &ring[i];
Michael J. Spencer 2:1df0b61d3b5a 112 }
Michael J. Spencer 2:1df0b61d3b5a 113
Michael J. Spencer 2:1df0b61d3b5a 114 template<class kind> void HeapRing<kind>::produce_head()
Michael J. Spencer 2:1df0b61d3b5a 115 {
Michael J. Spencer 2:1df0b61d3b5a 116 while (is_full());
Michael J. Spencer 2:1df0b61d3b5a 117 head_i = next(head_i);
Michael J. Spencer 2:1df0b61d3b5a 118 }
Michael J. Spencer 2:1df0b61d3b5a 119
Michael J. Spencer 2:1df0b61d3b5a 120 template<class kind> void HeapRing<kind>::consume_tail()
Michael J. Spencer 2:1df0b61d3b5a 121 {
Michael J. Spencer 2:1df0b61d3b5a 122 if (!is_empty())
Michael J. Spencer 2:1df0b61d3b5a 123 tail_i = next(tail_i);
Michael J. Spencer 2:1df0b61d3b5a 124 }
Michael J. Spencer 2:1df0b61d3b5a 125
Michael J. Spencer 2:1df0b61d3b5a 126 /*
Michael J. Spencer 2:1df0b61d3b5a 127 * queue status accessors
Michael J. Spencer 2:1df0b61d3b5a 128 */
Michael J. Spencer 2:1df0b61d3b5a 129
Michael J. Spencer 2:1df0b61d3b5a 130 template<class kind> bool HeapRing<kind>::is_full()
Michael J. Spencer 2:1df0b61d3b5a 131 {
Michael J. Spencer 2:1df0b61d3b5a 132 __disable_irq();
Michael J. Spencer 2:1df0b61d3b5a 133 bool r = (next(head_i) == tail_i);
Michael J. Spencer 2:1df0b61d3b5a 134 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 135
Michael J. Spencer 2:1df0b61d3b5a 136 return r;
Michael J. Spencer 2:1df0b61d3b5a 137 }
Michael J. Spencer 2:1df0b61d3b5a 138
Michael J. Spencer 2:1df0b61d3b5a 139 template<class kind> bool HeapRing<kind>::is_empty()
Michael J. Spencer 2:1df0b61d3b5a 140 {
Michael J. Spencer 2:1df0b61d3b5a 141 __disable_irq();
Michael J. Spencer 2:1df0b61d3b5a 142 bool r = (head_i == tail_i);
Michael J. Spencer 2:1df0b61d3b5a 143 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 144
Michael J. Spencer 2:1df0b61d3b5a 145 return r;
Michael J. Spencer 2:1df0b61d3b5a 146 }
Michael J. Spencer 2:1df0b61d3b5a 147
Michael J. Spencer 2:1df0b61d3b5a 148 /*
Michael J. Spencer 2:1df0b61d3b5a 149 * resize
Michael J. Spencer 2:1df0b61d3b5a 150 */
Michael J. Spencer 2:1df0b61d3b5a 151
Michael J. Spencer 2:1df0b61d3b5a 152 template<class kind> bool HeapRing<kind>::resize(unsigned int length)
Michael J. Spencer 2:1df0b61d3b5a 153 {
Michael J. Spencer 2:1df0b61d3b5a 154 if (is_empty())
Michael J. Spencer 2:1df0b61d3b5a 155 {
Michael J. Spencer 2:1df0b61d3b5a 156 if (length == 0)
Michael J. Spencer 2:1df0b61d3b5a 157 {
Michael J. Spencer 2:1df0b61d3b5a 158 __disable_irq();
Michael J. Spencer 2:1df0b61d3b5a 159
Michael J. Spencer 2:1df0b61d3b5a 160 if (is_empty()) // check again in case something was pushed
Michael J. Spencer 2:1df0b61d3b5a 161 {
Michael J. Spencer 2:1df0b61d3b5a 162 head_i = tail_i = this->length = 0;
Michael J. Spencer 2:1df0b61d3b5a 163
Michael J. Spencer 2:1df0b61d3b5a 164 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 165
Michael J. Spencer 2:1df0b61d3b5a 166 if (ring)
Michael J. Spencer 2:1df0b61d3b5a 167 delete [] ring;
Michael J. Spencer 2:1df0b61d3b5a 168 ring = NULL;
Michael J. Spencer 2:1df0b61d3b5a 169
Michael J. Spencer 2:1df0b61d3b5a 170 return true;
Michael J. Spencer 2:1df0b61d3b5a 171 }
Michael J. Spencer 2:1df0b61d3b5a 172
Michael J. Spencer 2:1df0b61d3b5a 173 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 174
Michael J. Spencer 2:1df0b61d3b5a 175 return false;
Michael J. Spencer 2:1df0b61d3b5a 176 }
Michael J. Spencer 2:1df0b61d3b5a 177
Michael J. Spencer 2:1df0b61d3b5a 178 // Note: we don't use realloc so we can fall back to the existing ring if allocation fails
Michael J. Spencer 2:1df0b61d3b5a 179 kind* newring = new kind[length];
Michael J. Spencer 2:1df0b61d3b5a 180
Michael J. Spencer 2:1df0b61d3b5a 181 if (newring != NULL)
Michael J. Spencer 2:1df0b61d3b5a 182 {
Michael J. Spencer 2:1df0b61d3b5a 183 kind* oldring = ring;
Michael J. Spencer 2:1df0b61d3b5a 184
Michael J. Spencer 2:1df0b61d3b5a 185 __disable_irq();
Michael J. Spencer 2:1df0b61d3b5a 186
Michael J. Spencer 2:1df0b61d3b5a 187 if (is_empty()) // check again in case something was pushed while malloc did its thing
Michael J. Spencer 2:1df0b61d3b5a 188 {
Michael J. Spencer 2:1df0b61d3b5a 189 ring = newring;
Michael J. Spencer 2:1df0b61d3b5a 190 this->length = length;
Michael J. Spencer 2:1df0b61d3b5a 191 head_i = tail_i = 0;
Michael J. Spencer 2:1df0b61d3b5a 192
Michael J. Spencer 2:1df0b61d3b5a 193 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 194
Michael J. Spencer 2:1df0b61d3b5a 195 if (oldring)
Michael J. Spencer 2:1df0b61d3b5a 196 delete [] oldring;
Michael J. Spencer 2:1df0b61d3b5a 197
Michael J. Spencer 2:1df0b61d3b5a 198 return true;
Michael J. Spencer 2:1df0b61d3b5a 199 }
Michael J. Spencer 2:1df0b61d3b5a 200
Michael J. Spencer 2:1df0b61d3b5a 201 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 202
Michael J. Spencer 2:1df0b61d3b5a 203 delete [] newring;
Michael J. Spencer 2:1df0b61d3b5a 204 }
Michael J. Spencer 2:1df0b61d3b5a 205 }
Michael J. Spencer 2:1df0b61d3b5a 206
Michael J. Spencer 2:1df0b61d3b5a 207 return false;
Michael J. Spencer 2:1df0b61d3b5a 208 }
Michael J. Spencer 2:1df0b61d3b5a 209
Michael J. Spencer 2:1df0b61d3b5a 210 template<class kind> bool HeapRing<kind>::provide(kind* buffer, unsigned int length)
Michael J. Spencer 2:1df0b61d3b5a 211 {
Michael J. Spencer 2:1df0b61d3b5a 212 __disable_irq();
Michael J. Spencer 2:1df0b61d3b5a 213
Michael J. Spencer 2:1df0b61d3b5a 214 if (is_empty())
Michael J. Spencer 2:1df0b61d3b5a 215 {
Michael J. Spencer 2:1df0b61d3b5a 216 kind* oldring = ring;
Michael J. Spencer 2:1df0b61d3b5a 217
Michael J. Spencer 2:1df0b61d3b5a 218 if ((buffer != NULL) && (length > 0))
Michael J. Spencer 2:1df0b61d3b5a 219 {
Michael J. Spencer 2:1df0b61d3b5a 220 ring = buffer;
Michael J. Spencer 2:1df0b61d3b5a 221 this->length = length;
Michael J. Spencer 2:1df0b61d3b5a 222 head_i = tail_i = 0;
Michael J. Spencer 2:1df0b61d3b5a 223
Michael J. Spencer 2:1df0b61d3b5a 224 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 225
Michael J. Spencer 2:1df0b61d3b5a 226 if (oldring)
Michael J. Spencer 2:1df0b61d3b5a 227 delete [] oldring;
Michael J. Spencer 2:1df0b61d3b5a 228 return true;
Michael J. Spencer 2:1df0b61d3b5a 229 }
Michael J. Spencer 2:1df0b61d3b5a 230 }
Michael J. Spencer 2:1df0b61d3b5a 231
Michael J. Spencer 2:1df0b61d3b5a 232 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 233
Michael J. Spencer 2:1df0b61d3b5a 234 return false;
Michael J. Spencer 2:1df0b61d3b5a 235 }