@@ -59,20 +59,22 @@ int CDC_TransmitQueue_ReadSize(CDC_TransmitQueue_TypeDef *queue) {
5959}
6060
6161// 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 ) {
6464 uint32_t sizeToEnd = CDC_TRANSMIT_QUEUE_BUFFER_SIZE - queue -> write ;
6565 if (sizeToEnd > size ) {
6666 memcpy (& queue -> buffer [queue -> write ], & buffer [0 ], size );
6767 } else {
6868 memcpy (& queue -> buffer [queue -> write ], & buffer [0 ], sizeToEnd );
6969 memcpy (& queue -> buffer [0 ], & buffer [sizeToEnd ], size - sizeToEnd );
7070 }
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 );
7273}
7374
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 ) {
7678 if (queue -> write >= queue -> read ) {
7779 * size = queue -> write - queue -> read ;
7880 } else {
@@ -83,7 +85,8 @@ uint8_t *CDC_TransmitQueue_ReadBlock(CDC_TransmitQueue_TypeDef *queue, uint16_t
8385}
8486
8587void 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 ;
8790}
8891
8992// Initialize read and write position of queue.
@@ -95,23 +98,33 @@ void CDC_ReceiveQueue_Init(CDC_ReceiveQueue_TypeDef *queue) {
9598
9699// Reserve block in queue and return pointer to it.
97100uint8_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 ;
110121 }
122+ return 0 ;
111123}
112124
113125// 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 ) {
115128 queue -> write += size ;
116129 if (queue -> write >= queue -> length ) {
117130 queue -> length = CDC_RECEIVE_QUEUE_BUFFER_SIZE ;
@@ -123,38 +136,45 @@ void CDC_ReceiveQueue_CommitBlock(CDC_ReceiveQueue_TypeDef *queue, uint16_t size
123136
124137// Determine size, available for read
125138int 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 ;
130145 }
146+ return length + write - queue -> read ;
131147}
132148
133149// Read one byte from queue.
134150int 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 ;
136155 uint8_t ch = queue -> buffer [queue -> read ++ ];
137- if (queue -> read >= queue -> length ) {
156+ if (queue -> read >= length ) {
138157 queue -> read = 0 ;
139158 }
140159 return ch ;
141160}
142161
143162// Peek byte from queue.
144163int 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 ;
146168 return queue -> buffer [queue -> read ];
147169}
148170
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 ) {
150173 volatile uint16_t write = queue -> write ;
151174 volatile uint16_t length = queue -> length ;
152175 uint16_t available ;
153- while (write != queue -> write || length != queue -> length ) {
154- write = queue -> write ;
155- length = queue -> length ;
156- }
157176
177+ if (queue -> read >= length ) queue -> read = 0 ;
158178 if (write >= queue -> read ) {
159179 available = write - queue -> read ;
160180 } else {
@@ -172,16 +192,13 @@ uint16_t CDC_ReceiveQueue_Read(CDC_ReceiveQueue_TypeDef *queue, uint8_t *buffer,
172192 return size ;
173193}
174194
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 ) {
177197 volatile uint16_t write = queue -> write ;
178198 volatile uint16_t length = queue -> length ;
179199 uint16_t available ;
180- while (write != queue -> write || length != queue -> length ) {
181- write = queue -> write ;
182- length = queue -> length ;
183- }
184200
201+ if (queue -> read >= length ) queue -> read = 0 ;
185202 if (write >= queue -> read ) {
186203 available = write - queue -> read ;
187204 } else {
0 commit comments