@@ -59,20 +59,22 @@ int CDC_TransmitQueue_ReadSize(CDC_TransmitQueue_TypeDef *queue) {
59
59
}
60
60
61
61
// Write provided data into queue.
62
- void CDC_TransmitQueue_Enqueue (CDC_TransmitQueue_TypeDef * queue , const uint8_t * buffer ,
63
- uint32_t size ) {
62
+ void CDC_TransmitQueue_Enqueue (CDC_TransmitQueue_TypeDef * queue ,
63
+ const uint8_t * buffer , uint32_t size ) {
64
64
uint32_t sizeToEnd = CDC_TRANSMIT_QUEUE_BUFFER_SIZE - queue -> write ;
65
65
if (sizeToEnd > size ) {
66
66
memcpy (& queue -> buffer [queue -> write ], & buffer [0 ], size );
67
67
} else {
68
68
memcpy (& queue -> buffer [queue -> write ], & buffer [0 ], sizeToEnd );
69
69
memcpy (& queue -> buffer [0 ], & buffer [sizeToEnd ], size - sizeToEnd );
70
70
}
71
- queue -> write = (uint16_t )((queue -> write + size ) % CDC_TRANSMIT_QUEUE_BUFFER_SIZE );
71
+ queue -> write = (uint16_t )((queue -> write + size ) %
72
+ CDC_TRANSMIT_QUEUE_BUFFER_SIZE );
72
73
}
73
74
74
- // Read flat block from queue (biggest as possible, but max CDC_QUEUE_MAX_PACKET_SIZE).
75
- uint8_t * CDC_TransmitQueue_ReadBlock (CDC_TransmitQueue_TypeDef * queue , uint16_t * size ) {
75
+ // Read flat block from queue biggest as possible, but max QUEUE_MAX_PACKET_SIZE
76
+ uint8_t * CDC_TransmitQueue_ReadBlock (CDC_TransmitQueue_TypeDef * queue ,
77
+ uint16_t * size ) {
76
78
if (queue -> write >= queue -> read ) {
77
79
* size = queue -> write - queue -> read ;
78
80
} else {
@@ -83,7 +85,8 @@ uint8_t *CDC_TransmitQueue_ReadBlock(CDC_TransmitQueue_TypeDef *queue, uint16_t
83
85
}
84
86
85
87
void CDC_TransmitQueue_CommitRead (CDC_TransmitQueue_TypeDef * queue ) {
86
- queue -> read = (queue -> read + queue -> reserved ) % CDC_TRANSMIT_QUEUE_BUFFER_SIZE ;
88
+ queue -> read = (queue -> read + queue -> reserved ) %
89
+ CDC_TRANSMIT_QUEUE_BUFFER_SIZE ;
87
90
}
88
91
89
92
// Initialize read and write position of queue.
@@ -95,23 +98,33 @@ void CDC_ReceiveQueue_Init(CDC_ReceiveQueue_TypeDef *queue) {
95
98
96
99
// Reserve block in queue and return pointer to it.
97
100
uint8_t * CDC_ReceiveQueue_ReserveBlock (CDC_ReceiveQueue_TypeDef * queue ) {
98
- if ((uint16_t )(CDC_RECEIVE_QUEUE_BUFFER_SIZE - queue -> write ) >= CDC_QUEUE_MAX_PACKET_SIZE &&
99
- (queue -> read <= queue -> write || (uint16_t )(queue -> read - queue -> write ) >= CDC_QUEUE_MAX_PACKET_SIZE )) {
100
- // have enough space on the rest of buffer to store full-length packet
101
- return & queue -> buffer [queue -> write ];
102
- } else if (queue -> read >= CDC_QUEUE_MAX_PACKET_SIZE && queue -> read <= queue -> write ) {
103
- // have enough space on the beginning of buffer to store full-length packet
104
- queue -> length = queue -> write ;
105
- queue -> write = 0 ;
106
- return & queue -> buffer [queue -> write ];
107
- } else {
108
- // have no space to store full-length packet
109
- return 0 ;
101
+ const uint16_t limit =
102
+ CDC_RECEIVE_QUEUE_BUFFER_SIZE - CDC_QUEUE_MAX_PACKET_SIZE ;
103
+ volatile uint16_t read = queue -> read ;
104
+
105
+ if (read <= queue -> write ) {
106
+ // if write is limited only by buffer size.
107
+ if (queue -> write < limit || (queue -> write == limit && read > 0 )) {
108
+ // if size in the rest of buffer is enough for full packet plus 1 byte
109
+ // or if it tight enough and write position can be set to 0
110
+ return queue -> buffer + queue -> write ;
111
+ } else if (read > CDC_QUEUE_MAX_PACKET_SIZE ) {
112
+ // if size in the rest is not enough, but enough size in head
113
+ queue -> length = queue -> write ;
114
+ queue -> write = 0 ;
115
+ return queue -> buffer + queue -> write ;
116
+ }
117
+ } else if (queue -> write + CDC_QUEUE_MAX_PACKET_SIZE < read ) {
118
+ // write position must be less than read position
119
+ // after reading largest possible packet
120
+ return queue -> buffer + queue -> write ;
110
121
}
122
+ return 0 ;
111
123
}
112
124
113
125
// Commits block in queue and make it available for reading
114
- void CDC_ReceiveQueue_CommitBlock (CDC_ReceiveQueue_TypeDef * queue , uint16_t size ) {
126
+ void CDC_ReceiveQueue_CommitBlock (CDC_ReceiveQueue_TypeDef * queue ,
127
+ uint16_t size ) {
115
128
queue -> write += size ;
116
129
if (queue -> write >= queue -> length ) {
117
130
queue -> length = CDC_RECEIVE_QUEUE_BUFFER_SIZE ;
@@ -123,38 +136,45 @@ void CDC_ReceiveQueue_CommitBlock(CDC_ReceiveQueue_TypeDef *queue, uint16_t size
123
136
124
137
// Determine size, available for read
125
138
int CDC_ReceiveQueue_ReadSize (CDC_ReceiveQueue_TypeDef * queue ) {
126
- if (queue -> write >= queue -> read ) {
127
- return queue -> write - queue -> read ;
128
- } else {
129
- return queue -> length + queue -> write - queue -> read ;
139
+ // reading length after write make guarantee, that length >= write
140
+ // and determined reading size will be smaller or equal than real one.
141
+ volatile uint16_t write = queue -> write ;
142
+ volatile uint16_t length = queue -> length ;
143
+ if (write >= queue -> read ) {
144
+ return write - queue -> read ;
130
145
}
146
+ return length + write - queue -> read ;
131
147
}
132
148
133
149
// Read one byte from queue.
134
150
int CDC_ReceiveQueue_Dequeue (CDC_ReceiveQueue_TypeDef * queue ) {
135
- if (queue -> write == queue -> read ) return -1 ;
151
+ volatile uint16_t write = queue -> write ;
152
+ volatile uint16_t length = queue -> length ;
153
+ if (queue -> read == length ) queue -> read = 0 ;
154
+ if (write == queue -> read ) return -1 ;
136
155
uint8_t ch = queue -> buffer [queue -> read ++ ];
137
- if (queue -> read >= queue -> length ) {
156
+ if (queue -> read >= length ) {
138
157
queue -> read = 0 ;
139
158
}
140
159
return ch ;
141
160
}
142
161
143
162
// Peek byte from queue.
144
163
int CDC_ReceiveQueue_Peek (CDC_ReceiveQueue_TypeDef * queue ) {
145
- if (queue -> write == queue -> read ) return -1 ;
164
+ volatile uint16_t write = queue -> write ;
165
+ volatile uint16_t length = queue -> length ;
166
+ if (queue -> read >= length ) queue -> read = 0 ;
167
+ if (write == queue -> read ) return -1 ;
146
168
return queue -> buffer [queue -> read ];
147
169
}
148
170
149
- uint16_t CDC_ReceiveQueue_Read (CDC_ReceiveQueue_TypeDef * queue , uint8_t * buffer , uint16_t size ) {
171
+ uint16_t CDC_ReceiveQueue_Read (CDC_ReceiveQueue_TypeDef * queue ,
172
+ uint8_t * buffer , uint16_t size ) {
150
173
volatile uint16_t write = queue -> write ;
151
174
volatile uint16_t length = queue -> length ;
152
175
uint16_t available ;
153
- while (write != queue -> write || length != queue -> length ) {
154
- write = queue -> write ;
155
- length = queue -> length ;
156
- }
157
176
177
+ if (queue -> read >= length ) queue -> read = 0 ;
158
178
if (write >= queue -> read ) {
159
179
available = write - queue -> read ;
160
180
} else {
@@ -172,16 +192,13 @@ uint16_t CDC_ReceiveQueue_Read(CDC_ReceiveQueue_TypeDef *queue, uint8_t *buffer,
172
192
return size ;
173
193
}
174
194
175
- bool CDC_ReceiveQueue_ReadUntil (CDC_ReceiveQueue_TypeDef * queue , uint8_t terminator , uint8_t * buffer ,
176
- uint16_t size , uint16_t * fetched ) {
195
+ bool CDC_ReceiveQueue_ReadUntil (CDC_ReceiveQueue_TypeDef * queue ,
196
+ uint8_t terminator , uint8_t * buffer , uint16_t size , uint16_t * fetched ) {
177
197
volatile uint16_t write = queue -> write ;
178
198
volatile uint16_t length = queue -> length ;
179
199
uint16_t available ;
180
- while (write != queue -> write || length != queue -> length ) {
181
- write = queue -> write ;
182
- length = queue -> length ;
183
- }
184
200
201
+ if (queue -> read >= length ) queue -> read = 0 ;
185
202
if (write >= queue -> read ) {
186
203
available = write - queue -> read ;
187
204
} else {
0 commit comments