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 A maple device driver.
307 \ingroup maple
308
309 Anything which is added to this list is capable of handling one or more
310 maple device types. When a device of the given type is connected (includes
311 startup "connection"), the driver is invoked. This same process happens for
312 disconnection, response receipt, and on a periodic interval (for normal
313 updates).
314
315 \headerfile dc/maple.h
316*/
317typedef struct maple_driver {
318 /** \brief Driver list handle. NOT A FUNCTION! */
319 LIST_ENTRY(maple_driver) drv_list;
320
321 uint32_t functions; /**< \brief One or more MAPLE_FUNCs ORed together */
322 const char *name; /**< \brief The driver name */
323
324 size_t status_size;/**< \brief The size of the status buffer */
325
326 /* Callbacks, to be filled in by the driver */
327
328 /** \brief Periodic polling callback.
329
330 This callback will be called to update the status of connected devices
331 periodically.
332
333 \param drv This structure for the driver.
334 */
335 void (*periodic)(struct maple_driver *drv);
336
337 /** \brief Device attached callback.
338
339 This callback will be called when a new device of this driver is
340 connected to the system.
341
342 \param drv This structure for the driver.
343 \param dev The device that was connected.
344 \return 0 on success, <0 on error.
345 */
346 int (*attach)(struct maple_driver *drv, maple_device_t *dev);
347
348 /** \brief Device detached callback.
349
350 This callback will be called when a device of this driver is disconnected
351 from the system.
352
353 \param drv This structure for the driver.
354 \param dev The device that was detached.
355 */
356 void (*detach)(struct maple_driver *drv, maple_device_t *dev);
357
358 /** \brief User-specified device attached callback.
359
360 This callback will be called when a new device of this driver is
361 connected to the system. It should be set by applications using
362 maple_attach_callback().
363
364 \param dev The device that was connected.
365 \return 0 on success, <0 on error.
366 */
367 void (*user_attach)(maple_device_t *dev);
368
369 /** \brief User-specified device detached callback.
370
371 This callback will be called when a new device of this driver is
372 connected to the system. It should be set by applications using
373 maple_detach_callback().
374
375 \param dev The device that was connected.
376 \return 0 on success, <0 on error.
377 */
378 void (*user_detach)(maple_device_t *dev);
380
381/** \brief Maple state structure.
382 \ingroup maple
383
384 We put everything in here to keep from polluting the global namespace too
385 much.
386
387 \headerfile dc/maple.h
388*/
389typedef struct maple_state_str {
390 /** \brief Maple device driver list. Do not manipulate directly! */
391 struct maple_driver_list driver_list;
392
393 /** \brief Maple frame submission queue. Do not manipulate directly! */
394 struct maple_frame_queue frame_queue;
395
396 /** \brief Maple device info structure */
398
399 /** \brief DMA interrupt counter */
400 volatile int dma_cntr;
401
402 /** \brief VBlank interrupt counter */
403 volatile int vbl_cntr;
404
405 /** \brief DMA send buffer */
406 uint8_t *dma_buffer;
407
408 /** \brief Is a DMA running now? */
409 volatile int dma_in_progress;
410
411 /** \brief Next port that will be auto-detected */
413
414 /** \brief Mask of ports that completed the initial scan */
415 volatile uint8_t scan_ready_mask;
416
417 /** \brief Our vblank handler handle */
419
420 /** \brief The port to read for lightgun status, if any. */
422
423 /** \brief The horizontal position of the lightgun signal. */
424 int gun_x;
425
426 /** \brief The vertical position of the lightgun signal. */
427 int gun_y;
429
430/** \brief Maple DMA buffer size.
431 \ingroup maple
432
433 Increase if you do a _LOT_ of maple stuff on every periodic interrupt.
434*/
435#define MAPLE_DMA_SIZE 16384
436
437/* Maple memory read/write functions; these are just hooks in case
438 we need to do something else later */
439/** \brief Maple memory read macro.
440 \ingroup maple
441 */
442#define maple_read(A) ( *((volatile uint32_t*)(A)) )
443
444/** \brief Maple memory write macro.
445 \ingroup maple
446 */
447#define maple_write(A, V) ( *((volatile uint32_t*)(A)) = (V) )
448
449/** \defgroup maple_func_rvs Return Values
450 \brief Return codes from maple access functions
451 \ingroup maple
452 @{
453*/
454#define MAPLE_EOK 0 /**< \brief No error */
455#define MAPLE_EFAIL -1 /**< \brief Command failed */
456#define MAPLE_EAGAIN -2 /**< \brief Try again later */
457#define MAPLE_EINVALID -3 /**< \brief Invalid command */
458#define MAPLE_ENOTSUPP -4 /**< \brief Command not supported by device */
459#define MAPLE_ETIMEOUT -5 /**< \brief Command timed out */
460/** @} */
461
462/**************************************************************************/
463/* maple_globals.c */
464
465/** \cond Global state info.
466
467 Do not manipulate this state yourself, as it will likely break things if you
468 do so.
469*/
470extern maple_state_t maple_state;
471/** \endcond */
472
473/**************************************************************************/
474/* maple_utils.c */
475
476/** \brief Enable the Maple bus.
477 \ingroup maple
478
479 This will be done for you automatically at init time, and there's probably
480 not many reasons to be doing this during runtime.
481*/
483
484/** \brief Disable the Maple bus.
485 \ingroup maple
486
487 There's really not many good reasons to be mucking with this at runtime.
488*/
490
491/** \brief Start a Maple DMA.
492 \ingroup maple
493
494 This stuff will all be handled internally, so there's probably no reason to
495 be doing this yourself.
496*/
498
499/** \brief Stop a Maple DMA.
500 \ingroup maple
501
502 This stuff will all be handled internally, so there's probably no reason to
503 be doing this yourself.
504*/
505void maple_dma_stop(void);
506
507/** \brief Is a Maple DMA in progress?
508 \ingroup maple
509
510 \return Non-zero if a DMA is in progress.
511*/
513
514/** \brief Set the Maple DMA address.
515 \ingroup maple
516
517 Once again, you should not muck around with this in your programs.
518*/
519void maple_dma_addr(void *ptr);
520
521/** \brief Return a "maple address" for a port, unit pair.
522 \ingroup maple
523
524 \param port The port to build the address for.
525 \param unit The unit to build the address for.
526 \return The Maple address of the pair.
527*/
528uint8_t maple_addr(int port, int unit);
529
530/** \brief Decompose a "maple address" into a port, unit pair.
531 \ingroup maple
532
533 \warning
534 This function will not work with multi-cast addresses!
535
536 \param addr The input address.
537 \param port Output space for the port of the address.
538 \param unit Output space for the unit of the address.
539*/
540void maple_raddr(uint8_t addr, int * port, int * unit);
541
542/** \brief Return a string with the capabilities of a given function code.
543 \ingroup maple
544
545 This function is not re-entrant, and thus NOT THREAD SAFE.
546
547 \param functions The list of function codes.
548 \return A string containing the capabilities.
549*/
550const char * maple_pcaps(uint32_t functions);
551
552/** \brief Return a string representing the maple response code.
553 \ingroup maple
554
555 \param response The response code returned from the function.
556 \return A string containing a textual representation of the
557 response code.
558*/
559const char * maple_perror(int response);
560
561/** \brief Determine if a given device is valid.
562 \ingroup maple
563
564 \param p The port to check.
565 \param u The unit to check.
566 \return Non-zero if the device is valid.
567*/
568int maple_dev_valid(int p, int u);
569
570/** \brief Enable light gun mode for this frame.
571 \ingroup maple
572
573 This function enables light gun processing for the current frame of data.
574 Light gun mode will automatically be disabled when the data comes back for
575 this frame.
576
577 \param port The port to enable light gun mode on.
578 \return MAPLE_EOK on success, MAPLE_EFAIL on error.
579*/
580int maple_gun_enable(int port);
581
582/** \brief Disable light gun mode.
583 \ingroup maple
584
585 There is probably very little reason to call this function. Light gun mode
586 is ordinarily disabled and is automatically disabled after the data has been
587 read from the device. The only reason to call this function is if you call
588 the maple_gun_enable() function, and then change your mind during the same
589 frame.
590*/
592
593/** \brief Read the light gun position values.
594 \ingroup maple
595
596 This function fetches the gun position values from the video hardware and
597 returns them via the parameters. These values are not normalized before
598 returning.
599
600 \param x Storage for the horizontal position of the gun.
601 \param y Storage for the vertical position of the gun.
602
603 \note The values returned from this function are the raw H and V counter
604 values from the video hardware where the gun registered its
605 position. The values, however, need a bit of massaging before they
606 correspond nicely to screen values. The y value is particularly odd
607 in interlaced modes due to the fact that you really have half as
608 many physical lines on the screen as you might expect.
609*/
610void maple_gun_read_pos(int *x, int *y);
611
612/* Debugging help */
613
614/** \brief Setup a sentinel for debugging DMA issues.
615 \ingroup maple
616
617 \param buffer The buffer to add the sentinel to.
618 \param bufsize The size of the data in the buffer.
619*/
620void maple_sentinel_setup(void * buffer, int bufsize);
621
622/** \brief Verify the presence of the sentine.
623 \ingroup maple
624
625 \param bufname A string to recognize the buffer by.
626 \param buffer The buffer to check.
627 \param bufsize The size of the buffer.
628*/
629void maple_sentinel_verify(const char * bufname, void * buffer, int bufsize);
630
631/**************************************************************************/
632/* maple_queue.c */
633
634/** \brief Send all queued frames.
635 \ingroup maple
636 */
638
639/** \brief Submit a frame for queueing.
640 \ingroup maple
641
642 This will generally be called inside the periodic interrupt; however, if you
643 need to do something asynchronously (e.g., VMU access) then it might cause
644 some problems. In this case, the function will automatically do locking by
645 disabling interrupts temporarily. In any case, the callback will be done
646 inside an IRQ context.
647
648 \param frame The frame to queue up.
649 \retval 0 On success.
650 \retval -1 If the frame is already queued.
651*/
653
654/** \brief Remove a used frame from the queue.
655 \ingroup maple
656
657 This will be done automatically when the frame is consumed.
658
659 \param frame The frame to remove from the queue.
660 \retval 0 On success.
661 \retval -1 If the frame is not queued.
662*/
664
665/** \brief Initialize a new frame to prepare it to be placed on the queue.
666 \ingroup maple
667
668 You should call this before you fill in the frame data.
669
670 \param frame The frame to initialize.
671*/
673
674/** \brief Try to lock a frame so that someone else can't use it in the
675 mean time.
676 \ingroup maple
677
678 \retval 0 On success.
679 \retval -1 If the frame is already locked.
680*/
682
683/** \brief Lock a frame so that someone else can't use it in the mean time.
684 This function is not safe to use in interrupt context.
685 \ingroup maple
686
687 \retval 0 On success. No error code defined.
688*/
690
691/** \brief Unlock a frame.
692 \ingroup maple
693 */
695
696/**************************************************************************/
697/* maple_driver.c */
698
699/** \brief Register a maple device driver.
700 \ingroup maple
701
702 This should be done before calling maple_init().
703
704 \retval 0 On success (no error conditions defined).
705*/
707
708/** \brief Unregister a maple device driver.
709 \ingroup maple
710
711 \retval 0 On success (no error conditions defined).
712*/
714
715/** \brief Attach a maple device to a driver, if possible.
716 \ingroup maple
717
718 \param det The detection frame.
719 \retval 1 Couldn't allocate buffers.
720 \retval 0 On success.
721 \retval -1 If no driver is available.
722*/
724
725/** \brief Detach an attached maple device.
726 \ingroup maple
727
728 \param p The port of the device to detach.
729 \param u The unit of the device to detach.
730 \retval 0 On success.
731 \retval -1 If the device wasn't valid.
732*/
733int maple_driver_detach(int p, int u);
734
735/** \brief For each device which the given driver controls, call the callback.
736 \ingroup maple
737
738 \param drv The driver to loop through devices of.
739 \param callback The function to call. The parameter is the device
740 that it is being called on. It should return 0 on
741 success, and <0 on failure.
742 \retval 0 On success.
743 \retval -1 If any callbacks return <0.
744*/
746
747/** \brief Maple attach callback type.
748 \ingroup maple
749
750 Functions of this type can be set with maple_attach_callback() to respond
751 automatically to the attachment of a maple device that supports specified
752 functions.
753*/
755
756/** \brief Set an automatic maple attach callback.
757 \ingroup maple
758
759 This function sets a callback function to be called when the specified
760 maple device that supports functions has been attached.
761
762 \param functions The functions maple device must support. Set to
763 0 or MAPLE_FUNC_ANY to support all maple devices.
764 \param cb The callback to call when the maple is attached.
765*/
767
768/** \brief Maple detach callback type.
769 \ingroup maple
770
771 Functions of this type can be set with maple_detach_callback() to respond
772 automatically to the detachment of a maple device that supports specified
773 functions.
774*/
776
777/** \brief Set an automatic maple detach callback.
778 \ingroup maple
779
780 This function sets a callback function to be called when the specified
781 maple device that supports functions has been detached.
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 detached.
786*/
788
789/**************************************************************************/
790/* maple_irq.c */
791
792/** \brief Called on every VBL (~60fps).
793 \ingroup maple
794
795 \param code The ASIC event code.
796 \param data The user pointer associated with this callback.
797*/
798void maple_vbl_irq_hnd(uint32_t code, void *data);
799
800/** \brief Called after a Maple DMA send / receive pair completes.
801 \ingroup maple
802
803 \param code The ASIC event code.
804 \param data The user pointer associated with this callback.
805*/
806void maple_dma_irq_hnd(uint32_t code, void *data);
807
808/**************************************************************************/
809/* maple_enum.c */
810
811/** \brief Return the number of connected devices.
812 \ingroup maple
813
814 \return The number of devices connected.
815*/
817
818/** \brief Get a raw device info struct for the given device.
819 \ingroup maple
820
821 \param p The port to look up.
822 \param u The unit to look up.
823 \return The device at that address, or NULL if no device is
824 there.
825*/
827
828/** \brief Get the Nth device of the requested type (where N is zero-indexed).
829 \ingroup maple
830
831 \param n The index to look up.
832 \param func The function code to look for.
833 \return The device found, if any. NULL otherwise.
834*/
836
837/** \brief Return the Nth device that is of the requested type and supports the
838 list of capabilities given.
839 \ingroup maple
840
841 Note, this only currently makes sense for controllers, since some devices
842 don't necessarily use the function data in the same manner that controllers
843 do (and controllers are the only devices where we have a list of what all
844 the bits mean at the moment).
845
846 \param n The index to look up.
847 \param func The function code to look for.
848 \param cap Capabilities bits to look for.
849 \return The device found, if any. NULL otherwise.
850*/
851maple_device_t *maple_enum_type_ex(int n, uint32_t func, uint32_t cap);
852
853/** \brief Get the status struct for the requested maple device.
854 \ingroup maple
855
856 This function will wait until the status is valid before returning.
857 You should cast to the appropriate type you're expecting.
858
859 \param dev The device to look up.
860 \return The device's status.
861*/
863
864/**************************************************************************/
865/* maple_init.c */
866
867/** \brief Initialize Maple.
868 \ingroup maple
869 */
870void maple_init(void);
871
872/** \brief Shutdown Maple.
873 \ingroup maple
874 */
875void maple_shutdown(void);
876
877/** \brief Wait for the initial bus scan to complete.
878 \ingroup maple
879 */
881
882/**************************************************************************/
883/* Convenience macros */
884
885/* A "foreach" loop to scan all maple devices of a given type. It is used
886 like this:
887
888 MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)
889 if(st->buttons & CONT_START)
890 return -1;
891 MAPLE_FOREACH_END()
892
893 The peripheral index can be obtained with __i, and the raw device struct
894 with __dev. The code inside the loop is guaranteed to be inside a block
895 (i.e., { code })
896 */
897
898/** \brief Begin a foreach loop over Maple devices.
899 \ingroup maple
900
901 This macro (along with the MAPLE_FOREACH_END() one) implements a simple
902 foreach-style loop over the given type of devices. Essentially, it grabs the
903 status of the device, and leaves it to you to figure out what to do with it.
904
905 The most common use of this would be to look for input on any controller.
906
907 \param TYPE The function code of devices to look at.
908 \param VARTYPE The type to cast the return value of
909 maple_dev_status() to.
910 \param VAR The name of the result of maple_dev_status().
911*/
912#define MAPLE_FOREACH_BEGIN(TYPE, VARTYPE, VAR) \
913 do { \
914 maple_device_t * __dev; \
915 VARTYPE * VAR; \
916 int __i; \
917 \
918 __i = 0; \
919 while( (__dev = maple_enum_type(__i, TYPE)) ) { \
920 VAR = (VARTYPE *)maple_dev_status(__dev); \
921 do {
922
923/** \brief End a foreach loop over Maple devices.
924 \ingroup maple
925
926 Each MAPLE_FOREACH_BEGIN() must be paired with one of these after the loop
927 body.
928*/
929#define MAPLE_FOREACH_END() \
930 } while(0); \
931 __i++; \
932 } \
933 } while(0);
934
935__END_DECLS
936
937#endif /* __DC_MAPLE_H */
static struct @69 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_t)(maple_device_t *dev)
Maple detach callback type.
Definition maple.h:775
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.
void maple_detach_callback(uint32_t functions, maple_detach_callback_t cb)
Set an automatic maple detach callback.
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_shutdown(void)
Shutdown Maple.
void maple_attach_callback(uint32_t functions, maple_attach_callback_t cb)
Set an automatic maple attach callback.
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.
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_attach_callback_t)(maple_device_t *dev)
Maple attach callback type.
Definition maple.h:754
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 LIST_HEAD(nmmgr_list, nmmgr_handler) nmmgr_list_t
Name handler list type.
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
static char buffer[256]
Definition porthelper.c:11
static GLint y
Definition scissor.c:38
static GLint x
Definition scissor.c:38
__noinline void func(void)
Definition stacktrace.c:13
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:317
LIST_ENTRY(maple_driver) drv_list
Driver list handle.
const char * name
The driver name.
Definition maple.h:322
uint32_t functions
One or more MAPLE_FUNCs ORed together.
Definition maple.h:321
size_t status_size
The size of the status buffer.
Definition maple.h:324
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:389
volatile int dma_in_progress
Is a DMA running now?
Definition maple.h:409
int vbl_handle
Our vblank handler handle.
Definition maple.h:418
volatile int dma_cntr
DMA interrupt counter.
Definition maple.h:400
volatile int vbl_cntr
VBlank interrupt counter.
Definition maple.h:403
int gun_x
The horizontal position of the lightgun signal.
Definition maple.h:424
volatile uint8_t scan_ready_mask
Mask of ports that completed the initial scan.
Definition maple.h:415
int gun_y
The vertical position of the lightgun signal.
Definition maple.h:427
uint8_t detect_port_next
Next port that will be auto-detected.
Definition maple.h:412
uint8_t * dma_buffer
DMA send buffer.
Definition maple.h:406
int gun_port
The port to read for lightgun status, if any.
Definition maple.h:421
Common integer types.