12 #include <irx_imports.h>
15 #define MODNAME "INET_SPEED_UART_driver"
18 IRX_ID(MODNAME, 0x2, 0x1A);
63 int spduart_overrun_error_count;
64 int spduart_parity_error_count;
65 int spduart_framing_error_count;
66 int spduart_break_interrupt_count;
67 int spduart_buffer_overflow_count;
70 char spduart_fcr_cached;
71 char spduart_msr_cached;
72 char spduart_signal_pin;
73 char spduart_mcr_cached;
78 int spduart_alarm_1e4_flag;
79 int spduart_alarm_1e6_flag;
80 int spduart_start_flag;
81 int spduart_stop_flag;
83 int spduart_data_set_ready_flag;
93 char spduart_dial_[1024];
103 static const char *modem_firmware_s37[54] = {
104 "S3100000A000B20269A9008DBC044C0EE101\r",
105 "S31500009DA560606060606060606B606B606060606092\r",
106 "S31500009DB56B60606B60606060606060606060606082\r",
107 "S31500009DC56060606060606B606B60606B6060606067\r",
108 "S31500009DD5606060606060606B6B6060606B60606B4C\r",
109 "S31500009DE560606B606060606060606060606B606052\r",
110 "S31500009EB000000600000000004E0003000000000045\r",
111 "S31500009EC09300002A000000000000000000000000CF\r",
112 "S31500009ED00000000000006E006100006E000000003F\r",
113 "S31500009EE0000000000000004B7100000074000098A4\r",
114 "S31500009EF000009B000000000000000000005E000063\r",
115 "S30600009F00005A\r",
116 "S31500009F019A284C5F86A9608DA79DADA102D019A99B\r",
117 "S31500009F11048DEC02A973CD0D01B0038D0D01A9418C\r",
118 "S31500009F21CD110190038D110160C2016001FF4C1931\r",
119 "S31500009F31AD6487D014D2105D01A9328D1D87A900A9\r",
120 "S31500009F418D1E8748C2105D0168604CC686A9603FB8\r",
121 "S31500009F516B02A96B8DE49DA96B8DA79D604C008159\r",
122 "S31500009F61A21820445A0DEB02A2184CF5584C6986EA\r",
123 "S31500009F714C449EAE59048A2902F0168A29FD8D5950\r",
124 "S31500009F8104A9528D1C06A9807B09208D1806A9A05B\r",
125 "S31200009F917B60D2083906604CEF864C548682\r",
126 "S31500009DF9AD4B878540AD4C878541A541C900D00447\r",
127 "S31500009E09A540C996B033AD43878540AD44878541A2\r",
128 "S31500009E1938A540E98C8540A541E9008541A540ED75\r",
129 "S31500009E2952878540A541ED53878541B26444207820\r",
130 "S30F00009E3969A5408D439E4C708660BB\r",
131 "S31500009E447F4C04D21060016087FFAD9602C971F0A1\r",
132 "S31500009E542C206067A540E9588540A541E902854163\r",
133 "S31500009E64900BAD588789018D58874C4575AD960280\r",
134 "S31500009E74C971F009ADA89E8DA79E4CAE77ADA89E7C\r",
135 "S31500009E8438EDA79E9004C902B00160A900854085FB\r",
136 "S31500009E9441A5408D5887A5418D598707FF20DD7759\r",
137 "S30800009EA44C1361F5\r",
138 "S31500008654A950CD0286B0038D028660E2750102043C\r",
139 "S3150000866497FF27FF60A203A9004C9BE4AD478785CB\r",
140 "S3150000867440AD48878541B26444207869AD439E8500\r",
141 "S3150000868442208B69A541C907D004A540C9089012A8\r",
142 "S31500008694A9758D3F87A9778D4087B200AEB248B1E0\r",
143 "S315000086A4B759601FFF1BAFFF09A7FFC2027501B2CE\r",
144 "S315000086B414FEE25D01100AC6FED00617FFD202754B\r",
145 "S315000086C40160AD5702C93CD021BF6B1EB20747B249\r",
146 "S315000086D45046B20A45B2B9442096E3B20747B250AF\r",
147 "S315000086E446B20B45B2B9442096E360E21106100681\r",
148 "S30C000086F47F5C032095026084\r",
149 "S3150000810020A786E25D0110374F63342073E7AD96F2\r",
150 "S3150000811002C971D00FF24E01100AAD0404C960B055\r",
151 "S31500008120034CF960AD3F87C9B1F00FAD4D87C9006B\r",
152 "S31500008130F00DE2600110094C7E9EA9008D4D87600E\r",
153 "S3150000814020F99DADEC02C903D0F5AD3F87C9DBD060\r",
154 "S31500008150EEE25E0101E920C466A5406D45878540D3\r",
155 "S31500008160A5416D46878541B26444207869A5408D56\r",
156 "S31500008170A89E38E92890C8A54038E93290060FFF36\r",
157 "S30C00008180BE4C719E4C4C9EA3\r"};
161 #define sceInetPrintf(...) printf(__VA_ARGS__)
163 static int module_start(
int ac,
char *av[],
void *startaddr,
ModuleInfo_t *mi);
164 static int module_stop(
int ac,
char *av[],
void *startaddr,
ModuleInfo_t *mi);
166 int _start(
int argc,
char *argv[],
void *startaddr,
ModuleInfo_t *mi)
169 return module_start(argc, argv, startaddr, mi);
171 return module_stop(argc, argv, startaddr, mi);
174 static void spduart_dump_msr(u8 msr)
177 "spduart: MSR=%02x (DCTS=%d DDSR=%d TERI=%d DDCD=%d\n",
184 "spduart: CTS=%d DSR=%d RI=%d DCD=%d)\n", (msr >> 4) & 1, (msr >> 5) & 1, (msr >> 6) & 1, msr >> 7);
187 static unsigned int alarm_cb_1e4(
void *userdata)
192 priv->spduart_modem_ops.rcv_len = priv->recv_buf_struct.m_cur_xfer_len;
193 iSetEventFlag(priv->spduart_modem_ops.evfid, sceModemEFP_Recv);
197 static unsigned int alarm_cb_1e6(
void *userdata)
202 iSetEventFlag(priv->spduart_ef, 4u);
203 return priv->spduart_clock_1e6.lo;
214 priv->spduart_fcr_cached &= ~2;
215 m_cur_xfer_len = priv->send_buf_struct.m_cur_xfer_len;
217 if ( m_cur_xfer_len > 0 )
219 if ( m_cur_xfer_len > 16 )
221 if ( ((priv->spduart_msr_cached >> 4) & sceModemLINE_CTS) != 0 )
223 if ( (spduart_internals.dev9_uart_reg_area->
r_msr & 0x20) != 0 )
227 v6 = m_cur_xfer_len - 1;
230 v7 = *((u8 *)priv->send_buf_struct.m_ptr + (priv->send_buf_struct.m_offset2 & 0x3FF));
231 ++priv->send_buf_struct.m_offset2;
232 priv->send_buf_struct.m_cur_xfer_len -= 1;
237 if ( priv->send_buf_struct.m_cur_xfer_len > 0 )
239 priv->spduart_fcr_cached |= 2;
244 priv->spduart_fcr_cached |= 2;
246 priv->spduart_tx_count += v4;
249 spduart_internals.dev9_uart_reg_area->
r_wrfcr_rdiir = priv->spduart_fcr_cached;
254 static int spduart_dev9_intr_cb(
int flag)
268 switch ( spduart_internals.dev9_uart_reg_area->
r_lcr & 0xF )
271 r_scr = spduart_internals.dev9_uart_reg_area->
r_scr;
272 if ( spduart_internals.spduart_start_flag )
274 spduart_internals.spduart_msr_cached = spduart_internals.dev9_uart_reg_area->
r_scr;
277 if ( (spduart_internals.dev9_uart_reg_area->
r_scr & 1) != 0 )
279 if ( ((spduart_internals.dev9_uart_reg_area->
r_scr >> 4) & sceModemLINE_CTS) != 0 )
286 if ( ((spduart_internals.dev9_uart_reg_area->
r_scr >> 4) & sceModemLINE_DSR) == 0 )
288 spduart_internals.shutdown_flag = 1;
289 iSetEventFlag(spduart_internals.spduart_modem_ops.evfid, sceModemEFP_PlugOut);
293 if ( !spduart_internals.spduart_data_set_ready_flag )
296 spduart_internals.spduart_data_set_ready_flag = 1;
297 iSetEventFlag(spduart_internals.spduart_modem_ops.evfid, sceModemEFP_StartDone | sceModemEFP_Send);
303 iSetEventFlag(spduart_internals.spduart_modem_ops.evfid, sceModemEFP_Ring);
305 if ( (r_scr & 8) && (((spduart_internals.spduart_msr_cached ^ (u8)r_scr) >> 4) & sceModemLINE_DCD) != 0 )
307 iSetEventFlag(spduart_internals.spduart_modem_ops.evfid, ( ((r_scr >> 4) & sceModemLINE_DCD) != 0 ) ? sceModemEFP_Connect : sceModemEFP_Disconnect);
309 spduart_internals.spduart_msr_cached = r_scr;
315 spduart_internals.spduart_rx_count += v1;
316 if ( spduart_internals.recv_buf_struct.m_cur_xfer_len < 257 )
318 if ( (spduart_internals.spduart_signal_pin & 2) == 0 )
320 spduart_internals.spduart_signal_pin |= 2u;
321 spduart_internals.dev9_uart_reg_area->
r_lsr = spduart_internals.spduart_signal_pin;
324 if ( spduart_internals.recv_buf_struct.m_cur_xfer_len >= 768 )
326 if ( (spduart_internals.spduart_signal_pin & 2) != 0 )
328 spduart_internals.spduart_signal_pin &= ~2u;
329 spduart_internals.dev9_uart_reg_area->
r_lsr = spduart_internals.spduart_signal_pin;
334 iSetEventFlag(spduart_internals.spduart_ef, v2);
337 spduart_internals.spduart_fcr_cached &= ~2u;
338 spduart_internals.dev9_uart_reg_area->
r_wrfcr_rdiir = spduart_internals.spduart_fcr_cached;
343 while ( (spduart_internals.dev9_uart_reg_area->
r_msr & 1) != 0 && !spduart_internals.spduart_start_flag )
345 if ( spduart_internals.recv_buf_struct.m_cur_xfer_len >= 1024 )
347 ++spduart_internals.spduart_buffer_overflow_count;
352 m_offset1 = spduart_internals.recv_buf_struct.m_offset1;
353 *((u8 *)spduart_internals.recv_buf_struct.m_ptr + (spduart_internals.recv_buf_struct.m_offset1 & 0x3FF)) =
355 spduart_internals.recv_buf_struct.m_offset1 = m_offset1 + 1;
356 ++spduart_internals.recv_buf_struct.m_cur_xfer_len;
361 r_msr = spduart_internals.dev9_uart_reg_area->
r_msr;
364 ++spduart_internals.spduart_overrun_error_count;
368 ++spduart_internals.spduart_parity_error_count;
372 ++spduart_internals.spduart_framing_error_count;
376 ++spduart_internals.spduart_break_interrupt_count;
385 static int spduart_set_baud(
int baud)
410 spduart_internals.dev9_uart_reg_area->
r_cr1 = 27;
411 spduart_internals.dev9_uart_reg_area->
r_cr2 = 4;
414 priv->spduart_mcr_cached = -125;
415 spduart_internals.dev9_uart_reg_area->
r_mcr = priv->spduart_mcr_cached;
416 v2 = spduart_set_baud(priv->spduart_baud_);
418 spduart_internals.dev9_uart_reg_area->
r_wrfcr_rdiir = (v2 >> 8) & 0xFF;
419 priv->spduart_mcr_cached = 3;
420 spduart_internals.dev9_uart_reg_area->
r_mcr = priv->spduart_mcr_cached;
421 priv->spduart_signal_pin = 3;
422 spduart_internals.dev9_uart_reg_area->
r_lsr = priv->spduart_signal_pin;
423 switch ( priv->spduart_trig_ )
427 spduart_internals.dev9_uart_reg_area->
r_lcr = 1;
432 spduart_internals.dev9_uart_reg_area->
r_lcr = 65;
438 spduart_internals.dev9_uart_reg_area->
r_lcr = -127;
443 spduart_internals.dev9_uart_reg_area->
r_lcr = -63;
449 static void spduart_deinit()
451 spduart_internals.dev9_uart_reg_area->
r_cr2 = -124;
454 static void fail_sleep(
const char *fmt)
463 if ( priv->shutdown_flag )
465 fail_sleep(
"spduart: plug-out\n");
469 static int spduart_send_now(
struct spduart_internals_ *priv,
const char *in_buf,
char *expected_buf)
488 sleep_on_shutdown(priv);
491 r_scr = spduart_internals.dev9_uart_reg_area->
r_scr;
492 priv->spduart_msr_cached = r_scr;
493 if ( ((r_scr >> 4) & sceModemLINE_CTS) != 0 && ((spduart_internals.dev9_uart_reg_area->
r_msr >> 4) & sceModemLINE_DSR) != 0 )
509 if ( (spduart_internals.dev9_uart_reg_area->
r_msr & 1) != 0 )
516 if ( v14 != spduart_internals.dev9_uart_reg_area->
r_wrthr_rdrbr )
556 sleep_on_shutdown(priv);
557 spduart_do_init_dev9(priv);
558 for ( i = 0; i < 300; ++i )
560 sleep_on_shutdown(priv);
565 sleep_on_shutdown(priv);
566 priv->spduart_msr_cached = spduart_internals.dev9_uart_reg_area->
r_scr;
567 if ( ((priv->spduart_msr_cached >> 4) & sceModemLINE_DSR) != 0 )
571 }
while ( spduart_send_now(priv,
"AT\r",
"OK") < 0 && spduart_send_now(priv,
"AT\r",
"OK") < 0 );
572 if ( spduart_send_now(priv,
"ATI3\r",
"P2109-V90") < 0 )
574 sceInetPrintf(
"spduart: P2109-V90 detected\n");
575 spduart_send_now(priv,
"AT**\r",
"Download initiated ..");
576 sceInetPrintf(
"spduart: downloading (9A-40)\n");
579 while ( modem_firmware_s37[i] )
581 v5 = spduart_send_now(priv, modem_firmware_s37[i],
".");
584 sceInetPrintf(
"spduart: failed to download (1)\n");
589 if ( v5 >= 0 && spduart_send_now(priv,
"S70500000000FA\r",
"OK") >= 0 )
591 sceInetPrintf(
"spduart: download completed\n");
594 sceInetPrintf(
"spduart: failed to download (2)\n");
596 if ( priv->spduart_nogci_ )
598 if ( !priv->spduart_gci_[0] )
600 sprintf(priv->buf2data,
"AT+GCI=%c%c\r", priv->spduart_gci_[0], priv->spduart_gci_[1]);
601 sceInetPrintf(
"spduart: sending \"%S\"\n", priv->buf2data);
602 if ( spduart_send_now(priv, priv->buf2data,
"OK") >= 0 )
604 sceInetPrintf(
"spduart: failed to set GCI (1)\n");
606 if ( !priv->spduart_dial_[0] )
608 fail_sleep(
"spduart: no dial_cnf\n");
610 sceInetPrintf(
"spduart: scanning GCI setting in \"%s\"\n", priv->spduart_dial_);
611 v7 = open(priv->spduart_dial_, 1);
614 fail_sleep(
"spduart: can't open\n");
616 buf1data = priv->buf1data;
617 v10 = read(v7, buf1data, 1024);
620 fail_sleep(
"spduart: read error\n");
623 if ( (
unsigned int)v10 >= 0x400 )
625 fail_sleep(
"spduart: file too big\n");
627 v11 = &buf1data[v10];
630 if ( buf1data >= v11 )
632 fail_sleep(
"spduart: no GCI setting\n");
634 while ( buf1data < v11 )
636 if ( (isspace(*buf1data)) == 0 )
640 if ( *buf1data !=
'#' )
642 while ( buf1data < v11 && *buf1data !=
'+' )
646 if ( (*buf1data ==
'+') && (strncmp(
"+GCI=", buf1data, 5) == 0) )
649 if ( ((isxdigit(buf1data[0])) != 0) && ((isxdigit(buf1data[1])) != 0) )
655 while ( buf1data < v11 && *buf1data !=
'\n' )
659 if ( *buf1data ==
'\n' )
662 sprintf(priv->buf2data,
"AT+GCI=%c%c\r", (u8)*buf1data, (u8)buf1data[1]);
663 sceInetPrintf(
"spduart: sending \"%S\"\n", priv->buf2data);
664 if ( spduart_send_now(priv, priv->buf2data,
"OK") < 0 )
666 sceInetPrintf(
"spduart: failed to set GCI (2)\n");
673 static void spduart_thread_proc(
void *arg)
681 spduart_init_hw(priv);
682 priv->spduart_fcr_cached = 13;
683 spduart_internals.dev9_uart_reg_area->
r_wrfcr_rdiir = priv->spduart_fcr_cached;
684 while ( !WaitEventFlag(priv->spduart_ef, 0xFu, 17, &v12) )
686 if ( (v12 & 2) != 0 && !priv->spduart_start_flag )
688 SpdIntrDisable(4096);
689 if ( priv->spduart_alarm_1e4_flag )
691 CancelAlarm(alarm_cb_1e4, priv);
692 priv->spduart_alarm_1e4_flag = 0;
694 if ( priv->spduart_alarm_1e6_flag )
696 CancelAlarm(alarm_cb_1e6, priv);
697 priv->spduart_alarm_1e6_flag = 0;
699 priv->spduart_signal_pin = 0;
700 spduart_internals.dev9_uart_reg_area->
r_lsr = 0;
701 spduart_internals.dev9_uart_reg_area->
r_lcr = -121;
702 priv->recv_buf_struct.m_cur_xfer_len = 0;
703 priv->recv_buf_struct.m_offset1 = 0;
704 priv->recv_buf_struct.m_offset2 = 0;
705 priv->send_buf_struct.m_cur_xfer_len = 0;
706 priv->send_buf_struct.m_offset1 = 0;
707 priv->send_buf_struct.m_offset2 = 0;
709 spduart_internals.dev9_uart_reg_area->
r_lcr = -127;
710 priv->spduart_start_flag = 1;
711 priv->spduart_stop_flag = 0;
712 if ( !priv->shutdown_flag )
714 priv->spduart_mcr_cached = 67;
715 spduart_internals.dev9_uart_reg_area->
r_mcr = priv->spduart_mcr_cached;
716 for ( i = 0; i < 20; i += 1 )
718 if ( priv->shutdown_flag )
720 if ( ((priv->spduart_msr_cached >> 4) & sceModemLINE_DCD) == 0 )
722 priv->spduart_mcr_cached = 3;
723 spduart_internals.dev9_uart_reg_area->
r_mcr = 3;
724 for ( i = 0; i < 300; i += 1 )
726 if ( priv->shutdown_flag )
736 if ( !priv->spduart_start_flag )
738 if ( (v12 & 4) != 0 )
740 if ( priv->spduart_data_set_ready_flag )
742 if ( spduart_send(priv) > 0 )
744 m_cur_xfer_len = priv->send_buf_struct.m_cur_xfer_len;
745 if ( m_cur_xfer_len >= 257 )
747 priv->spduart_modem_ops.snd_len = 1024 - m_cur_xfer_len;
748 SetEventFlag(priv->spduart_modem_ops.evfid, sceModemEFP_Send);
753 if ( (v12 & 8) != 0 )
755 if ( priv->spduart_alarm_1e4_flag )
757 CancelAlarm(alarm_cb_1e4, priv);
758 priv->spduart_alarm_1e4_flag = 0;
760 v10 = priv->recv_buf_struct.m_cur_xfer_len;
763 priv->spduart_modem_ops.rcv_len = v10;
764 SetEventFlag(priv->spduart_modem_ops.evfid, sceModemEFP_Recv);
768 SetAlarm(&priv->spduart_clock_1e4, alarm_cb_1e4, priv);
769 priv->spduart_alarm_1e4_flag = 1;
773 else if ( (v12 & 1) != 0 )
775 priv->shutdown_flag = 0;
776 priv->spduart_data_set_ready_flag = 0;
777 priv->spduart_modem_ops.snd_len = 1024;
778 priv->spduart_signal_pin = 3;
779 spduart_internals.dev9_uart_reg_area->
r_lsr = 3;
780 priv->spduart_msr_cached = spduart_internals.dev9_uart_reg_area->
r_scr;
781 spduart_dump_msr(priv->spduart_msr_cached);
782 if ( ((priv->spduart_msr_cached >> 4) & sceModemLINE_DSR) != 0 )
784 SetEventFlag(priv->spduart_modem_ops.evfid, sceModemEFP_StartDone | sceModemEFP_Send);
785 priv->spduart_data_set_ready_flag = 1;
787 if ( ((priv->spduart_msr_cached >> 4) & sceModemLINE_DCD) != 0 )
789 SetEventFlag(priv->spduart_modem_ops.evfid, sceModemEFP_Connect);
791 priv->spduart_start_flag = 0;
792 SetAlarm(&priv->spduart_clock_1e6, alarm_cb_1e6, priv);
793 priv->spduart_alarm_1e6_flag = 1;
799 static int spduart_op_start(
void *userdata,
int flags)
805 priv->spduart_stop_flag = 0;
806 SetEventFlag(priv->spduart_ef, 1u);
810 static int spduart_op_stop(
void *userdata,
int flags)
816 priv->spduart_stop_flag = 1;
817 SetEventFlag(priv->spduart_ef, 2u);
821 static int spduart_op_recv(
void *userdata,
void *ptr,
int len)
831 m_cur_xfer_len = len;
833 if ( priv->recv_buf_struct.m_cur_xfer_len < len )
834 m_cur_xfer_len = priv->recv_buf_struct.m_cur_xfer_len;
835 v8 = priv->recv_buf_struct.m_offset2 & 0x3FF;
837 if ( m_cur_xfer_len < 1024 - v8 )
844 bcopy((
char *)priv->recv_buf_struct.m_ptr + v8, ptr, v9);
845 v10 = m_cur_xfer_len - v9;
848 bcopy(priv->recv_buf_struct.m_ptr, (
char *)ptr + v9, v10);
852 priv->recv_buf_struct.m_cur_xfer_len -= v7;
853 priv->recv_buf_struct.m_offset2 += v7;
854 priv->spduart_modem_ops.rcv_len = priv->recv_buf_struct.m_cur_xfer_len;
855 if ( priv->recv_buf_struct.m_cur_xfer_len < 257 )
857 if ( (priv->spduart_signal_pin & 2) == 0 )
859 priv->spduart_signal_pin |= 2;
860 spduart_internals.dev9_uart_reg_area->
r_lsr = priv->spduart_signal_pin;
868 static int spduart_op_send(
void *userdata,
void *ptr,
int len)
880 if ( 1024 - priv->send_buf_struct.m_cur_xfer_len < len )
881 v4 = 1024 - priv->send_buf_struct.m_cur_xfer_len;
882 v8 = priv->send_buf_struct.m_offset1 & 0x3FF;
884 if ( (
unsigned int)v4 < v9 )
891 bcopy(ptr, (
char *)priv->send_buf_struct.m_ptr + v8, v9);
895 bcopy((
char *)ptr + v9, priv->send_buf_struct.m_ptr, v10);
899 priv->send_buf_struct.m_cur_xfer_len += v7;
900 priv->send_buf_struct.m_offset1 += v7;
901 priv->spduart_modem_ops.snd_len = 1024 - priv->send_buf_struct.m_cur_xfer_len;
905 SetEventFlag(priv->spduart_ef, 4u);
909 static int spduart_op_control(
void *userdata,
int code,
void *ptr,
int len)
921 case sceModemCC_FLUSH_RXBUF:
922 case sceModemCC_FLUSH_TXBUF:
923 case sceModemCC_GET_DIALCONF:
933 case sceModemCC_GET_THPRI:
935 bcopy(&priv->spduart_thpri_, ptr, 4);
938 case sceModemCC_GET_IF_TYPE:
940 v22 = sceModemIFT_SERIAL;
944 case sceModemCC_FLUSH_RXBUF:
947 priv->recv_buf_struct.m_offset1 = 0;
948 priv->recv_buf_struct.m_offset2 = 0;
949 priv->recv_buf_struct.m_cur_xfer_len = 0;
950 priv->spduart_modem_ops.rcv_len = 0;
954 case sceModemCC_FLUSH_TXBUF:
957 priv->send_buf_struct.m_offset1 = 0;
958 priv->send_buf_struct.m_offset2 = 0;
959 priv->send_buf_struct.m_cur_xfer_len = 0;
960 priv->spduart_modem_ops.snd_len = 1024;
964 case sceModemCC_GET_DIALCONF:
968 v13 = strlen(priv->spduart_dial_) + 1;
973 bcopy(priv->spduart_dial_, ptr, v13);
976 case sceModemCC_GET_RX_COUNT:
978 bcopy(&priv->spduart_rx_count, ptr, 4);
981 case sceModemCC_GET_TX_COUNT:
983 bcopy(&priv->spduart_tx_count, ptr, 4);
986 case sceModemCC_GET_OE_COUNT:
988 bcopy(&priv->spduart_overrun_error_count, ptr, 4);
991 case sceModemCC_GET_PE_COUNT:
993 bcopy(&priv->spduart_parity_error_count, ptr, 4);
996 case sceModemCC_GET_FE_COUNT:
998 bcopy(&priv->spduart_framing_error_count, ptr, 4);
1001 case sceModemCC_GET_BO_COUNT:
1003 bcopy(&priv->spduart_buffer_overflow_count, ptr, 4);
1006 case sceModemCC_GET_PARAM:
1008 v25 = sceModemPARAM_RTSCTS;
1009 v25 |= ((priv->spduart_mcr_cached << 30) & (sceModemPARAM_PARODD | sceModemPARAM_PARENB));
1010 v25 |= ((priv->spduart_mcr_cached << 28) & sceModemPARAM_CSIZE);
1011 v25 |= priv->spduart_baud_;
1012 v25 |= ( (priv->spduart_mcr_cached & 4) != 0 ) ? sceModemPARAM_STOP2 : sceModemPARAM_STOP1;
1013 bcopy((
int *)&v25, ptr, 4);
1016 case sceModemCC_GET_LINE:
1018 v26 = ((priv->spduart_signal_pin << 4) & (sceModemLINE_DTR | sceModemLINE_RTS)) | (((u8)priv->spduart_msr_cached >> 4) & (sceModemLINE_CTS | sceModemLINE_DSR | sceModemLINE_RI | sceModemLINE_DCD));
1019 bcopy(&v26, ptr, 4);
1022 case sceModemCC_SET_THPRI:
1026 bcopy(ptr, &priority, 4);
1028 if ( priv->spduart_thread > 0 )
1030 v6 = ChangeThreadPriority(priv->spduart_thread, priority);
1032 priv->spduart_thpri_ = priority;
1034 if ( priv->spduart_thread <= 0 || v6 == -413 )
1036 if ( (
unsigned int)(priority - 9) < 0x73 )
1037 priv->spduart_thpri_ = priority;
1041 case sceModemCC_SET_PARAM:
1045 bcopy(ptr, &v25, 4);
1046 v17 = spduart_set_baud(v25 & sceModemPARAM_SPEED);
1049 if ( (v25 & sceModemPARAM_STOP1) == 0 || (v25 & (sceModemPARAM_XON | sceModemPARAM_XOFF)) != 0 )
1051 if ( (v25 & sceModemPARAM_PARODD) != 0 || (v25 & sceModemPARAM_RTSCTS) == 0 )
1053 priv->spduart_mcr_cached &= 0x40;
1054 priv->spduart_mcr_cached |= ((v25 & (sceModemPARAM_PARODD | sceModemPARAM_PARENB)) >> 30);
1055 priv->spduart_mcr_cached |= ((v25 & sceModemPARAM_CSIZE) >> 28);
1056 priv->spduart_mcr_cached |= ((v25 & sceModemPARAM_STOPS) >> 27);
1057 priv->spduart_mcr_cached |= 0x80;
1058 spduart_internals.dev9_uart_reg_area->
r_mcr = priv->spduart_mcr_cached;
1060 spduart_internals.dev9_uart_reg_area->
r_wrfcr_rdiir = (v17 >> 8) & 0xFF;
1061 priv->spduart_mcr_cached &= ~0x80;
1063 spduart_internals.dev9_uart_reg_area->
r_mcr = priv->spduart_mcr_cached;
1066 case sceModemCC_SET_LINE:
1068 bcopy(ptr, &v26, 4);
1069 if ( (v26 & ~(sceModemLINE_DTR | sceModemLINE_RTS)) != 0 )
1071 priv->spduart_signal_pin &= ~3;
1072 priv->spduart_signal_pin |= ((
unsigned int)(v26 & (sceModemLINE_DTR | sceModemLINE_RTS)) >> 4);
1073 spduart_internals.dev9_uart_reg_area->
r_lsr = priv->spduart_signal_pin;
1081 static void shutdown_cb(
void)
1083 spduart_internals.shutdown_flag = 1;
1086 static int print_version(
void)
1088 printf(
"SPDUART (%s)%s\n",
"Version 2.26.0",
"");
1089 return MODULE_NO_RESIDENT_END;
1092 static int print_usage(
void)
1094 printf(
"Usage: spduart [-probe] [-nogci] [baud=<baud>] [trig=<trig>] [gci=<gci>] [thpri=<prio>] [thstack=<stack>] "
1096 return MODULE_NO_RESIDENT_END;
1100 void spduart_2_deinit(
int a1)
1104 if ( !a1 && (SPD_REG16(SPD_R_REV_3) & 8) != 0 )
1105 spduart_internals.dev9_uart_reg_area->
r_cr2 = -124;
1109 static int module_start(
int ac,
char *av[],
void *startaddr,
ModuleInfo_t *mi)
1126 spduart_internals.spduart_thpri_ = 40;
1127 spduart_internals.spduart_thstack_ = 0x2000;
1128 spduart_internals.spduart_dial_[0] = 0;
1129 spduart_internals.spduart_baud_ = 115200;
1130 spduart_internals.spduart_trig_ = 8;
1131 for ( v5 = 1; v5 < ac; v5 += 1 )
1133 if ( !strcmp(
"-help", av[v5]) )
1135 return print_usage();
1137 else if ( !strcmp(
"-version", av[v5]) )
1139 return print_version();
1141 else if ( !strcmp(
"-probe", av[v5]) )
1146 else if ( !strcmp(
"-nogci", av[v5]) )
1148 spduart_internals.spduart_nogci_ = 1;
1151 else if ( !strncmp(
"dial=", av[v5], 5) )
1153 strcpy(spduart_internals.spduart_dial_, av[v5] + 5);
1156 else if ( !strncmp(
"gci=", av[v5], 4) )
1158 v7 = (
char *)(av[v5] + 4);
1159 if ( (isxdigit(*v7)) == 0 || (isxdigit(v7[1])) == 0 )
1160 return print_usage();
1161 spduart_internals.spduart_gci_[0] = v7[0];
1162 spduart_internals.spduart_gci_[1] = v7[1];
1165 else if ( !strncmp(
"thpri=", av[v5], 6) )
1167 v7 = (
char *)(av[v5] + 6);
1168 if ( (isdigit(*v7)) == 0 )
1169 return print_usage();
1170 v11 = strtol(v7, 0, 10);
1171 if ( (
unsigned int)(v11 - 9) >= 0x73 )
1172 return print_usage();
1173 spduart_internals.spduart_thpri_ = v11;
1175 else if ( !strncmp(
"thstack=", av[v5], 8) )
1177 v7 = (
char *)(av[v5] + 8);
1178 if ( (isdigit(*v7)) == 0 )
1179 return print_usage();
1180 spduart_internals.spduart_thstack_ = strtol(v7, 0, 10);
1183 if ( (isdigit(*v7)) == 0 )
1187 if ( !strcmp(v7,
"KB") )
1189 spduart_internals.spduart_thstack_ <<= 10;
1193 else if ( !strncmp(
"baud=", av[v5], 5) )
1195 v7 = (
char *)(av[v5] + 5);
1196 if ( (isdigit(*v7)) == 0 )
1197 return print_usage();
1198 spduart_internals.spduart_baud_ = strtol(v7, 0, 10);
1199 if ( !spduart_set_baud(spduart_internals.spduart_baud_) )
1200 return print_usage();
1202 else if ( !strncmp(
"trig=", av[v5], 5) )
1204 v7 = (
char *)(av[v5] + 5);
1205 if ( (isdigit(*v7)) == 0 )
1206 return print_usage();
1207 v11 = strtol(v7, 0, 10);
1215 spduart_internals.spduart_trig_ = v11;
1220 return print_usage();
1226 return print_usage();
1230 if ( (isdigit(*v7)) == 0 )
1235 return print_usage();
1237 if ( (SPD_REG16(SPD_R_REV_3) & 8) == 0 )
1239 sceInetPrintf(
"spduart: SPEED-UART not found\n");
1242 sceInetPrintf(
"spduart: SPEED-UART detected\n");
1247 if ( RegisterLibraryEntries(&_exp_spduart) )
1249 sceInetPrintf(
"spduart: module already loaded\n");
1255 "spduart: thpri=%d baud=%d trig=%d\n",
1256 spduart_internals.spduart_thpri_,
1257 spduart_internals.spduart_baud_,
1258 spduart_internals.spduart_trig_);
1260 spduart_internals.recv_buf_struct.m_ptr = spduart_internals.buf1data;
1261 spduart_internals.send_buf_struct.m_ptr = spduart_internals.buf2data;
1262 spduart_internals.spduart_start_flag = 1;
1263 spduart_internals.spduart_stop_flag = 0;
1264 spduart_do_init_dev9(&spduart_internals);
1265 for ( v14 = 0; v14 < 30; v14 += 1 )
1267 spduart_internals.spduart_msr_cached = spduart_internals.dev9_uart_reg_area->
r_scr;
1268 if ( ((spduart_internals.spduart_msr_cached >> 4) & sceModemLINE_DSR) != 0 )
1270 sceInetPrintf(
"spduart: Modem module detected\n");
1271 Dev9RegisterPowerOffHandler(1, shutdown_cb);
1272 memset(&v17, 0,
sizeof(v17));
1273 spduart_internals.spduart_ef = CreateEventFlag(&v17);
1274 if ( spduart_internals.spduart_ef > 0 )
1276 v18.attr = 0x2000000;
1277 v18.thread = spduart_thread_proc;
1279 v18.priority = spduart_internals.spduart_thpri_;
1280 v18.stacksize = spduart_internals.spduart_thstack_;
1281 v16 = CreateThread(&v18);
1284 spduart_internals.spduart_thread = v16;
1285 if ( !StartThread(v16, &spduart_internals) )
1287 SpdIntrDisable(4096);
1288 SpdRegisterIntrHandler(12, (dev9_intr_cb_t)spduart_dev9_intr_cb);
1289 USec2SysClock(10000u, &spduart_internals.spduart_clock_1e4);
1290 USec2SysClock(1000000u, &spduart_internals.spduart_clock_1e6);
1291 bzero(&spduart_internals.spduart_modem_ops, 108);
1292 spduart_internals.spduart_modem_ops.module_name =
"spduart";
1293 spduart_internals.spduart_modem_ops.vendor_name =
"SCE";
1294 spduart_internals.spduart_modem_ops.device_name =
"Modem (Network Adaptor)";
1295 spduart_internals.spduart_modem_ops.bus_type = sceModemBus_NIC;
1296 spduart_internals.spduart_modem_ops.start = spduart_op_start;
1297 spduart_internals.spduart_modem_ops.stop = spduart_op_stop;
1298 spduart_internals.spduart_modem_ops.recv = spduart_op_recv;
1299 spduart_internals.spduart_modem_ops.send = spduart_op_send;
1300 spduart_internals.spduart_modem_ops.prot_ver = sceModemProtVer;
1301 spduart_internals.spduart_modem_ops.impl_ver = 0;
1302 spduart_internals.spduart_modem_ops.priv = &spduart_internals;
1303 spduart_internals.spduart_modem_ops.control = spduart_op_control;
1304 if ( sceModemRegisterDevice(&spduart_internals.spduart_modem_ops) >= 0 )
1307 return MODULE_REMOVABLE_END;
1309 if ( mi && ((mi->
newflags & 2) != 0) )
1311 return MODULE_RESIDENT_END;
1315 TerminateThread(spduart_internals.spduart_thread);
1318 DeleteThread(spduart_internals.spduart_thread);
1321 DeleteEventFlag(spduart_internals.spduart_ef);
1324 DelayThread(100000);
1326 sceInetPrintf(
"spduart: Modem module NOT detected\n");
1328 ReleaseLibraryEntries(&_exp_spduart);
1330 sceInetPrintf(
"spduart: not resident end (fail%d)\n", v2);
1331 return MODULE_NO_RESIDENT_END;
1334 static int module_stop(
int ac,
char *av[],
void *startaddr,
ModuleInfo_t *mi)
1341 if ( !spduart_internals.spduart_start_flag && !spduart_internals.spduart_stop_flag )
1343 sceInetPrintf(
"spduart: can't unload (busy)\n");
1344 return MODULE_REMOVABLE_END;
1346 sceModemUnregisterDevice(&spduart_internals.spduart_modem_ops);
1347 TerminateThread(spduart_internals.spduart_thread);
1348 DeleteThread(spduart_internals.spduart_thread);
1349 DeleteEventFlag(spduart_internals.spduart_ef);
1350 if ( spduart_internals.spduart_alarm_1e4_flag )
1351 CancelAlarm(alarm_cb_1e4, &spduart_internals);
1352 if ( spduart_internals.spduart_alarm_1e6_flag )
1353 CancelAlarm(alarm_cb_1e6, &spduart_internals);
1354 Dev9RegisterPowerOffHandler(1, 0);
1355 ReleaseLibraryEntries(&_exp_spduart);
1356 SpdIntrDisable(4096);
1358 return MODULE_NO_RESIDENT_END;