ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_usb_pvnd.c
Go to the documentation of this file.
1
21
22#include "ra8_usb_pvnd.h"
23
24#include <stdint.h>
25
26#include "ra8_attributes.h"
27#include "ra8_check.h"
28#include "ra8_err.h"
29#include "ra8_log.h"
30#include "ra8_usb.h"
31
32static const char* s_tag = "USBPVND";
33
34/* =============================================================================
35 * Internal state
36 * =============================================================================
37 */
38
52
54
55/* =============================================================================
56 * Internal helpers
57 * =============================================================================
58 */
59
81
96{
97 const uint16_t mp = internal_bulk_max_packet(speed);
98
99 /* Both calls receive the init-validated speed and compile-time pipe tuples
100 * that satisfy every `ra8_usb_configure_endpoint` argument guard. */
101 (void)ra8_usb_configure_endpoint(speed,
106 mp);
107 (void)ra8_usb_configure_endpoint(speed,
112 mp);
113}
114
129{
130 s_state.speed = speed;
131 s_state.bulk_max_packet = internal_bulk_max_packet(speed);
132 s_state.desc = nullptr;
133 s_state.desc_len = 0U;
134 s_state.setup_cb = nullptr;
135 s_state.setup_ctx = nullptr;
136}
137
161
162/* =============================================================================
163 * Lifecycle
164 * =============================================================================
165 */
166
168{
169 if ((speed != k_ra8_usb_speed_fs) && (speed != k_ra8_usb_speed_hs)) {
171 }
172 const ra8_err_t usb_err = ra8_usb_device_init(speed);
173 if (usb_err != k_ra8_ok) {
174 ra8_log_error_val(s_tag, "ra8_usb_device_init failed", (uint32_t)usb_err);
176 }
178
180 s_state.initialized = true;
181 ra8_log_info_val(s_tag, "device-Vendor ready", (uint32_t)speed);
182 return k_ra8_ok;
183}
184
186{
187 if (!s_state.initialized) {
189 }
190 (void)ra8_usb_device_attach(s_state.speed, false);
191 const ra8_err_t err = ra8_usb_device_deinit(s_state.speed);
192 s_state.initialized = false;
193 s_state.desc = nullptr;
194 s_state.setup_cb = nullptr;
195 s_state.setup_ctx = nullptr;
196 return err;
197}
198
199/* =============================================================================
200 * Descriptor handoff
201 * =============================================================================
202 */
203
204ra8_err_t ra8_usb_pvnd_set_descriptors(const uint8_t* desc, uint16_t desc_len)
205{
206 if (!s_state.initialized) {
208 }
209 RA8_CHECK_NULL_PTR(desc, s_tag, "set_descriptors: desc");
210 if (desc_len == 0U) {
212 }
213 s_state.desc = desc;
214 s_state.desc_len = desc_len;
215 return k_ra8_ok;
216}
217
218/* =============================================================================
219 * Vendor data transport
220 * =============================================================================
221 */
222
223ra8_err_t ra8_usb_pvnd_send(const uint8_t* data, uint16_t len)
224{
225 if (!s_state.initialized) {
227 }
228 if ((data == nullptr) && (len != 0U)) {
229 return k_ra8_err_null_ptr;
230 }
231 if ((len == 0U) || (len > s_state.bulk_max_packet)) {
233 }
234 return ra8_usb_queue_in(s_state.speed, k_ra8_pvnd_pipe_bulk_in, data, len);
235}
236
237ra8_err_t ra8_usb_pvnd_recv(uint8_t* buf, uint16_t max_len, uint16_t* got_len)
238{
239 RA8_CHECK_NULL_PTR(buf, s_tag, "recv: buf");
240 RA8_CHECK_NULL_PTR(got_len, s_tag, "recv: got_len");
241 if (!s_state.initialized) {
243 }
244 if (max_len == 0U) {
246 }
247 uint16_t inout_len = max_len;
248 const ra8_err_t err =
249 ra8_usb_queue_out(s_state.speed, k_ra8_pvnd_pipe_bulk_out, buf, &inout_len, true);
250 if (err == k_ra8_ok) {
251 *got_len = inout_len;
252 } else {
253 *got_len = 0U;
254 }
255 return err;
256}
257
258/* =============================================================================
259 * Setup-handler attach
260 * =============================================================================
261 */
262
264{
265 if (!s_state.initialized) {
267 }
268 s_state.setup_cb = setup_fn;
269 s_state.setup_ctx = ctx;
270 return k_ra8_ok;
271}
272
273/* =============================================================================
274 * Vendor SETUP dispatch
275 * =============================================================================
276 */
277
279{
280 RA8_CHECK_NULL_PTR(setup, s_tag, "handle_setup: setup");
281 if (!s_state.initialized) {
283 }
286 }
287 if (s_state.setup_cb == nullptr) {
288 /* No application handler -> stall the unknown vendor request. */
289 return ra8_usb_control_response(s_state.speed, false);
290 }
291 const ra8_err_t cb_err = s_state.setup_cb(s_state.setup_ctx, setup);
292 if (cb_err != k_ra8_ok) {
293 return ra8_usb_control_response(s_state.speed, false);
294 }
295 return ra8_usb_control_response(s_state.speed, true);
296}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_hw_init_failed
Hardware peripheral failed to initialise.
Definition ra8_err.h:290
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
Definition ra8_err.h:180
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Definition ra8_log.h:366
#define ra8_log_error_val(tag, message, value)
RA8 log error val.
Definition ra8_log.h:337
static uint32_t s_state
Native USB controller driver public API (device + host modes).
ra8_err_t ra8_usb_queue_out(ra8_usb_speed_t speed, uint8_t pipe_num, uint8_t *out_buf, uint16_t *inout_len, bool rearm)
Drain an OUT transfer (host -> device) from pipe_num.
@ k_ra8_usb_ep_type_bulk
Bulk transfer.
ra8_err_t ra8_usb_device_init(ra8_usb_speed_t speed)
Bring up a USB controller in device mode.
ra8_err_t ra8_usb_control_response(ra8_usb_speed_t speed, bool accept)
Issue a control-transfer status response on EP0.
ra8_err_t ra8_usb_device_deinit(ra8_usb_speed_t speed)
Tear down a USB controller and drop its MSTP reference.
ra8_err_t ra8_usb_configure_endpoint(ra8_usb_speed_t speed, uint8_t pipe_num, uint8_t ep_addr, ra8_usb_ep_dir_t dir, ra8_usb_ep_type_t type, uint16_t max_packet)
Configure a non-control PIPE for IN or OUT bulk / interrupt / iso transfers.
ra8_err_t ra8_usb_device_attach(ra8_usb_speed_t speed, bool attached)
Raise / drop the D+ pull-up to advertise the device to the host.
@ k_ra8_usb_ep_dir_in
Device -> host.
@ k_ra8_usb_ep_dir_out
Host -> device.
ra8_usb_speed_t
Selects which controller instance the call targets.
@ k_ra8_usb_speed_hs
High-Speed controller (USBHS @ 0x40351000).
@ k_ra8_usb_speed_fs
Full-Speed controller (USBFS @ 0x40250000).
ra8_err_t ra8_usb_queue_in(ra8_usb_speed_t speed, uint8_t pipe_num, const uint8_t *data, uint16_t len)
Queue an IN transfer (device -> host) on pipe_num.
static ra8_err_t internal_configure_pipes(void)
Configure the host-Audio iso pipes against the attached device's endpoints.
static bool internal_is_vendor_envelope(uint8_t bm)
Recognise a vendor-recipient SETUP envelope.
ra8_err_t ra8_usb_pvnd_set_descriptors(const uint8_t *desc, uint16_t desc_len)
Install the caller-supplied descriptor blob.
ra8_err_t ra8_usb_pvnd_recv(uint8_t *buf, uint16_t max_len, uint16_t *got_len)
Drain a payload from the vendor bulk-OUT endpoint.
ra8_err_t ra8_usb_pvnd_handle_setup(const ra8_usb_setup_t *setup)
Process a vendor-specific SETUP packet on EP0.
ra8_err_t ra8_usb_pvnd_init(ra8_usb_speed_t speed)
Bring up the device-Vendor function on a chosen USB controller.
ra8_err_t ra8_usb_pvnd_attach_setup_handler(ra8_usb_pvnd_setup_fn_t setup_fn, void *ctx)
Register the application's vendor setup handler.
static void internal_reset_shadow(ra8_usb_speed_t speed)
Reset shadow state to spec defaults.
ra8_err_t ra8_usb_pvnd_close(void)
Tear down the device-Vendor function and release the controller.
static uint16_t internal_bulk_max_packet(ra8_usb_speed_t speed)
Pick the bulk-max-packet ceiling matching the negotiated speed.
ra8_err_t ra8_usb_pvnd_send(const uint8_t *data, uint16_t len)
Push a payload on the vendor bulk-IN endpoint.
Native USB device-side Vendor-defined class layer.
ra8_err_t(* ra8_usb_pvnd_setup_fn_t)(void *ctx, const ra8_usb_setup_t *setup)
Caller-supplied vendor class-setup handler signature.
@ k_ra8_pvnd_bm_vendor_iface_in
Vendor | Interface | In.
@ k_ra8_pvnd_bm_vendor_ep_out
Vendor | Endpoint | Out.
@ k_ra8_pvnd_bm_vendor_dev_in
Vendor | Device | In.
@ k_ra8_pvnd_bm_vendor_iface_out
Vendor | Interface | Out.
@ k_ra8_pvnd_bm_vendor_dev_out
Vendor | Device | Out.
@ k_ra8_pvnd_bm_vendor_ep_in
Vendor | Endpoint | In.
@ k_ra8_pvnd_pipe_bulk_out
PIPE1 -> EP2 OUT (vendor OUT).
@ k_ra8_pvnd_pipe_bulk_in
PIPE5 -> EP1 IN (vendor IN).
@ k_ra8_pvnd_ep_bulk_in_addr
EP1 IN address.
@ k_ra8_pvnd_ep_bulk_out_addr
EP2 OUT address.
@ k_ra8_pvnd_bulk_max_packet_hs
Bulk size at HS.
@ k_ra8_pvnd_bulk_max_packet_fs
Bulk size at FS.
Singleton shadow state for the device-Vendor function.
ra8_usb_pvnd_setup_fn_t setup_cb
Application class handler.
const uint8_t * desc
Cached descriptor blob.
void * setup_ctx
Class handler context.
uint16_t bulk_max_packet
Pipe max-packet size.
uint16_t desc_len
Descriptor blob byte len.
ra8_usb_speed_t speed
Underlying controller.
bool initialized
True after init.
Decoded 8-byte USB SETUP packet.
uint8_t bm_request_type
Request direction / type / recipient.