summaryrefslogtreecommitdiff
path: root/Source/TestSuite/WSD/source/dolphintest_wsd.cpp
blob: 52fbe4bbf8fcb0d4d0898c72362cdf381779ab0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// SD card insertion/removal callback demo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gccore.h>
#include <wiiuse/wpad.h>


#define IOCTL_SDIO_SENDCMD      0x07

#define SDIO_CMD_REGINTR      0x40
#define SDIO_CMD_UNREGINTR      0x41

#define SD_INSERT_EVENT        0x01
#define SD_REMOVE_EVENT        0x02

static struct _sdiorequest
{
  u32 cmd;
  u32 cmd_type;
  u32 rsp_type;
  u32 arg;
  u32 blk_cnt;
  u32 blk_size;
  void *dma_addr;
  u32 isdma;
  u32 pad0;
} sd_req;

static struct _sdioresponse
{
  u32 rsp_fields[3];
  u32 acmd12_response;
} sd_resp;

static s32 __sd0_fd = -1;
static const char _sd0_fs[] ATTRIBUTE_ALIGN(32) = "/dev/sdio/slot0";

static s32 __sdio_getinterrupt(u32 hook, ipccallback cb)
{
  memset(&sd_req, 0, sizeof(sd_req));

  sd_req.cmd = SDIO_CMD_REGINTR;
  sd_req.arg = hook;

  if (hook==SD_INSERT_EVENT)
    printf("Requesting insert event %p %p\n", cb, &sd_resp);
  else if (hook==SD_REMOVE_EVENT)
    printf("Requesting removal event %p %p\n", cb, &sd_resp);
  else
    printf("I don't know what I'm requesting here: hook=%u\n", hook);

  if (__sd0_fd<0)
    __sd0_fd = IOS_Open(_sd0_fs,1);

  if (__sd0_fd>=0)
    return IOS_IoctlAsync(__sd0_fd,IOCTL_SDIO_SENDCMD,&sd_req,sizeof(sd_req),&sd_resp,sizeof(sd_resp),cb,NULL);

  // else return the IOS_Open error code
  return __sd0_fd;
}

static s32 __sdio_releaseinterrupt(void)
{
  if (__sd0_fd<0)
    return 0;

  // this command makes the IOS_IoctlAsync call above return a response immediately

  // sd_req.arg is already set to the right value (1 or 2, whatever was used last)
  sd_req.cmd = SDIO_CMD_UNREGINTR;
  return IOS_Ioctl(__sd0_fd,IOCTL_SDIO_SENDCMD,&sd_req,sizeof(sd_req),&sd_resp,sizeof(sd_resp));
}

static void sd_cb(u32 ret, void* unused)
{
  printf("Got an SD interrupt, ret = %08X\n", ret);
  printf("Response data: %08X %08X %08X %08X\n", sd_resp.rsp_fields[0], sd_resp.rsp_fields[1], sd_resp.rsp_fields[2], sd_resp.acmd12_response);

  if (ret==SD_INSERT_EVENT)
  {
    printf("SD card was inserted\n");
    // tell us when it gets removed
    __sdio_getinterrupt(SD_REMOVE_EVENT, (ipccallback)sd_cb);
  }
  else if (ret==SD_REMOVE_EVENT)
  {
    printf("SD card was removed\n");
    // tell us when something is inserted
    __sdio_getinterrupt(SD_INSERT_EVENT, (ipccallback)sd_cb);
  }
  else
    printf("Unknown SD int: %08X\n", ret);
}



static void *xfb = NULL;
static GXRModeObj *rmode = NULL;

int main(int argc, char **argv) {
  VIDEO_Init();
  WPAD_Init();
  rmode = VIDEO_GetPreferredMode(NULL);
  xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
  console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
  VIDEO_Configure(rmode);
  VIDEO_SetNextFramebuffer(xfb);
  VIDEO_SetBlack(FALSE);
  VIDEO_Flush();
  VIDEO_WaitVSync();
  if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();

  printf("\x1b[2;0H");
  printf("SD Card insertion/removal demo\n");
  printf("Press HOME at any time to exit\n");

  __sdio_getinterrupt(SD_INSERT_EVENT, (ipccallback)sd_cb);

  while(1) {
    WPAD_ScanPads();
    u32 pressed = WPAD_ButtonsDown(0);
    if ( pressed & WPAD_BUTTON_HOME ) break;
    VIDEO_WaitVSync();
  }

  printf("SD event release returned %d\n", __sdio_releaseinterrupt());
  IOS_Close(__sd0_fd);

  sleep(4);

  return 0;
}