KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
maple.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 dc/maple.h
4 Copyright (C) 2002 Megan Potter
5 Copyright (C) 2015 Lawrence Sebald
6 Copyright (C) 2026 Ruslan Rostovtsev
7
8 This new driver's design is based loosely on the LinuxDC maple
9 bus driver.
10*/
11
12/** \file dc/maple.h
13 \brief Maple Bus driver interface.
14 \ingroup maple
15
16 This file provides support for accessing the Maple bus on the Dreamcast.
17 Maple is the bus that all of your controllers and memory cards and the like
18 connect to, so this is one of those types of things that are quite important
19 to know how to use.
20
21 Each peripheral device registers their driver within this system, and can be
22 accessed through the functions here. Most of the drivers have their own
23 functionality that is implemented in their header files, as well.
24
25 \bug Sending a rumble (PuruPuru / Jump Pack) command can cause VMUs
26 plugged into any controller to beep. This is a hardware-level side
27 effect and not something KOS can prevent in software.
28
29 \bug Inserting a VMU can cause its parent controller to briefly disconnect
30 and re-enumerate on the Maple bus, producing a detach/attach event for
31 the controller as well as the VMU. This is another hardware-level side
32 effect and not something KOS can prevent in software.
33
34 \author Megan Potter
35 \author Lawrence Sebald
36 \author Ruslan Rostovtsev
37
38 \see dc/maple/controller.h
39 \see dc/maple/dreameye.h
40 \see dc/maple/keyboard.h
41 \see dc/maple/mouse.h
42 \see dc/maple/purupuru.h
43 \see dc/maple/sip.h
44 \see dc/maple/vmu.h
45*/
46
47#ifndef __DC_MAPLE_H
48#define __DC_MAPLE_H
49
50#include <kos/cdefs.h>
51__BEGIN_DECLS
52
53#include <stdbool.h>
54#include <stdint.h>
55#include <sys/queue.h>
56
57/** \defgroup maple Maple Bus
58 \brief Driver for the Dreamcast's Maple Peripheral Bus
59 \ingroup peripherals
60*/
61
62/** \brief Enable Maple DMA debugging.
63 \ingroup maple
64
65 Changing this to a 1 will add massive amounts of processing time to the
66 maple system in general, but it can help in verifying DMA errors. In
67 general, for most purposes this should stay disabled.
68*/
69#define MAPLE_DMA_DEBUG 0
70
71/** \brief Enable Maple IRQ debugging.
72 \ingroup maple
73
74 Changing this to a 1 will turn on intra-interrupt debugging messages, which
75 may cause issues if you're using dcload rather than a raw serial debug
76 terminal. You probably will never have a good reason to enable this, so keep
77 it disabled for normal use.
78*/
79#define MAPLE_IRQ_DEBUG 0
80
81/** \defgroup maple_regs Registers
82 \brief Addresses for various maple registers
83 \ingroup maple
84
85 These are various registers related to the Maple Bus. In general, you
86 probably won't ever need to mess with these directly.
87
88 @{
89*/
90#define MAPLE_BASE 0xa05f6c00 /**< \brief Maple register base */
91#define MAPLE_DMA_ADDR (MAPLE_BASE+0x04) /**< \brief DMA address register */
92#define MAPLE_DMA_TSEL (MAPLE_BASE+0x10) /**< \brief Maple DMA trigger select (bit 0) */
93#define MAPLE_ENABLE (MAPLE_BASE+0x14) /**< \brief Enable register */
94#define MAPLE_STATE (MAPLE_BASE+0x18) /**< \brief Status register */
95#define MAPLE_SPEED (MAPLE_BASE+0x80) /**< \brief Speed register */
96#define MAPLE_DMA_PROT (MAPLE_BASE+0x8c) /**< \brief Allowed DMA buffer address range */
97/** @} */
98
99/** \defgroup maple_reg_values Register Values
100 \brief Values for various maple registers
101 \ingroup maple
102
103 These are the values that are written to registers to get them to do their
104 thing.
105
106 @{
107*/
108#define MAPLE_DMA_TSEL_SOFTWARE 0 /**< \brief DMA initiated by software */
109#define MAPLE_DMA_TSEL_VBLANK 1 /**< \brief DMA initiated at V-Blank */
110#define MAPLE_ENABLE_ENABLED 1 /**< \brief Enable Maple */
111#define MAPLE_ENABLE_DISABLED 0 /**< \brief Disable Maple */
112#define MAPLE_STATE_IDLE 0 /**< \brief Idle state */
113#define MAPLE_STATE_DMA 1 /**< \brief DMA in-progress */
114#define MAPLE_SPEED_1MBPS 0x0100 /**< \brief 1Mbps bus speed */
115#define MAPLE_SPEED_2MBPS 0x0000 /**< \brief 2Mbps bus speed */
116#define MAPLE_SPEED_4MBPS 0x0200 /**< \brief 4Mbps bus speed */
117#define MAPLE_SPEED_8MBPS 0x0300 /**< \brief 8Mbps bus speed */
118#define MAPLE_SPEED_TIMEOUT(n) ((n) << 16) /**< \brief Bus timeout macro */
119
120#define MAPLE_DMA_PROT_MAGIC 0x61550000 /**< \brief Key in bits 31-16; lo/hi bytes set the allowed range */
121
122/** @} */
123
124/** \defgroup maple_cmds Commands and Responses
125 \brief Maple command and response values
126 \ingroup maple
127
128 These are all either commands or responses to commands sent to or from Maple
129 in normal operation.
130
131 @{
132*/
133#define MAPLE_RESPONSE_FILEERR -5 /**< \brief File error */
134#define MAPLE_RESPONSE_AGAIN -4 /**< \brief Try again later */
135#define MAPLE_RESPONSE_BADCMD -3 /**< \brief Bad command sent */
136#define MAPLE_RESPONSE_BADFUNC -2 /**< \brief Bad function code */
137#define MAPLE_RESPONSE_NONE -1 /**< \brief No response */
138#define MAPLE_COMMAND_DEVINFO 1 /**< \brief Device info request */
139#define MAPLE_COMMAND_ALLINFO 2 /**< \brief All info request */
140#define MAPLE_COMMAND_RESET 3 /**< \brief Reset device request */
141#define MAPLE_COMMAND_KILL 4 /**< \brief Kill device request */
142#define MAPLE_RESPONSE_DEVINFO 5 /**< \brief Device info response */
143#define MAPLE_RESPONSE_ALLINFO 6 /**< \brief All info response */
144#define MAPLE_RESPONSE_OK 7 /**< \brief Command completed ok */
145#define MAPLE_RESPONSE_DATATRF 8 /**< \brief Data transfer */
146#define MAPLE_COMMAND_GETCOND 9 /**< \brief Get condition request */
147#define MAPLE_COMMAND_GETMINFO 10 /**< \brief Get memory information */
148#define MAPLE_COMMAND_BREAD 11 /**< \brief Block read */
149#define MAPLE_COMMAND_BWRITE 12 /**< \brief Block write */
150#define MAPLE_COMMAND_BSYNC 13 /**< \brief Block sync */
151#define MAPLE_COMMAND_SETCOND 14 /**< \brief Set condition request */
152#define MAPLE_COMMAND_MICCONTROL 15 /**< \brief Microphone control */
153#define MAPLE_COMMAND_CAMCONTROL 17 /**< \brief Camera control */
154/** @} */
155
156/** \defgroup maple_functions Function Codes
157 \brief Values of maple "function" codes
158 \ingroup maple
159
160 This is the list of maple device types (function codes). Each device must
161 have at least one function to actually do anything.
162
163 @{
164*/
165
166/* Function codes; most sources claim that these numbers are little
167 endian, and for all I know, they might be; but since it's a bitmask
168 it doesn't really make much different. We'll just reverse our constants
169 from the "big-endian" version. */
170#define MAPLE_FUNC_PURUPURU 0x00010000 /**< \brief Jump pack */
171#define MAPLE_FUNC_MOUSE 0x00020000 /**< \brief Mouse */
172#define MAPLE_FUNC_CAMERA 0x00080000 /**< \brief Camera (Dreameye) */
173#define MAPLE_FUNC_CONTROLLER 0x01000000 /**< \brief Controller */
174#define MAPLE_FUNC_MEMCARD 0x02000000 /**< \brief Memory card */
175#define MAPLE_FUNC_LCD 0x04000000 /**< \brief LCD screen */
176#define MAPLE_FUNC_CLOCK 0x08000000 /**< \brief Clock */
177#define MAPLE_FUNC_MICROPHONE 0x10000000 /**< \brief Microphone */
178#define MAPLE_FUNC_ARGUN 0x20000000 /**< \brief AR gun? */
179#define MAPLE_FUNC_KEYBOARD 0x40000000 /**< \brief Keyboard */
180#define MAPLE_FUNC_LIGHTGUN 0x80000000 /**< \brief Lightgun */
181#define MAPLE_FUNC_MIE 0x00000001 /**< \brief Naomi MIE/JVS bridge */
182#define MAPLE_FUNC_ANY 0xffffffff /**< \brief Match/request any */
183/** @} */
184
185/* \cond */
186/* Pre-define list/queue types */
187struct maple_frame;
188TAILQ_HEAD(maple_frame_queue, maple_frame);
189
190struct maple_driver;
191LIST_HEAD(maple_driver_list, maple_driver);
192
193struct maple_state_str;
194/* \endcond */
195
196/** \brief Maple frame to be queued for transport.
197 \ingroup maple
198
199 Internal representation of a frame to be queued up for sending.
200
201 \headerfile dc/maple.h
202*/
203typedef struct maple_frame {
204 /** \brief Send queue handle. NOT A FUNCTION! */
205 TAILQ_ENTRY(maple_frame) frameq;
206
207 int cmd; /**< \brief Command (see \ref maple_cmds) */
208 int dst_port; /**< \brief Destination port */
209 int dst_unit; /**< \brief Destination unit */
210 int length; /**< \brief Data transfer length in 32-bit words */
211 volatile int state; /**< \brief Has this frame been sent / responded to? */
212 volatile int queued; /**< \brief Are we on the queue? */
213
214 uint32_t *send_buf; /**< \brief The data which will be sent (if any) */
215 uint8_t *recv_buf; /**< \brief Points into recv_buf_arr, but 32-byte aligned */
216
217 struct maple_device *dev; /**< \brief Does this belong to a device? */
218
219 void (*callback)(struct maple_state_str *, struct maple_frame *); /**< \brief Response callback */
220
221#if MAPLE_DMA_DEBUG
222 uint8_t recv_buf_arr[1024 + 1024 + 32]; /**< \brief Response receive area */
223#else
224 uint8_t recv_buf_arr[1024 + 32]; /**< \brief Response receive area */
225#endif
227
228/** \defgroup maple_frame_states Frame States
229 \brief States for a maple frame
230 \ingroup maple
231 @{
232*/
233#define MAPLE_FRAME_VACANT 0 /**< \brief Ready to be used */
234#define MAPLE_FRAME_UNSENT 1 /**< \brief Ready to be sent */
235#define MAPLE_FRAME_SENT 2 /**< \brief Frame has been sent, but no response yet */
236#define MAPLE_FRAME_RESPONDED 3 /**< \brief Frame has a response */
237/** @} */
238
239/** \brief Maple device info structure.
240 \ingroup maple
241
242 This structure is used by the hardware to deliver the response to the device
243 info request.
244
245 \note product_name and product_license are not guaranteed to be NUL terminated.
246
247 \headerfile dc/maple.h
248*/
249typedef struct maple_devinfo {
250 uint32_t functions; /**< \brief Function codes supported */
251 uint32_t function_data[3]; /**< \brief Additional data per function */
252 uint8_t area_code; /**< \brief Region code */
253 uint8_t connector_direction; /**< \brief 0: UP (most controllers), 1: DOWN (lightgun, microphones) */
254 char product_name[30] __attribute__ ((nonstring)); /**< \brief Name of device */
255 char product_license[60] __attribute__ ((nonstring)); /**< \brief License statement */
256 uint16_t standby_power; /**< \brief Power consumption (standby) */
257 uint16_t max_power; /**< \brief Power consumption (max) */
259
260/** \brief Maple response frame structure.
261 \ingroup maple
262
263 This structure is used to deliver the actual response to a request placed.
264 The data field is where all the interesting stuff will be.
265
266 \headerfile dc/maple.h
267*/
268typedef struct maple_response {
269 int8_t response; /**< \brief Response */
270 uint8_t dst_addr; /**< \brief Destination address */
271 uint8_t src_addr; /**< \brief Source address */
272 uint8_t data_len; /**< \brief Data length (in 32-bit words) */
273 uint8_t data[]; /**< \brief Data (if any) */
275
276/* \cond */
277/* Number of failed autodetects before detaching a device. */
278#define MAPLE_DEV_VALID_TIMEOUT 30
279/* \endcond */
280
281/** \brief One maple device.
282 \ingroup maple
283
284 Note that we duplicate the port/unit info which is normally somewhat
285 implicit so that we can pass around a pointer to a particular device struct.
286
287 \headerfile dc/maple.h
288*/
289typedef struct maple_device {
290 /* Public */
291 uint8_t valid; /**< \brief Is this a valid device? 0 for no */
292 int port; /**< \brief Maple bus port connected to */
293 int unit; /**< \brief Unit number, off of the port */
294 maple_devinfo_t info; /**< \brief Device info struct */
295
296 /* Private */
297 maple_frame_t frame; /**< \brief One rx/tx frame */
298 struct maple_driver *drv; /**< \brief Driver which handles this device */
299
300 uint8_t probe_mask; /**< \brief Mask of sub-devices left to probe */
301 uint8_t dev_mask; /**< \brief Device-present mask for unit 0's */
302
303 void *status; /**< \brief Status buffer (for pollable devices) */
305
306#define MAPLE_PORT_COUNT 4 /**< \brief Number of ports on the bus */
307#define MAPLE_UNIT_COUNT 6 /**< \brief Max number of units per port */
308
309/** \brief Internal representation of a Maple port.
310 \ingroup maple
311
312 Each maple port can contain up to 6 devices, the first one of which is
313 always the port itself.
314
315 \headerfile dc/maple.h
316*/
317typedef struct maple_port {
318 int port; /**< \brief Port ID */
319 maple_device_t *units[MAPLE_UNIT_COUNT]; /**< \brief Pointers to active units */
321
322/** \brief Maple user callback type.
323 \ingroup maple
324
325 Functions of this type can be set with maple_{attach,detach}_callback()
326 to respond automatically to those events.
327
328 \param dev The device that triggered the callback.
329*/
330typedef void (*maple_user_callback_t)(maple_device_t *dev, void *user_data);
331
332/* \cond */
333/* Compat */
334#define maple_attach_callback_t __depr("Use the type maple_user_callback_t rather than maple_attach_callback_t.") maple_user_callback_t
335#define maple_detach_callback_t __depr("Use the type maple_user_callback_t rather than maple_detach_callback_t.") maple_user_callback_t
336/* \endcond */
337
338/** \brief A maple device driver.
339 \ingroup maple
340
341 Anything which is added to this list is capable of handling one or more
342 maple device types. When a device of the given type is connected (includes
343 startup "connection"), the driver is invoked. This same process happens for
344 disconnection, response receipt, and on a periodic interval (for normal
345 updates).
346
347 \headerfile dc/maple.h
348*/
349typedef struct maple_driver {
350 /** \brief Driver list handle. NOT A FUNCTION! */
351 LIST_ENTRY(maple_driver) drv_list;
352
353 uint32_t functions; /**< \brief One or more MAPLE_FUNCs ORed together */
354 const char *name; /**< \brief The driver name */
355
356 size_t status_size;/**< \brief The size of the status buffer */
357
358 /* Callbacks, to be filled in by the driver */
359
360 /** \brief Periodic polling callback.
361
362 This callback will be called to update the status of connected devices
363 periodically.
364
365 \param drv This structure for the driver.
366 */
367 void (*periodic)(struct maple_driver *drv);
368
369 /** \brief Device attached callback.
370
371 This callback will be called when a new device of this driver is
372 connected to the system.
373
374 \param drv This structure for the driver.
375 \param dev The device that was connected.
376 \return 0 on success, <0 on error.
377 */
378 int (*attach)(struct maple_driver *drv, maple_device_t *dev);
379
380 /** \brief Device detached callback.
381
382 This callback will be called when a device of this driver is disconnected
383 from the system.
384
385 \param drv This structure for the driver.
386 \param dev The device that was detached.
387 */
388 void (*detach)(struct maple_driver *drv, maple_device_t *dev);
389
390 /** \brief User-specified device attached callback.
391
392 This callback will be called when a new device of this driver is
393 connected to the system. It should be set by applications using
394 maple_attach_callback().
395 */
397
398 /** \brief User-specified device attached callback data.
399
400 This data will be passed to user_attach when called.
401 */
403
404 /** \brief User-specified device detached callback.
405
406 This callback will be called when a device using this driver is
407 disconnected from the system. It should be set by applications using
408 maple_detach_callback().
409 */
411
412 /** \brief User-specified device detached callback data.
413
414 This data will be passed to user_detach when called.
415 */
418
419/** \brief Maple state structure.
420 \ingroup maple
421
422 We put everything in here to keep from polluting the global namespace too
423 much.
424
425 \headerfile dc/maple.h
426*/
427typedef struct maple_state_str {
428 /** \brief Maple device driver list. Do not manipulate directly! */
429 struct maple_driver_list driver_list;
430
431 /** \brief Maple frame submission queue. Do not manipulate directly! */
432 struct maple_frame_queue frame_queue;
433
434 /** \brief Maple device info structure */
436
437 /** \brief DMA interrupt counter */
438 volatile int dma_cntr;
439
440 /** \brief VBlank interrupt counter */
441 volatile int vbl_cntr;
442
443 /** \brief DMA send buffer */
444 uint8_t *dma_buffer;
445
446 /** \brief Is a DMA running now? */
447 volatile int dma_in_progress;
448
449 /** \brief Next port that will be auto-detected */
451
452 /** \brief Mask of ports that completed the initial scan */
453 volatile uint8_t scan_ready_mask;
454
455 /** \brief Port A is MIE (skip autodetect on port 0). */
456 uint8_t port0_mie;
457
458 /** \brief Our vblank handler handle */
460
461 /** \brief The port to read for lightgun status, if any. */
463
464 /** \brief The horizontal position of the lightgun signal. */
465 int gun_x;
466
467 /** \brief The vertical position of the lightgun signal. */
468 int gun_y;
470
471/** \brief Maple DMA buffer size.
472 \ingroup maple
473
474 Increase if you do a _LOT_ of maple stuff on every periodic interrupt.
475*/
476#define MAPLE_DMA_SIZE 16384
477
478/* Maple memory read/write functions; these are just hooks in case
479 we need to do something else later */
480/** \brief Maple memory read macro.
481 \ingroup maple
482 */
483#define maple_read(A) ( *((volatile uint32_t*)(A)) )
484
485/** \brief Maple memory write macro.
486 \ingroup maple
487 */
488#define maple_write(A, V) ( *((volatile uint32_t*)(A)) = (V) )
489
490/** \defgroup maple_func_rvs Return Values
491 \brief Return codes from maple access functions
492 \ingroup maple
493 @{
494*/
495#define MAPLE_EOK 0 /**< \brief No error */
496#define MAPLE_EFAIL -1 /**< \brief Command failed */
497#define MAPLE_EAGAIN -2 /**< \brief Try again later */
498#define MAPLE_EINVALID -3 /**< \brief Invalid command */
499#define MAPLE_ENOTSUPP -4 /**< \brief Command not supported by device */
500#define MAPLE_ETIMEOUT -5 /**< \brief Command timed out */
501/** @} */
502
503/**************************************************************************/
504/* maple_globals.c */
505
506/** \cond Global state info.
507
508 Do not manipulate this state yourself, as it will likely break things if you
509 do so.
510*/
511extern maple_state_t maple_state;
512/** \endcond */
513
514/**************************************************************************/
515/* maple_utils.c */
516
517/** \brief Enable the Maple bus.
518 \ingroup maple
519
520 This will be done for you automatically at init time, and there's probably
521 not many reasons to be doing this during runtime.
522*/
524
525/** \brief Disable the Maple bus.
526 \ingroup maple
527
528 There's really not many good reasons to be mucking with this at runtime.
529*/
531
532/** \brief Start a Maple DMA.
533 \ingroup maple
534
535 This stuff will all be handled internally, so there's probably no reason to
536 be doing this yourself.
537*/
539
540/** \brief Stop a Maple DMA.
541 \ingroup maple
542
543 This stuff will all be handled internally, so there's probably no reason to
544 be doing this yourself.
545*/
546void maple_dma_stop(void);
547
548/** \brief Is a Maple DMA in progress?
549 \ingroup maple
550
551 \return Non-zero if a DMA is in progress.
552*/
554
555/** \brief Set the Maple DMA address.
556 \ingroup maple
557
558 Once again, you should not muck around with this in your programs.
559*/
560void maple_dma_addr(void *ptr);
561
562/** \brief Return a "maple address" for a port, unit pair.
563 \ingroup maple
564
565 \param port The port to build the address for.
566 \param unit The unit to build the address for.
567 \return The Maple address of the pair.
568*/
569uint8_t maple_addr(int port, int unit);
570
571/** \brief Decompose a "maple address" into a port, unit pair.
572 \ingroup maple
573
574 \warning
575 This function will not work with multi-cast addresses!
576
577 \param addr The input address.
578 \param port Output space for the port of the address.
579 \param unit Output space for the unit of the address.
580*/
581void maple_raddr(uint8_t addr, int *port, int *unit);
582
583/** \brief Return a string with the capabilities of a given function code.
584 \ingroup maple
585
586 This function is not re-entrant, and thus NOT THREAD SAFE.
587
588 \param functions The list of function codes.
589 \return A string containing the capabilities.
590*/
591const char *maple_pcaps(uint32_t functions);
592
593/** \brief Return a string representing the maple response code.
594 \ingroup maple
595
596 \param response The response code returned from the function.
597 \return A string containing a textual representation of the
598 response code.
599*/
600const char *maple_perror(int response);
601
602/** \brief Determine if a given device is valid.
603 \ingroup maple
604
605 \param p The port to check.
606 \param u The unit to check.
607 \return Non-zero if the device is valid.
608*/
609int maple_dev_valid(int p, int u);
610
611/** \brief Enable light gun mode for this frame.
612 \ingroup maple
613
614 This function enables light gun processing for the current frame of data.
615 Light gun mode will automatically be disabled when the data comes back for
616 this frame.
617
618 \param port The port to enable light gun mode on.
619 \return MAPLE_EOK on success, MAPLE_EFAIL on error.
620*/
621int maple_gun_enable(int port);
622
623/** \brief Disable light gun mode.
624 \ingroup maple
625
626 There is probably very little reason to call this function. Light gun mode
627 is ordinarily disabled and is automatically disabled after the data has been
628 read from the device. The only reason to call this function is if you call
629 the maple_gun_enable() function, and then change your mind during the same
630 frame.
631*/
633
634/** \brief Read the light gun position values.
635 \ingroup maple
636
637 This function fetches the gun position values from the video hardware and
638 returns them via the parameters. These values are not normalized before
639 returning.
640
641 \param x Storage for the horizontal position of the gun.
642 \param y Storage for the vertical position of the gun.
643
644 \note The values returned from this function are the raw H and V counter
645 values from the video hardware where the gun registered its
646 position. The values, however, need a bit of massaging before they
647 correspond nicely to screen values. The y value is particularly odd
648 in interlaced modes due to the fact that you really have half as
649 many physical lines on the screen as you might expect.
650*/
651void maple_gun_read_pos(int *x, int *y);
652
653/* Debugging help */
654
655/** \brief Setup a sentinel for debugging DMA issues.
656 \ingroup maple
657
658 \param buffer The buffer to add the sentinel to.
659 \param bufsize The size of the data in the buffer.
660*/
661void maple_sentinel_setup(void *buffer, int bufsize);
662
663/** \brief Verify the presence of the sentine.
664 \ingroup maple
665
666 \param bufname A string to recognize the buffer by.
667 \param buffer The buffer to check.
668 \param bufsize The size of the buffer.
669*/
670void maple_sentinel_verify(const char *bufname, void *buffer, int bufsize);
671
672/**************************************************************************/
673/* maple_queue.c */
674
675/** \brief Send all queued frames.
676 \ingroup maple
677 */
679
680/** \brief Submit a frame for queueing.
681 \ingroup maple
682
683 This will generally be called inside the periodic interrupt; however, if you
684 need to do something asynchronously (e.g., VMU access) then it might cause
685 some problems. In this case, the function will automatically do locking by
686 disabling interrupts temporarily. In any case, the callback will be done
687 inside an IRQ context.
688
689 \param frame The frame to queue up.
690 \retval 0 On success.
691 \retval -1 If the frame is already queued.
692*/
694
695/** \brief Remove a used frame from the queue.
696 \ingroup maple
697
698 This will be done automatically when the frame is consumed.
699
700 \param frame The frame to remove from the queue.
701 \retval 0 On success.
702 \retval -1 If the frame is not queued.
703*/
705
706/** \brief Initialize a new frame to prepare it to be placed on the queue.
707 \ingroup maple
708
709 You should call this before you fill in the frame data.
710
711 \param frame The frame to initialize.
712*/
714
715/** \brief Try to lock a frame so that someone else can't use it in the
716 mean time.
717 \ingroup maple
718
719 \retval 0 On success.
720 \retval -1 If the frame is already locked.
721*/
723
724/** \brief Lock a frame so that someone else can't use it in the mean time.
725 This function is not safe to use in interrupt context.
726 \ingroup maple
727
728 \retval 0 On success. No error code defined.
729*/
731
732/** \brief Unlock a frame.
733 \ingroup maple
734 */
736
737/**************************************************************************/
738/* maple_driver.c */
739
740/** \brief Register a maple device driver.
741 \ingroup maple
742
743 This should be done before calling maple_init().
744
745 \retval 0 On success (no error conditions defined).
746*/
748
749/** \brief Unregister a maple device driver.
750 \ingroup maple
751
752 \retval 0 On success (no error conditions defined).
753*/
755
756/** \brief Attach a maple device to a driver, if possible.
757 \ingroup maple
758
759 \param det The detection frame.
760 \retval 1 Couldn't allocate buffers.
761 \retval 0 On success.
762 \retval -1 If no driver is available.
763*/
765
766/** \brief Detach an attached maple device.
767 \ingroup maple
768
769 \param p The port of the device to detach.
770 \param u The unit of the device to detach.
771 \retval 0 On success.
772 \retval -1 If the device wasn't valid.
773*/
774int maple_driver_detach(int p, int u);
775
776/** \brief For each device which the given driver controls, call the callback.
777 \ingroup maple
778
779 \param drv The driver to loop through devices of.
780 \param callback The function to call. The parameter is the device
781 that it is being called on. It should return 0 on
782 success, and <0 on failure.
783 \retval 0 On success.
784 \retval -1 If any callbacks return <0.
785*/
787
788/** \brief Set an automatic maple attach callback.
789 \ingroup maple
790
791 This function sets a callback function to be called when the specified
792 maple device that supports functions has been attached.
793
794 \note
795 Your function will not be called for devices which have already been
796 detected on the maple bus. This is only for newly detected devices.
797
798 \warning
799 \p cb will be invoked from within an IRQ context! Do not perform any logic
800 which requires additional interrupt processing!
801
802 \param functions The functions maple device must support. Set to
803 0 or MAPLE_FUNC_ANY to support all maple devices.
804 \param cb The callback to call when the maple is attached.
805 \param user_data User data to be passed to cb when called.
806*/
807void maple_attach_callback(uint32_t functions, maple_user_callback_t cb, void *user_data);
808
809/** \brief Set an automatic maple detach callback.
810 \ingroup maple
811
812 This function sets a callback function to be called when the specified
813 maple device that supports functions has been detached.
814
815 \param functions The functions maple device must support. Set to
816 0 or MAPLE_FUNC_ANY to support all maple devices.
817 \param cb The callback to call when the maple is detached.
818 \param user_data User data to be passed to cb when called.
819*/
820void maple_detach_callback(uint32_t functions, maple_user_callback_t cb, void *user_data);
821
822/**************************************************************************/
823/* maple_irq.c */
824
825/** \brief Called on every VBL (~60fps).
826 \ingroup maple
827
828 \param code The ASIC event code.
829 \param data The user pointer associated with this callback.
830*/
831void maple_vbl_irq_hnd(uint32_t code, void *data);
832
833/** \brief Called after a Maple DMA send / receive pair completes.
834 \ingroup maple
835
836 \param code The ASIC event code.
837 \param data The user pointer associated with this callback.
838*/
839void maple_dma_irq_hnd(uint32_t code, void *data);
840
841/**************************************************************************/
842/* maple_enum.c */
843
844/** \brief Return the number of connected devices.
845 \ingroup maple
846
847 \return The number of devices connected.
848*/
850
851/** \brief Get a raw device info struct for the given device.
852 \ingroup maple
853
854 \param p The port to look up.
855 \param u The unit to look up.
856 \return The device at that address, or NULL if no device is
857 there.
858*/
860
861/** \brief Get the Nth device of the requested type (where N is zero-indexed).
862 \ingroup maple
863
864 \param n The index to look up.
865 \param func The function code to look for.
866 \return The device found, if any. NULL otherwise.
867*/
868maple_device_t *maple_enum_type(int n, uint32_t func);
869
870/** \brief Return the Nth device that is of the requested type and supports the
871 list of capabilities given.
872 \ingroup maple
873
874 Note, this only currently makes sense for controllers, since some devices
875 don't necessarily use the function data in the same manner that controllers
876 do (and controllers are the only devices where we have a list of what all
877 the bits mean at the moment).
878
879 \param n The index to look up.
880 \param func The function code to look for.
881 \param cap Capabilities bits to look for.
882 \return The device found, if any. NULL otherwise.
883*/
884maple_device_t *maple_enum_type_ex(int n, uint32_t func, uint32_t cap);
885
886/** \brief Get the status struct for the requested maple device.
887 \ingroup maple
888
889 This function will wait until the status is valid before returning.
890 You should cast to the appropriate type you're expecting.
891
892 \param dev The device to look up.
893 \return The device's status.
894*/
896
897/**************************************************************************/
898/* maple_init.c */
899
900/** \brief Initialize Maple.
901 \ingroup maple
902 */
903void maple_init(void);
904
905/** \brief Shutdown Maple.
906 \ingroup maple
907 */
908void maple_shutdown(void);
909
910/** \brief Wait for the initial bus scan to complete.
911 \ingroup maple
912 */
914
915/**************************************************************************/
916/* Convenience macros */
917
918/* A "foreach" loop to scan all maple devices of a given type. It is used
919 like this:
920
921 MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)
922 if(st->buttons & CONT_START)
923 return -1;
924 MAPLE_FOREACH_END()
925
926 The peripheral index can be obtained with __i, and the raw device struct
927 with __dev. The code inside the loop is guaranteed to be inside a block
928 (i.e., { code })
929 */
930
931/** \brief Begin a foreach loop over Maple devices.
932 \ingroup maple
933
934 This macro (along with the MAPLE_FOREACH_END() one) implements a simple
935 foreach-style loop over the given type of devices. Essentially, it grabs the
936 status of the device, and leaves it to you to figure out what to do with it.
937
938 The most common use of this would be to look for input on any controller.
939
940 \param TYPE The function code of devices to look at.
941 \param VARTYPE The type to cast the return value of
942 maple_dev_status() to.
943 \param VAR The name of the result of maple_dev_status().
944*/
945#define MAPLE_FOREACH_BEGIN(TYPE, VARTYPE, VAR) \
946 do { \
947 maple_device_t *__dev; \
948 VARTYPE * VAR; \
949 int __i = 0; \
950 \
951 while( (__dev = maple_enum_type(__i, TYPE)) ) { \
952 VAR = (VARTYPE *)maple_dev_status(__dev); \
953 do {
954
955/** \brief End a foreach loop over Maple devices.
956 \ingroup maple
957
958 Each MAPLE_FOREACH_BEGIN() must be paired with one of these after the loop
959 body.
960*/
961#define MAPLE_FOREACH_END() \
962 } while(0); \
963 __i++; \
964 } \
965 } while(0);
966
967__END_DECLS
968
969#endif /* __DC_MAPLE_H */
static struct @89 data[BARRIER_COUNT]
Various common macros used throughout the codebase.
int maple_driver_unreg(maple_driver_t *driver)
Unregister a maple device driver.
int maple_driver_attach(maple_frame_t *det)
Attach a maple device to a driver, if possible.
void maple_detach_callback(uint32_t functions, maple_user_callback_t cb, void *user_data)
Set an automatic maple detach callback.
int maple_gun_enable(int port)
Enable light gun mode for this frame.
void maple_dma_start(void)
Start a Maple DMA.
void maple_dma_addr(void *ptr)
Set the Maple DMA address.
void maple_gun_read_pos(int *x, int *y)
Read the light gun position values.
maple_device_t * maple_enum_type(int n, uint32_t func)
Get the Nth device of the requested type (where N is zero-indexed).
int maple_driver_detach(int p, int u)
Detach an attached maple device.
uint8_t maple_addr(int port, int unit)
Return a "maple address" for a port, unit pair.
const char * maple_perror(int response)
Return a string representing the maple response code.
void maple_wait_scan(void)
Wait for the initial bus scan to complete.
void maple_frame_init(maple_frame_t *frame)
Initialize a new frame to prepare it to be placed on the queue.
void(* maple_user_callback_t)(maple_device_t *dev, void *user_data)
Maple user callback type.
Definition maple.h:330
void maple_shutdown(void)
Shutdown Maple.
int maple_frame_lock(maple_frame_t *frame)
Lock a frame so that someone else can't use it in the mean time.
int maple_frame_trylock(maple_frame_t *frame)
Try to lock a frame so that someone else can't use it in the mean time.
void maple_attach_callback(uint32_t functions, maple_user_callback_t cb, void *user_data)
Set an automatic maple attach callback.
int maple_driver_reg(maple_driver_t *driver)
Register a maple device driver.
int maple_dev_valid(int p, int u)
Determine if a given device is valid.
int maple_enum_count(void)
Return the number of connected devices.
void maple_init(void)
Initialize Maple.
void maple_sentinel_setup(void *buffer, int bufsize)
Setup a sentinel for debugging DMA issues.
maple_device_t * maple_enum_type_ex(int n, uint32_t func, uint32_t cap)
Return the Nth device that is of the requested type and supports the list of capabilities given.
void maple_vbl_irq_hnd(uint32_t code, void *data)
Called on every VBL (~60fps).
void maple_sentinel_verify(const char *bufname, void *buffer, int bufsize)
Verify the presence of the sentine.
void maple_gun_disable(void)
Disable light gun mode.
void maple_bus_disable(void)
Disable the Maple bus.
int maple_queue_frame(maple_frame_t *frame)
Submit a frame for queueing.
const char * maple_pcaps(uint32_t functions)
Return a string with the capabilities of a given function code.
void maple_dma_stop(void)
Stop a Maple DMA.
void maple_frame_unlock(maple_frame_t *frame)
Unlock a frame.
void maple_bus_enable(void)
Enable the Maple bus.
void maple_queue_flush(void)
Send all queued frames.
maple_device_t * maple_enum_dev(int p, int u)
Get a raw device info struct for the given device.
void maple_dma_irq_hnd(uint32_t code, void *data)
Called after a Maple DMA send / receive pair completes.
void maple_raddr(uint8_t addr, int *port, int *unit)
Decompose a "maple address" into a port, unit pair.
int maple_dma_in_progress(void)
Is a Maple DMA in progress?
void * maple_dev_status(maple_device_t *dev)
Get the status struct for the requested maple device.
int maple_driver_foreach(maple_driver_t *drv, int(*callback)(maple_device_t *))
For each device which the given driver controls, call the callback.
int maple_queue_remove(maple_frame_t *frame)
Remove a used frame from the queue.
typedef TAILQ_HEAD(http_state_list, http_state)
Definition httpd.c:24
#define MAPLE_PORT_COUNT
Number of ports on the bus.
Definition maple.h:306
#define MAPLE_UNIT_COUNT
Max number of units per port.
Definition maple.h:307
int y
Definition example.c:183
static char buffer[256]
Definition porthelper.c:11
One maple device.
Definition maple.h:289
void * status
Status buffer (for pollable devices)
Definition maple.h:303
int unit
Unit number, off of the port.
Definition maple.h:293
uint8_t dev_mask
Device-present mask for unit 0's.
Definition maple.h:301
maple_devinfo_t info
Device info struct.
Definition maple.h:294
uint8_t valid
Is this a valid device? 0 for no.
Definition maple.h:291
maple_frame_t frame
One rx/tx frame.
Definition maple.h:297
uint8_t probe_mask
Mask of sub-devices left to probe.
Definition maple.h:300
int port
Maple bus port connected to.
Definition maple.h:292
struct maple_driver * drv
Driver which handles this device.
Definition maple.h:298
Maple device info structure.
Definition maple.h:249
uint32_t functions
Function codes supported.
Definition maple.h:250
uint8_t area_code
Region code.
Definition maple.h:252
uint16_t max_power
Power consumption (max)
Definition maple.h:257
uint8_t connector_direction
0: UP (most controllers), 1: DOWN (lightgun, microphones)
Definition maple.h:253
uint16_t standby_power
Power consumption (standby)
Definition maple.h:256
A maple device driver.
Definition maple.h:349
maple_user_callback_t user_detach
User-specified device detached callback.
Definition maple.h:410
LIST_ENTRY(maple_driver) drv_list
Driver list handle.
const char * name
The driver name.
Definition maple.h:354
uint32_t functions
One or more MAPLE_FUNCs ORed together.
Definition maple.h:353
size_t status_size
The size of the status buffer.
Definition maple.h:356
void * user_detach_data
User-specified device detached callback data.
Definition maple.h:416
void * user_attach_data
User-specified device attached callback data.
Definition maple.h:402
maple_user_callback_t user_attach
User-specified device attached callback.
Definition maple.h:396
Maple frame to be queued for transport.
Definition maple.h:203
uint8_t * recv_buf
Points into recv_buf_arr, but 32-byte aligned.
Definition maple.h:215
uint32_t * send_buf
The data which will be sent (if any)
Definition maple.h:214
volatile int queued
Are we on the queue?
Definition maple.h:212
int cmd
Command (see Commands and Responses)
Definition maple.h:207
int dst_port
Destination port.
Definition maple.h:208
struct maple_device * dev
Does this belong to a device?
Definition maple.h:217
int dst_unit
Destination unit.
Definition maple.h:209
TAILQ_ENTRY(maple_frame) frameq
Send queue handle.
int length
Data transfer length in 32-bit words.
Definition maple.h:210
volatile int state
Has this frame been sent / responded to?
Definition maple.h:211
Internal representation of a Maple port.
Definition maple.h:317
int port
Port ID.
Definition maple.h:318
Maple response frame structure.
Definition maple.h:268
uint8_t data_len
Data length (in 32-bit words)
Definition maple.h:272
int8_t response
Response.
Definition maple.h:269
uint8_t dst_addr
Destination address.
Definition maple.h:270
uint8_t src_addr
Source address.
Definition maple.h:271
Maple state structure.
Definition maple.h:427
volatile int dma_in_progress
Is a DMA running now?
Definition maple.h:447
uint8_t port0_mie
Port A is MIE (skip autodetect on port 0).
Definition maple.h:456
int vbl_handle
Our vblank handler handle.
Definition maple.h:459
volatile int dma_cntr
DMA interrupt counter.
Definition maple.h:438
volatile int vbl_cntr
VBlank interrupt counter.
Definition maple.h:441
int gun_x
The horizontal position of the lightgun signal.
Definition maple.h:465
volatile uint8_t scan_ready_mask
Mask of ports that completed the initial scan.
Definition maple.h:453
int gun_y
The vertical position of the lightgun signal.
Definition maple.h:468
uint8_t detect_port_next
Next port that will be auto-detected.
Definition maple.h:450
uint8_t * dma_buffer
DMA send buffer.
Definition maple.h:444
int gun_port
The port to read for lightgun status, if any.
Definition maple.h:462