change PAD_ScanPads()s behaviour. the return value now contains a bitmask of the...
[libogc.git] / wiiuse / io_wii.c
bloba9082c9b88a2a140c2e20e0e1b17752688db7831
1 #ifdef GEKKO
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <string.h>
8 #include "definitions.h"
9 #include "wiiuse_internal.h"
10 #include "events.h"
11 #include "io.h"
12 #include "lwp_wkspace.h"
14 #define MAX_COMMANDS 0x100
15 #define MAX_WIIMOTES 5
17 static vu32* const _ipcReg = (u32*)0xCD000000;
18 static u8 *__queue_buffer[MAX_WIIMOTES] = { 0, 0, 0, 0, 0 };
20 extern void parse_event(struct wiimote_t *wm);
21 extern void idle_cycle(struct wiimote_t* wm);
22 extern void hexdump(void *d, int len);
24 static __inline__ u32 ACR_ReadReg(u32 reg)
26 return _ipcReg[reg>>2];
29 static __inline__ void ACR_WriteReg(u32 reg,u32 val)
31 _ipcReg[reg>>2] = val;
34 static s32 __wiiuse_disconnected(void *arg,struct bte_pcb *pcb,u8 err)
36 struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg;
37 struct wiimote_t *wm = wml->wm;
39 if(!wm) return ERR_OK;
41 //printf("wiimote disconnected\n");
42 WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_IR|WIIMOTE_STATE_IR_INIT));
43 WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_SPEAKER|WIIMOTE_STATE_SPEAKER_INIT));
44 WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_EXP|WIIMOTE_STATE_EXP_HANDSHAKE|WIIMOTE_STATE_EXP_FAILED));
45 WIIMOTE_DISABLE_STATE(wm,(WIIMOTE_STATE_CONNECTED|WIIMOTE_STATE_HANDSHAKE|WIIMOTE_STATE_HANDSHAKE_COMPLETE));
47 while(wm->cmd_head) {
48 __lwp_queue_append(&wm->cmdq,&wm->cmd_head->node);
49 wm->cmd_head = wm->cmd_head->next;
51 wm->cmd_tail = NULL;
53 if(wm->event_cb) wm->event_cb(wm,WIIUSE_DISCONNECT);
55 wml->wm = NULL;
56 return ERR_OK;
59 static s32 __wiiuse_receive(void *arg,void *buffer,u16 len)
61 struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg;
62 struct wiimote_t *wm = wml->wm;
64 if(!wm || !buffer || len==0) return ERR_OK;
66 //printf("__wiiuse_receive[%02x]\n",*(char*)buffer);
67 wm->event = WIIUSE_NONE;
69 memcpy(wm->event_buf,buffer,len);
70 memset(&(wm->event_buf[len]),0,(MAX_PAYLOAD - len));
71 parse_event(wm);
73 if(wm->event!=WIIUSE_NONE) {
74 if(wm->event_cb) wm->event_cb(wm,wm->event);
77 return ERR_OK;
80 static s32 __wiiuse_connected(void *arg,struct bte_pcb *pcb,u8 err)
82 struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg;
83 struct wiimote_t *wm;
85 wm = wml->assign_cb(&wml->bdaddr);
87 if(!wm) {
88 bte_disconnect(wml->sock);
89 return ERR_OK;
92 wml->wm = wm;
94 wm->sock = wml->sock;
95 wm->bdaddr = wml->bdaddr;
97 //printf("__wiiuse_connected()\n");
98 WIIMOTE_ENABLE_STATE(wm,(WIIMOTE_STATE_CONNECTED|WIIMOTE_STATE_HANDSHAKE));
100 wm->handshake_state = 0;
101 wiiuse_handshake(wm,NULL,0);
103 return ERR_OK;
106 static s32 __wiiuse_sent(void *arg,struct bte_pcb *pcb,u8 err)
108 struct cmd_blk_t *cmd = NULL;
109 struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg;
110 struct wiimote_t *wm = wml->wm;
112 if(!wm) return ERR_OK;
114 cmd = wm->cmd_head;
116 if(!cmd) return ERR_OK;
117 if(cmd->state!=CMD_SENT) return ERR_OK;
119 switch(cmd->data[0]) {
120 case WM_CMD_CTRL_STATUS:
121 case WM_CMD_WRITE_DATA:
122 case WM_CMD_READ_DATA:
123 return ERR_OK;
124 default:
125 wm->cmd_head = cmd->next;
127 cmd->state = CMD_DONE;
128 if(cmd->cb) cmd->cb(wm,NULL,0);
130 __lwp_queue_append(&wm->cmdq,&cmd->node);
131 wiiuse_send_next_command(wm);
132 break;
134 return ERR_OK;
137 void __wiiuse_sensorbar_enable(int enable)
139 u32 val;
140 u32 level;
142 level = IRQ_Disable();
143 val = (ACR_ReadReg(0xc0)&~0x100);
144 if(enable) val |= 0x100;
145 ACR_WriteReg(0xc0,val);
146 IRQ_Restore(level);
149 int wiiuse_register(struct wiimote_listen_t *wml, struct bd_addr *bdaddr, struct wiimote_t *(*assign_cb)(struct bd_addr *bdaddr))
151 s32 err;
153 if(!wml || !bdaddr || !assign_cb) return 0;
155 wml->wm = NULL;
156 wml->bdaddr = *bdaddr;
157 wml->sock = bte_new();
158 wml->assign_cb = assign_cb;
159 if(wml->sock==NULL) return 0;
161 bte_arg(wml->sock,wml);
162 bte_received(wml->sock,__wiiuse_receive);
163 bte_disconnected(wml->sock,__wiiuse_disconnected);
165 err = bte_registerdeviceasync(wml->sock,bdaddr,__wiiuse_connected);
166 if(err==ERR_OK) return 1;
168 return 0;
171 void wiiuse_disconnect(struct wiimote_t *wm)
173 if(wm==NULL || wm->sock==NULL) return;
175 WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_CONNECTED);
176 bte_disconnect(wm->sock);
179 void wiiuse_sensorbar_enable(int enable)
181 __wiiuse_sensorbar_enable(enable);
185 void wiiuse_init_cmd_queue(struct wiimote_t *wm)
187 u32 size;
189 if (!__queue_buffer[wm->unid]) {
190 size = (MAX_COMMANDS*sizeof(struct cmd_blk_t));
191 __queue_buffer[wm->unid] = __lwp_wkspace_allocate(size);
192 if(!__queue_buffer[wm->unid]) return;
195 __lwp_queue_initialize(&wm->cmdq,__queue_buffer[wm->unid],MAX_COMMANDS,sizeof(struct cmd_blk_t));
198 int wiiuse_io_write(struct wiimote_t *wm,ubyte *buf,int len)
200 if(wm->sock)
201 return bte_sendmessageasync(wm->sock,buf,len,__wiiuse_sent);
203 return ERR_CONN;
206 #endif