--- gforth/engine/io-nxt.c 2007/04/22 20:06:26 1.2 +++ gforth/engine/io-nxt.c 2008/02/23 13:03:56 1.12 @@ -6,7 +6,7 @@ Gforth is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 + as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + along with this program; if not, see http://www.gnu.org/licenses/. The following is stolen from the readline library for bash */ @@ -25,26 +24,160 @@ #include "forth.h" #include "../arch/arm/nxt/AT91SAM7.h" #include "../arch/arm/nxt/bt.h" +#include "../arch/arm/nxt/display.h" +#include "../arch/arm/nxt/aic.h" +#include "../arch/arm/nxt/systick.h" +#include "../arch/arm/nxt/sound.h" +#include "../arch/arm/nxt/interrupts.h" +#include "../arch/arm/nxt/nxt_avr.h" +#include "../arch/arm/nxt/nxt_motors.h" +#include "../arch/arm/nxt/i2c.h" -long key_avail () +int terminal_prepped = 0; +int needs_update = 0; +int bt_mode = 0; +int bt_state = 0; +static char bt_buf[0x100]; +static char udp_buf[0x100]; +int bt_index; +int udp_index; +int udp_size; + +void +show_splash(U32 milliseconds) { - return bt_avail(); + display_clear(0); + display_goto_xy(4, 6); + display_string("Gforth NXT"); + display_update(); + + systick_wait_ms(milliseconds); } -Cell getkey() +const static bt_lens[0x3C] = { 10, 3, 10, 3, 10, 30, 10, 3, 4, 4, 26, 4, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, + 0, 19, 0, 4, 0, 3, 0, 3, 0, 3, 3, 3, 0, 0, 0, 3, + 0, 0, 0, 3, 5, 0, 3, 4, 0, 3, 0, 3, 0 }; + +void bt_send_cmd(char * cmd) { - return bt_getkey(); + int len = bt_lens[cmd[1]]; + int i, sum=0; + + cmd[0] = len; + for(i=1; i>8); + cmd[i++] = (char)(sum & 0xff); + + // systick_wait_ms(500); + + bt_send(cmd, len+1); } -int terminal_prepped = 0; +int do_bluetooth () +{ + if(!bt_mode) { + char cmd[30]; + + bt_receive(cmd); + if(cmd[0]) { + display_goto_xy(0,1); + display_hex(cmd[0],2); + display_goto_xy(3,1); + display_hex(cmd[1],2); + } + + switch(cmd[1]) { + case 0x16: // request connection + display_char('-'); + cmd[1] = 0x9; // accept connection + cmd[2] = 1; // yes, we do + bt_send_cmd(cmd); + break; + case 0x0f: // inquiry result + display_char('+'); + cmd[1] = 0x05; + bt_send_cmd(cmd); // add devices as known device + break; + case 0x13: // connect result + if(cmd[2]) { + int n=0; + int handle=cmd[3]; + display_char('/'); display_update(); + systick_wait_ms(300); + bt_receive(cmd); + if(cmd[0]==0) { + cmd[1] = 0xB; // open stream + cmd[2] = handle; + bt_send_cmd(cmd); + systick_wait_ms(100); + bt_set_arm7_cmd(); + bt_mode = 1; + display_char(')'); display_update(); + type_chars("Gforth NXT\n", 11); + } + // bt_state = 1; + } else { + display_char('('); + } + break; + case 0x20: // discoverableack + if(cmd[2]) { + display_char('?'); + cmd[1] = 0x03; bt_send_cmd(cmd); // open port query + break; + } + case 0x10: + case 0x14: + display_char('!'); + cmd[1] = 0x1C; cmd[2] = 1; bt_send_cmd(cmd); + break; + default: + break; + } + display_update(); + } + return bt_mode; +} void prep_terminal () { + char cmd[30]; + aic_initialise(); interrupts_enable(); systick_init(); - display_init(); + sound_init(); + nxt_avr_init(); + nxt_motor_init(); + i2c_init(); bt_init(); + udp_init(); + display_init(); + show_splash(2000); + display_goto_xy(0,0); + display_string("BT Reset "); + display_update(); + // bt_reset(); + display_string("ok"); + display_update(); + bt_buf[0] = 0; + bt_buf[1] = 0; + bt_index = 0; + // bt_start_ad_converter(); + // do { + // bt_receive(cmd); + // } while((cmd[0] != 3) && (cmd[1] != 0x14)); + // cmd[1] = 0x36; // break stream mode + // cmd[2] = 0; + // bt_send_cmd(cmd); + // cmd[1] = 0x1C; cmd[2] = 1; bt_send_cmd(cmd); // make visible + display_string("."); + display_goto_xy(0,1); + display_update(); + while(!do_bluetooth() && !udp_configured()); terminal_prepped = 1; } @@ -54,16 +187,80 @@ void deprep_terminal () terminal_prepped = 0; } +long key_avail () +{ + if(!terminal_prepped) prep_terminal(); + + if(do_bluetooth()) { + return bt_buf[0] - bt_index; + } else if(udp_configured()) { + return udp_size - udp_index; + } else { + systick_wait_ms(100); + return 0; + } +} + +Cell getkey() +{ + int key; + + if(!terminal_prepped) prep_terminal(); + + if(needs_update) { + display_update(); + needs_update = 0; + } + + do { + if(do_bluetooth()) { + while(bt_index >= bt_buf[0]) { + bt_receive(bt_buf); + bt_index = 0; + } + key = bt_buf[bt_index++]; + } else if(udp_configured()) { + if(udp_index < udp_size) { + key = udp_buf[udp_index++]; + } else { + udp_size = udp_read(udp_buf, 0x100); + udp_index = 0; + key = 0; + } + } else { + key = 0; + } + } while(!key); + + display_char(key); display_update(); + + return key; +} + void emit_char(char x) { - bt_send(&x, 1); - display_char(x); + char buf[3]; + if(!terminal_prepped) prep_terminal(); + if(bt_mode) { + buf[0] = 1; + buf[1] = 0; + buf[2] = x; + bt_send(buf, 3); + } } void type_chars(char *addr, unsigned int l) { int i; - bt_send(addr, l); - for(i=0; i