fix while() stall. (shagkur)
[libogc.git] / wiiuse / io_wii.c
blobd024d971c47db60f8755237c19bb458e8c4141b3
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
16 static vu32* const _ipcReg = (u32*)0xCD000000;
18 extern void parse_event(struct wiimote_t *wm);
19 extern void idle_cycle(struct wiimote_t* wm);
20 extern void hexdump(void *d, int len);
22 static __inline__ u32 ACR_ReadReg(u32 reg)
24 return _ipcReg[reg>>2];
27 static __inline__ void ACR_WriteReg(u32 reg,u32 val)
29 _ipcReg[reg>>2] = val;
32 static s32 __wiiuse_disconnected(void *arg,struct bte_pcb *pcb,u8 err)
34 struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg;
35 struct wiimote_t *wm = wml->wm;
37 if(!wm) return ERR_OK;
39 //printf("wiimote disconnected\n");
40 WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_IR|WIIMOTE_STATE_IR_INIT));
41 WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_SPEAKER|WIIMOTE_STATE_SPEAKER_INIT));
42 WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_EXP|WIIMOTE_STATE_EXP_HANDSHAKE|WIIMOTE_STATE_EXP_FAILED));
43 WIIMOTE_DISABLE_STATE(wm,(WIIMOTE_STATE_CONNECTED|WIIMOTE_STATE_HANDSHAKE|WIIMOTE_STATE_HANDSHAKE_COMPLETE));
45 while(wm->cmd_head) {
46 __lwp_queue_append(&wm->cmdq,&wm->cmd_head->node);
47 wm->cmd_head = wm->cmd_head->next;
49 wm->cmd_tail = NULL;
51 if(wm->event_cb) wm->event_cb(wm,WIIUSE_DISCONNECT);
53 wml->wm = NULL;
54 return ERR_OK;
57 static s32 __wiiuse_receive(void *arg,void *buffer,u16 len)
59 struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg;
60 struct wiimote_t *wm = wml->wm;
62 if(!wm || !buffer || len==0) return ERR_OK;
64 //printf("__wiiuse_receive[%02x]\n",*(char*)buffer);
65 wm->event = WIIUSE_NONE;
67 memcpy(wm->event_buf,buffer,len);
68 memset(&(wm->event_buf[len]),0,(MAX_PAYLOAD - len));
69 parse_event(wm);
71 if(wm->event!=WIIUSE_NONE) {
72 if(wm->event_cb) wm->event_cb(wm,wm->event);
75 return ERR_OK;
78 static s32 __wiiuse_connected(void *arg,struct bte_pcb *pcb,u8 err)
80 struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg;
81 struct wiimote_t *wm;
83 wm = wml->assign_cb(&wml->bdaddr);
85 if(!wm) {
86 bte_disconnect(wml->sock);
87 return ERR_OK;
90 wml->wm = wm;
92 wm->sock = wml->sock;
93 wm->bdaddr = wml->bdaddr;
95 //printf("__wiiuse_connected()\n");
96 WIIMOTE_ENABLE_STATE(wm,(WIIMOTE_STATE_CONNECTED|WIIMOTE_STATE_HANDSHAKE));
98 wm->handshake_state = 0;
99 wiiuse_handshake(wm,NULL,0);
101 return ERR_OK;
104 static s32 __wiiuse_sent(void *arg,struct bte_pcb *pcb,u8 err)
106 struct cmd_blk_t *cmd = NULL;
107 struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg;
108 struct wiimote_t *wm = wml->wm;
110 if(!wm) return ERR_OK;
112 cmd = wm->cmd_head;
114 if(!cmd) return ERR_OK;
115 if(cmd->state!=CMD_SENT) return ERR_OK;
117 switch(cmd->data[0]) {
118 case WM_CMD_CTRL_STATUS:
119 case WM_CMD_WRITE_DATA:
120 case WM_CMD_READ_DATA:
121 return ERR_OK;
122 default:
123 wm->cmd_head = cmd->next;
125 cmd->state = CMD_DONE;
126 if(cmd->cb) cmd->cb(wm,NULL,0);
128 __lwp_queue_append(&wm->cmdq,&cmd->node);
129 wiiuse_send_next_command(wm);
130 break;
132 return ERR_OK;
135 void __wiiuse_sensorbar_enable(int enable)
137 u32 val;
138 u32 level;
140 level = IRQ_Disable();
141 val = (ACR_ReadReg(0xc0)&~0x100);
142 if(enable) val |= 0x100;
143 ACR_WriteReg(0xc0,val);
144 IRQ_Restore(level);
147 int wiiuse_register(struct wiimote_listen_t *wml, struct bd_addr *bdaddr, struct wiimote_t *(*assign_cb)(struct bd_addr *bdaddr))
149 s32 err;
151 if(!wml || !bdaddr || !assign_cb) return 0;
153 wml->wm = NULL;
154 wml->bdaddr = *bdaddr;
155 wml->sock = bte_new();
156 wml->assign_cb = assign_cb;
157 if(wml->sock==NULL) return 0;
159 bte_arg(wml->sock,wml);
160 bte_received(wml->sock,__wiiuse_receive);
161 bte_disconnected(wml->sock,__wiiuse_disconnected);
163 err = bte_registerdeviceasync(wml->sock,bdaddr,__wiiuse_connected);
164 if(err==ERR_OK) return 1;
166 return 0;
169 void wiiuse_disconnect(struct wiimote_t *wm)
171 if(wm==NULL || wm->sock==NULL) return;
173 WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_CONNECTED);
174 bte_disconnect(wm->sock);
177 void wiiuse_sensorbar_enable(int enable)
179 __wiiuse_sensorbar_enable(enable);
182 void wiiuse_init_cmd_queue(struct wiimote_t *wm)
184 u8 *buffer;
185 u32 size;
187 size = (MAX_COMMANDS*sizeof(struct cmd_blk_t));
188 buffer = __lwp_wkspace_allocate(size);
189 __lwp_queue_initialize(&wm->cmdq,buffer,MAX_COMMANDS,sizeof(struct cmd_blk_t));
192 int wiiuse_io_write(struct wiimote_t *wm,ubyte *buf,int len)
194 if(wm->sock)
195 return bte_sendmessageasync(wm->sock,buf,len,__wiiuse_sent);
197 return ERR_CONN;
200 #endif