Skip to content

Commit 34b082d

Browse files
makarenyafpistm
authored andcommitted
[USB CDC] Add queue implementation
Signed-off-by: Alexey Makarenya <[email protected]>
1 parent e5a947e commit 34b082d

File tree

2 files changed

+231
-0
lines changed

2 files changed

+231
-0
lines changed
+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/**
2+
******************************************************************************
3+
* @file cdc_queue.c
4+
* @author makarenya
5+
* @version V1.0.0
6+
* @date 23-December-2018
7+
* @brief Provides methods to manipulate with CDC cyclic buffers
8+
******************************************************************************
9+
* @attention
10+
*
11+
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
12+
*
13+
* Redistribution and use in source and binary forms, with or without modification,
14+
* are permitted provided that the following conditions are met:
15+
* 1. Redistributions of source code must retain the above copyright notice,
16+
* this list of conditions and the following disclaimer.
17+
* 2. Redistributions in binary form must reproduce the above copyright notice,
18+
* this list of conditions and the following disclaimer in the documentation
19+
* and/or other materials provided with the distribution.
20+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
21+
* may be used to endorse or promote products derived from this software
22+
* without specific prior written permission.
23+
*
24+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34+
*
35+
******************************************************************************
36+
*/
37+
38+
#ifdef USBCON
39+
#ifdef USBD_USE_CDC
40+
41+
#include "cdc_queue.h"
42+
43+
// Initialize read and write position of queue
44+
void CDC_TransmitQueue_Init(CDC_TransmitQueue_TypeDef *queue) {
45+
queue->read = 0;
46+
queue->write = 0;
47+
}
48+
49+
// Determine size, available for write in queue
50+
int CDC_TransmitQueue_WriteSize(CDC_TransmitQueue_TypeDef *queue) {
51+
return (queue->read + CDC_TRANSMIT_QUEUE_BUFFER_SIZE - queue->write - 1)
52+
% CDC_TRANSMIT_QUEUE_BUFFER_SIZE;
53+
}
54+
55+
// Determine size of data, stored in queue
56+
int CDC_TransmitQueue_ReadSize(CDC_TransmitQueue_TypeDef *queue) {
57+
return (queue->write + CDC_TRANSMIT_QUEUE_BUFFER_SIZE - queue->read)
58+
% CDC_TRANSMIT_QUEUE_BUFFER_SIZE;
59+
}
60+
61+
// Write provided data into queue.
62+
void CDC_TransmitQueue_Enqueue(CDC_TransmitQueue_TypeDef *queue, const uint8_t *buffer,
63+
uint32_t size) {
64+
uint32_t sizeToEnd = CDC_TRANSMIT_QUEUE_BUFFER_SIZE - queue->write;
65+
if (sizeToEnd > size) {
66+
memcpy(&queue->buffer[queue->write], &buffer[0], size);
67+
} else {
68+
memcpy(&queue->buffer[queue->write], &buffer[0], sizeToEnd);
69+
memcpy(&queue->buffer[0], &buffer[sizeToEnd], size - sizeToEnd);
70+
}
71+
queue->write = (uint16_t)((queue->write + size) % CDC_TRANSMIT_QUEUE_BUFFER_SIZE);
72+
}
73+
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) {
76+
uint16_t readPos = queue->read;
77+
if (queue->write >= queue->read) {
78+
*size = queue->write - queue->read;
79+
queue->read = queue->write;
80+
} else if ((uint16_t)(CDC_TRANSMIT_QUEUE_BUFFER_SIZE - queue->read) > CDC_QUEUE_MAX_PACKET_SIZE) {
81+
// limit to max packet size
82+
*size = CDC_QUEUE_MAX_PACKET_SIZE;
83+
queue->read += CDC_QUEUE_MAX_PACKET_SIZE;
84+
} else {
85+
*size = CDC_TRANSMIT_QUEUE_BUFFER_SIZE - queue->read;
86+
queue->read = 0;
87+
}
88+
return &queue->buffer[readPos];
89+
}
90+
91+
// Initialize read and write position of queue.
92+
void CDC_ReceiveQueue_Init(CDC_ReceiveQueue_TypeDef *queue) {
93+
queue->read = 0;
94+
queue->write = 0;
95+
queue->length = CDC_RECEIVE_QUEUE_BUFFER_SIZE;
96+
}
97+
98+
// Reserve block in queue and return pointer to it.
99+
uint8_t *CDC_ReceiveQueue_ReserveBlock(CDC_ReceiveQueue_TypeDef *queue) {
100+
if ((uint16_t)(CDC_RECEIVE_QUEUE_BUFFER_SIZE - queue->write) >= CDC_QUEUE_MAX_PACKET_SIZE) {
101+
// have enough space on the rest of buffer to store full-length packet
102+
return &queue->buffer[queue->write];
103+
} else if (queue->read >= CDC_QUEUE_MAX_PACKET_SIZE) {
104+
// have enough space on the beginning of buffer to store full-length packet
105+
queue->length = queue->write;
106+
queue->write = 0;
107+
return &queue->buffer[queue->write];
108+
} else {
109+
// have no space to store full-length packet
110+
return 0;
111+
}
112+
}
113+
114+
// Commits block in queue and make it available for reading
115+
void CDC_ReceiveQueue_CommitBlock(CDC_ReceiveQueue_TypeDef *queue, uint16_t size) {
116+
queue->write += size;
117+
}
118+
119+
// Determine size, available for read
120+
int CDC_ReceiveQueue_ReadSize(CDC_ReceiveQueue_TypeDef *queue) {
121+
if (queue->write >= queue->read) {
122+
return queue->write - queue->read;
123+
} else {
124+
return queue->length - queue->read;
125+
}
126+
}
127+
128+
// Read one byte from queue.
129+
uint8_t CDC_ReceiveQueue_Dequeue(CDC_ReceiveQueue_TypeDef *queue) {
130+
uint8_t ch = queue->buffer[queue->read++];
131+
if (queue->read >= queue->length) {
132+
queue->read = 0;
133+
}
134+
return ch;
135+
}
136+
137+
// Peek byte from queue.
138+
uint8_t CDC_ReceiveQueue_Peek(CDC_ReceiveQueue_TypeDef *queue) {
139+
return queue->buffer[queue->read];
140+
}
141+
142+
#endif /* USBD_USE_CDC */
143+
#endif /* USBCON */
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
******************************************************************************
3+
* @file cdc_queue.h
4+
* @author makarenya
5+
* @version V1.0.0
6+
* @date 23-December-2018
7+
* @brief Header for cdc_queue.c module
8+
******************************************************************************
9+
* @attention
10+
*
11+
* <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
12+
*
13+
* Redistribution and use in source and binary forms, with or without modification,
14+
* are permitted provided that the following conditions are met:
15+
* 1. Redistributions of source code must retain the above copyright notice,
16+
* this list of conditions and the following disclaimer.
17+
* 2. Redistributions in binary form must reproduce the above copyright notice,
18+
* this list of conditions and the following disclaimer in the documentation
19+
* and/or other materials provided with the distribution.
20+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
21+
* may be used to endorse or promote products derived from this software
22+
* without specific prior written permission.
23+
*
24+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34+
*
35+
******************************************************************************
36+
*/
37+
38+
39+
/* Define to prevent recursive inclusion -------------------------------------*/
40+
#ifndef __CDC_QUEUE_H
41+
#define __CDC_QUEUE_H
42+
43+
/* Includes ------------------------------------------------------------------*/
44+
#include "usbd_def.h"
45+
46+
#ifdef __cplusplus
47+
extern "C" {
48+
#endif
49+
50+
#if USE_USB_HS
51+
#define CDC_QUEUE_MAX_PACKET_SIZE USB_HS_MAX_PACKET_SIZE
52+
#else
53+
#define CDC_QUEUE_MAX_PACKET_SIZE USB_FS_MAX_PACKET_SIZE
54+
#endif
55+
#define CDC_TRANSMIT_QUEUE_BUFFER_SIZE ((uint16_t)(CDC_QUEUE_MAX_PACKET_SIZE))
56+
#define CDC_RECEIVE_QUEUE_BUFFER_SIZE ((uint16_t)(CDC_QUEUE_MAX_PACKET_SIZE * 2))
57+
58+
typedef struct {
59+
uint8_t buffer[CDC_TRANSMIT_QUEUE_BUFFER_SIZE];
60+
volatile uint16_t write;
61+
volatile uint16_t read;
62+
} CDC_TransmitQueue_TypeDef;
63+
64+
typedef struct {
65+
uint8_t buffer[CDC_RECEIVE_QUEUE_BUFFER_SIZE];
66+
volatile uint16_t write;
67+
volatile uint16_t read;
68+
volatile uint16_t length;
69+
} CDC_ReceiveQueue_TypeDef;
70+
71+
void CDC_TransmitQueue_Init(CDC_TransmitQueue_TypeDef* queue);
72+
int CDC_TransmitQueue_WriteSize(CDC_TransmitQueue_TypeDef* queue);
73+
int CDC_TransmitQueue_ReadSize(CDC_TransmitQueue_TypeDef* queue);
74+
void CDC_TransmitQueue_Enqueue(CDC_TransmitQueue_TypeDef* queue, const uint8_t* buffer, uint32_t size);
75+
uint8_t* CDC_TransmitQueue_ReadBlock(CDC_TransmitQueue_TypeDef* queue, uint16_t* size);
76+
77+
void CDC_ReceiveQueue_Init(CDC_ReceiveQueue_TypeDef* queue);
78+
int CDC_ReceiveQueue_ReadSize(CDC_ReceiveQueue_TypeDef* queue);
79+
uint8_t CDC_ReceiveQueue_Dequeue(CDC_ReceiveQueue_TypeDef* queue);
80+
uint8_t CDC_ReceiveQueue_Peek(CDC_ReceiveQueue_TypeDef* queue);
81+
uint8_t* CDC_ReceiveQueue_ReserveBlock(CDC_ReceiveQueue_TypeDef* queue);
82+
void CDC_ReceiveQueue_CommitBlock(CDC_ReceiveQueue_TypeDef* queue, uint16_t size);
83+
84+
#ifdef __cplusplus
85+
}
86+
#endif
87+
88+
#endif // __CDC_QUEUE_H

0 commit comments

Comments
 (0)