Jean Mercier
/
jmSwitch
Read up to 8 debounced switches from serial port
jmRingBuffer.c@0:f3a5f6fe1c03, 2011-02-12 (annotated)
- Committer:
- jm
- Date:
- Sat Feb 12 16:46:49 2011 +0000
- Revision:
- 0:f3a5f6fe1c03
jmSwitch Command Line Interface Module
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jm | 0:f3a5f6fe1c03 | 1 | /************************************************************************* |
jm | 0:f3a5f6fe1c03 | 2 | * @file jmRingBuffer.c |
jm | 0:f3a5f6fe1c03 | 3 | * @brief Command Line Rx Ring Buffer |
jm | 0:f3a5f6fe1c03 | 4 | * |
jm | 0:f3a5f6fe1c03 | 5 | * @date Feb 12, 2011 |
jm | 0:f3a5f6fe1c03 | 6 | */ |
jm | 0:f3a5f6fe1c03 | 7 | |
jm | 0:f3a5f6fe1c03 | 8 | |
jm | 0:f3a5f6fe1c03 | 9 | #include "jmRingBuffer.h" |
jm | 0:f3a5f6fe1c03 | 10 | #include "stdio.h" |
jm | 0:f3a5f6fe1c03 | 11 | |
jm | 0:f3a5f6fe1c03 | 12 | // static creation of Command Line Buffer |
jm | 0:f3a5f6fe1c03 | 13 | struct RingBuffer Line, *pLine; |
jm | 0:f3a5f6fe1c03 | 14 | |
jm | 0:f3a5f6fe1c03 | 15 | /** @brief Command line ring buffer initialization. |
jm | 0:f3a5f6fe1c03 | 16 | * @param none |
jm | 0:f3a5f6fe1c03 | 17 | * @returns none |
jm | 0:f3a5f6fe1c03 | 18 | */ |
jm | 0:f3a5f6fe1c03 | 19 | void InitCommandLineRingBuffer(void){ |
jm | 0:f3a5f6fe1c03 | 20 | pLine = &Line; |
jm | 0:f3a5f6fe1c03 | 21 | FlushRingBuffer(pLine); |
jm | 0:f3a5f6fe1c03 | 22 | } |
jm | 0:f3a5f6fe1c03 | 23 | |
jm | 0:f3a5f6fe1c03 | 24 | /** @brief Move ring head pointer foward. |
jm | 0:f3a5f6fe1c03 | 25 | * @param *p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 26 | * @returns none |
jm | 0:f3a5f6fe1c03 | 27 | */ |
jm | 0:f3a5f6fe1c03 | 28 | void NextHead(struct RingBuffer *p) |
jm | 0:f3a5f6fe1c03 | 29 | { p->head++; |
jm | 0:f3a5f6fe1c03 | 30 | if(p->head >= DimRingBuffer) |
jm | 0:f3a5f6fe1c03 | 31 | p->head=0; |
jm | 0:f3a5f6fe1c03 | 32 | } |
jm | 0:f3a5f6fe1c03 | 33 | |
jm | 0:f3a5f6fe1c03 | 34 | /** @brief Move ring tail pointer foward. |
jm | 0:f3a5f6fe1c03 | 35 | * @param pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 36 | * @returns none |
jm | 0:f3a5f6fe1c03 | 37 | */ |
jm | 0:f3a5f6fe1c03 | 38 | void NextTail(struct RingBuffer *p) |
jm | 0:f3a5f6fe1c03 | 39 | { p->tail++; |
jm | 0:f3a5f6fe1c03 | 40 | if(p->tail >= DimRingBuffer) |
jm | 0:f3a5f6fe1c03 | 41 | p->tail=0; |
jm | 0:f3a5f6fe1c03 | 42 | } |
jm | 0:f3a5f6fe1c03 | 43 | |
jm | 0:f3a5f6fe1c03 | 44 | /** @brief Check if buffer full. |
jm | 0:f3a5f6fe1c03 | 45 | * @param *p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 46 | * @returns true if full, false otherwise |
jm | 0:f3a5f6fe1c03 | 47 | */ |
jm | 0:f3a5f6fe1c03 | 48 | bool Full(struct RingBuffer *p) |
jm | 0:f3a5f6fe1c03 | 49 | { if(p->qty >= DimRingBuffer) |
jm | 0:f3a5f6fe1c03 | 50 | return true; |
jm | 0:f3a5f6fe1c03 | 51 | else |
jm | 0:f3a5f6fe1c03 | 52 | return false; |
jm | 0:f3a5f6fe1c03 | 53 | } |
jm | 0:f3a5f6fe1c03 | 54 | |
jm | 0:f3a5f6fe1c03 | 55 | /** @brief Insert a char in buffer. |
jm | 0:f3a5f6fe1c03 | 56 | * @param c unsigned char to be inserted |
jm | 0:f3a5f6fe1c03 | 57 | * @param *p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 58 | * @returns none |
jm | 0:f3a5f6fe1c03 | 59 | */ |
jm | 0:f3a5f6fe1c03 | 60 | void Insert(unsigned char c, struct RingBuffer *p) |
jm | 0:f3a5f6fe1c03 | 61 | { if(Full(p)) |
jm | 0:f3a5f6fe1c03 | 62 | NextHead(p); |
jm | 0:f3a5f6fe1c03 | 63 | else |
jm | 0:f3a5f6fe1c03 | 64 | p->qty++; |
jm | 0:f3a5f6fe1c03 | 65 | |
jm | 0:f3a5f6fe1c03 | 66 | p->Buffer[p->tail]=c; |
jm | 0:f3a5f6fe1c03 | 67 | NextTail(p); |
jm | 0:f3a5f6fe1c03 | 68 | } |
jm | 0:f3a5f6fe1c03 | 69 | |
jm | 0:f3a5f6fe1c03 | 70 | /** @brief Check if ring buffer not empty. |
jm | 0:f3a5f6fe1c03 | 71 | * @param *p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 72 | * @returns true if full, false otherwise |
jm | 0:f3a5f6fe1c03 | 73 | */ |
jm | 0:f3a5f6fe1c03 | 74 | bool NotEmpty(struct RingBuffer *p) |
jm | 0:f3a5f6fe1c03 | 75 | { if(p->qty == 0) |
jm | 0:f3a5f6fe1c03 | 76 | return false ; |
jm | 0:f3a5f6fe1c03 | 77 | else |
jm | 0:f3a5f6fe1c03 | 78 | return true; |
jm | 0:f3a5f6fe1c03 | 79 | } |
jm | 0:f3a5f6fe1c03 | 80 | |
jm | 0:f3a5f6fe1c03 | 81 | /** @brief Extract a char from ring buffer. |
jm | 0:f3a5f6fe1c03 | 82 | * @param *p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 83 | * @returns unsigned char |
jm | 0:f3a5f6fe1c03 | 84 | */ |
jm | 0:f3a5f6fe1c03 | 85 | unsigned char Extract(struct RingBuffer *p) |
jm | 0:f3a5f6fe1c03 | 86 | { unsigned char c; |
jm | 0:f3a5f6fe1c03 | 87 | c = p->Buffer[p->head]; |
jm | 0:f3a5f6fe1c03 | 88 | if(NotEmpty(p)) |
jm | 0:f3a5f6fe1c03 | 89 | { NextHead(p); |
jm | 0:f3a5f6fe1c03 | 90 | p->qty--; |
jm | 0:f3a5f6fe1c03 | 91 | } |
jm | 0:f3a5f6fe1c03 | 92 | return c; |
jm | 0:f3a5f6fe1c03 | 93 | } |
jm | 0:f3a5f6fe1c03 | 94 | |
jm | 0:f3a5f6fe1c03 | 95 | /** @brief Flush ring buffer. |
jm | 0:f3a5f6fe1c03 | 96 | * @param *p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 97 | * @returns none |
jm | 0:f3a5f6fe1c03 | 98 | */ |
jm | 0:f3a5f6fe1c03 | 99 | void FlushRingBuffer(struct RingBuffer *p) |
jm | 0:f3a5f6fe1c03 | 100 | { int i; |
jm | 0:f3a5f6fe1c03 | 101 | p->head = 0; |
jm | 0:f3a5f6fe1c03 | 102 | p->tail = 0; |
jm | 0:f3a5f6fe1c03 | 103 | p->qty = 0; |
jm | 0:f3a5f6fe1c03 | 104 | for(i=0;i<DimRingBuffer;i++)p->Buffer[i]=0; |
jm | 0:f3a5f6fe1c03 | 105 | } |
jm | 0:f3a5f6fe1c03 | 106 | |
jm | 0:f3a5f6fe1c03 | 107 | /** @brief Delete last char from ring buffer. |
jm | 0:f3a5f6fe1c03 | 108 | * @param *p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 109 | * @returns none |
jm | 0:f3a5f6fe1c03 | 110 | */ |
jm | 0:f3a5f6fe1c03 | 111 | void DelChar(struct RingBuffer *p) |
jm | 0:f3a5f6fe1c03 | 112 | { if(p->qty != 0){ |
jm | 0:f3a5f6fe1c03 | 113 | if(p->tail==0)p->tail=DimRingBuffer; |
jm | 0:f3a5f6fe1c03 | 114 | else p->tail--; |
jm | 0:f3a5f6fe1c03 | 115 | p->qty--; |
jm | 0:f3a5f6fe1c03 | 116 | } |
jm | 0:f3a5f6fe1c03 | 117 | } |
jm | 0:f3a5f6fe1c03 | 118 | |
jm | 0:f3a5f6fe1c03 | 119 | /** @brief Remove a command line from ring buffer. |
jm | 0:f3a5f6fe1c03 | 120 | * @param c end command identifier unsigned char |
jm | 0:f3a5f6fe1c03 | 121 | * @param *p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 122 | * @returns none |
jm | 0:f3a5f6fe1c03 | 123 | */ |
jm | 0:f3a5f6fe1c03 | 124 | void NextCommand(unsigned char c, struct RingBuffer *p){ |
jm | 0:f3a5f6fe1c03 | 125 | // remove all char till end identifier is found |
jm | 0:f3a5f6fe1c03 | 126 | while(NotEmpty(p) && p->Buffer[p->head] != c) |
jm | 0:f3a5f6fe1c03 | 127 | { NextHead(p); |
jm | 0:f3a5f6fe1c03 | 128 | p->qty--; |
jm | 0:f3a5f6fe1c03 | 129 | } |
jm | 0:f3a5f6fe1c03 | 130 | |
jm | 0:f3a5f6fe1c03 | 131 | // remove end identifier |
jm | 0:f3a5f6fe1c03 | 132 | if(NotEmpty(p)&& p->Buffer[p->head] == c) |
jm | 0:f3a5f6fe1c03 | 133 | { NextHead(p); |
jm | 0:f3a5f6fe1c03 | 134 | p->qty--; |
jm | 0:f3a5f6fe1c03 | 135 | } |
jm | 0:f3a5f6fe1c03 | 136 | } |
jm | 0:f3a5f6fe1c03 | 137 | |
jm | 0:f3a5f6fe1c03 | 138 | /** @brief View ring buffer content. |
jm | 0:f3a5f6fe1c03 | 139 | * Print ring buffer content |
jm | 0:f3a5f6fe1c03 | 140 | * @param *p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 141 | * @returns none |
jm | 0:f3a5f6fe1c03 | 142 | */ |
jm | 0:f3a5f6fe1c03 | 143 | void ViewRingBuffer(struct RingBuffer *p){ |
jm | 0:f3a5f6fe1c03 | 144 | int i,j; |
jm | 0:f3a5f6fe1c03 | 145 | |
jm | 0:f3a5f6fe1c03 | 146 | printf("\nRingBuffer Qty: %d \nContent: ",p->qty); |
jm | 0:f3a5f6fe1c03 | 147 | |
jm | 0:f3a5f6fe1c03 | 148 | for(j=0,i=p->head;j<p->qty;j++){ |
jm | 0:f3a5f6fe1c03 | 149 | printf("%c",p->Buffer[i]); |
jm | 0:f3a5f6fe1c03 | 150 | if(i++>DimRingBuffer)i=0; |
jm | 0:f3a5f6fe1c03 | 151 | } |
jm | 0:f3a5f6fe1c03 | 152 | printf("\n"); |
jm | 0:f3a5f6fe1c03 | 153 | } |
jm | 0:f3a5f6fe1c03 | 154 | |
jm | 0:f3a5f6fe1c03 | 155 | /** @brief Extract a word from ring buffer. |
jm | 0:f3a5f6fe1c03 | 156 | * The extracted word is put in the array pointed by word |
jm | 0:f3a5f6fe1c03 | 157 | * @param p pointer to a ring buffer |
jm | 0:f3a5f6fe1c03 | 158 | * @param word pointer to array of char |
jm | 0:f3a5f6fe1c03 | 159 | * @returns true if a word is extracted otherwise returns false |
jm | 0:f3a5f6fe1c03 | 160 | */ |
jm | 0:f3a5f6fe1c03 | 161 | bool ExtractWord(struct RingBuffer *p, char * word){ |
jm | 0:f3a5f6fe1c03 | 162 | unsigned char c; |
jm | 0:f3a5f6fe1c03 | 163 | int i,j; |
jm | 0:f3a5f6fe1c03 | 164 | j=0; |
jm | 0:f3a5f6fe1c03 | 165 | |
jm | 0:f3a5f6fe1c03 | 166 | if(NotEmpty(p)){ |
jm | 0:f3a5f6fe1c03 | 167 | for(i=0;i<WordMaxSize-1;i++){ |
jm | 0:f3a5f6fe1c03 | 168 | // extract a char from Rx ring buffer |
jm | 0:f3a5f6fe1c03 | 169 | c=Extract(p); |
jm | 0:f3a5f6fe1c03 | 170 | |
jm | 0:f3a5f6fe1c03 | 171 | // remove leading blanks |
jm | 0:f3a5f6fe1c03 | 172 | if(c==' ' && j==0)continue; |
jm | 0:f3a5f6fe1c03 | 173 | |
jm | 0:f3a5f6fe1c03 | 174 | // end of word or end of command line |
jm | 0:f3a5f6fe1c03 | 175 | if(c==' ' || c==nl)break; |
jm | 0:f3a5f6fe1c03 | 176 | |
jm | 0:f3a5f6fe1c03 | 177 | // build the Word |
jm | 0:f3a5f6fe1c03 | 178 | word[j++]=c; |
jm | 0:f3a5f6fe1c03 | 179 | } |
jm | 0:f3a5f6fe1c03 | 180 | // 0 string termination |
jm | 0:f3a5f6fe1c03 | 181 | word[j]=0; |
jm | 0:f3a5f6fe1c03 | 182 | if(j>0)return true; |
jm | 0:f3a5f6fe1c03 | 183 | } |
jm | 0:f3a5f6fe1c03 | 184 | return false; |
jm | 0:f3a5f6fe1c03 | 185 | } |
jm | 0:f3a5f6fe1c03 | 186 | |
jm | 0:f3a5f6fe1c03 | 187 | /** @brief Extract an unsigned int from ring buffer. |
jm | 0:f3a5f6fe1c03 | 188 | * Convert a word from buffer into an integer between min and max values |
jm | 0:f3a5f6fe1c03 | 189 | * Value converted should be between min and max values. |
jm | 0:f3a5f6fe1c03 | 190 | * Value should be decimal or hexadecimal (beginning by 0x or 0X) |
jm | 0:f3a5f6fe1c03 | 191 | * @param p pointer to ring buffer |
jm | 0:f3a5f6fe1c03 | 192 | * @param result pointer to unsigned int |
jm | 0:f3a5f6fe1c03 | 193 | * @param min minimum limit |
jm | 0:f3a5f6fe1c03 | 194 | * @param max maximum limit |
jm | 0:f3a5f6fe1c03 | 195 | * @returns true if value is converted beetween limits, including limits. |
jm | 0:f3a5f6fe1c03 | 196 | */ |
jm | 0:f3a5f6fe1c03 | 197 | bool ExtractUInteger(struct RingBuffer *p, unsigned int *result, unsigned int min, unsigned int max){ |
jm | 0:f3a5f6fe1c03 | 198 | unsigned int i ; |
jm | 0:f3a5f6fe1c03 | 199 | char word[WordMaxSize-1]; |
jm | 0:f3a5f6fe1c03 | 200 | |
jm | 0:f3a5f6fe1c03 | 201 | if(ExtractWord(p,word)){ // Extract string value |
jm | 0:f3a5f6fe1c03 | 202 | if(word[0]=='0' && (word[1]=='x' || word[1]=='X')) { |
jm | 0:f3a5f6fe1c03 | 203 | sscanf(word,"%x",&i); // convert hexadecimal input |
jm | 0:f3a5f6fe1c03 | 204 | } |
jm | 0:f3a5f6fe1c03 | 205 | else |
jm | 0:f3a5f6fe1c03 | 206 | sscanf(word,"%d",&i); // convert decimal input |
jm | 0:f3a5f6fe1c03 | 207 | |
jm | 0:f3a5f6fe1c03 | 208 | if(i>=min && i<=max){ |
jm | 0:f3a5f6fe1c03 | 209 | *result = i; |
jm | 0:f3a5f6fe1c03 | 210 | return true; |
jm | 0:f3a5f6fe1c03 | 211 | } |
jm | 0:f3a5f6fe1c03 | 212 | } |
jm | 0:f3a5f6fe1c03 | 213 | *result = 0; |
jm | 0:f3a5f6fe1c03 | 214 | return false; |
jm | 0:f3a5f6fe1c03 | 215 | } |