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