OSDN Git Service

lejos_NXJ_win32_0_5_0beta.zip
[nxt-jsp/lejos_nxj.git] / nxtOSEK / lejos_nxj / src / nxtvm / platform / nxt / bt.c
1 #include "mytypes.h"
2 #include "AT91SAM7.h"
3 #include "uart.h"
4 #include "bt.h"
5 #include "aic.h"
6 #include  <string.h>
7 #include "display.h"
8 #include "systick.h"
9
10 static U8 in_buf[2][128];
11 static U8 in_buf_in_ptr, out_buf_ptr;
12 static U8 out_buf[2][256];
13
14 static U8* buf_ptr;
15
16 static int in_buf_idx = 0;
17
18 #define BAUD_RATE 460800
19 #define CLOCK_RATE 48054850
20
21         
22 void bt_init(void)
23 {
24   U8 trash;
25   U32 trash2;
26   in_buf_in_ptr = out_buf_ptr = 0; 
27   in_buf_idx = 0;
28   
29   *AT91C_PMC_PCER = (1 << AT91C_PERIPHERAL_ID_US1); 
30   
31   *AT91C_PIOA_PDR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; 
32   *AT91C_PIOA_ASR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; 
33   
34   *AT91C_US1_CR   = AT91C_US_RSTSTA;
35   *AT91C_US1_CR   = AT91C_US_STTTO;
36   *AT91C_US1_RTOR = 10000; 
37   *AT91C_US1_IDR  = AT91C_US_TIMEOUT;
38   *AT91C_US1_MR = (AT91C_US_USMODE_HWHSH & ~AT91C_US_SYNC) | AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT | AT91C_US_OVER;
39   *AT91C_US1_BRGR = ((CLOCK_RATE/8/BAUD_RATE) | (((CLOCK_RATE/8) - ((CLOCK_RATE/8/BAUD_RATE) * BAUD_RATE)) / ((BAUD_RATE + 4)/8)) << 16);
40   *AT91C_US1_PTCR = (AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); 
41   *AT91C_US1_RCR  = 0; 
42   *AT91C_US1_TCR  = 0; 
43   *AT91C_US1_RNPR = 0;
44   *AT91C_US1_TNPR = 0;
45   
46   aic_mask_off(AT91C_PERIPHERAL_ID_US1);
47   aic_clear(AT91C_PERIPHERAL_ID_US1);
48
49   trash = *AT91C_US1_RHR;
50   trash = *AT91C_US1_CSR;
51   
52   *AT91C_US1_RPR  = (unsigned int)&(in_buf[0][0]); 
53   *AT91C_US1_RCR  = 128;
54   *AT91C_US1_RNPR = (unsigned int)&(in_buf[1][0]);
55   *AT91C_US1_RNCR = 128;
56   *AT91C_US1_CR   = AT91C_US_RXEN | AT91C_US_TXEN; 
57   *AT91C_US1_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN); 
58   
59   *AT91C_PIOA_PDR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; 
60   *AT91C_PIOA_ASR = BT_RX_PIN | BT_TX_PIN | BT_SCK_PIN | BT_RTS_PIN | BT_CTS_PIN; 
61   *AT91C_PIOA_PER   = BT_CS_PIN | BT_RST_PIN; 
62   *AT91C_PIOA_OER   = BT_CS_PIN | BT_RST_PIN; 
63   *AT91C_PIOA_SODR  = BT_CS_PIN | BT_RST_PIN;
64   *AT91C_PIOA_PPUDR = BT_ARM7_CMD_PIN;
65   *AT91C_PIOA_PER   = BT_ARM7_CMD_PIN; 
66   *AT91C_PIOA_CODR  = BT_ARM7_CMD_PIN;
67   *AT91C_PIOA_OER   = BT_ARM7_CMD_PIN; 
68   // Configure timer 01 as trigger for ADC, sample every 0.5ms
69   *AT91C_PMC_PCER = (1 << AT91C_PERIPHERAL_ID_TC1); 
70   *AT91C_TC1_CCR = AT91C_TC_CLKDIS;
71   *AT91C_TC1_IDR = ~0;
72   trash2 = *AT91C_TC1_SR;
73   *AT91C_TC1_CMR = AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_SET | AT91C_TC_ACPC_CLEAR | AT91C_TC_ASWTRG_SET; /* MCLK/2, wave mode 10 */
74   *AT91C_TC1_RC = (CLOCK_FREQUENCY/2)/(2000);
75   *AT91C_TC1_RA = (CLOCK_FREQUENCY/2)/(4000);
76   *AT91C_TC1_CCR = AT91C_TC_CLKEN;
77   *AT91C_TC1_CCR = AT91C_TC_SWTRG;
78
79   *AT91C_PMC_PCER = (1 << AT91C_PERIPHERAL_ID_ADC); 
80   *AT91C_ADC_MR  = 0;
81   *AT91C_ADC_MR |= AT91C_ADC_TRGEN_EN | AT91C_ADC_TRGSEL_TIOA1;
82   *AT91C_ADC_MR |= 0x00003F00;
83   *AT91C_ADC_MR |= 0x00020000;
84   *AT91C_ADC_MR |= 0x09000000;
85   *AT91C_ADC_CHER  = AT91C_ADC_CH6 | AT91C_ADC_CH4; 
86   
87   buf_ptr = &(in_buf[0][0]);
88 }
89
90 void bt_start_ad_converter()
91 {
92   // This method is no longer required. The ADC is started automatically
93   // by the hardware timer.
94 }
95
96 U32 bt_get_mode()
97 {
98   // return the bt4 mode value.
99   return (U32) *AT91C_ADC_CDR6;
100 }
101
102 void bt_send(U8 *buf, U32 len)
103 {
104   if (*AT91C_US1_TNCR == 0)
105   {
106     memcpy(&(out_buf[out_buf_ptr][0]), buf, len);
107     *AT91C_US1_TNPR = (unsigned int) &(out_buf[out_buf_ptr][0]);
108     *AT91C_US1_TNCR = len;
109     out_buf_ptr = (out_buf_ptr+1) % 2;
110   }
111 }
112
113 U32 bt_write(U8 *buf, U32 off, U32 len)
114 {
115   if (*AT91C_US1_TNCR == 0)
116   {     
117     if (len > 256) len = 256;   
118     memcpy(&(out_buf[out_buf_ptr][0]), buf+off, len);
119     *AT91C_US1_TNPR = (unsigned int) &(out_buf[out_buf_ptr][0]);
120     *AT91C_US1_TNCR = len;
121     out_buf_ptr = (out_buf_ptr+1) % 2;
122     return len;
123   }
124   else
125     return 0;
126 }
127
128 U32 bt_pending()
129 {
130   // return the state of any pending i/o requests one bit for input one bit
131   // for output.
132   // First check for any input
133   int ret = 0;
134   int bytes_ready;
135   if (*AT91C_US1_RNCR == 0) 
136     bytes_ready = 256 - *AT91C_US1_RCR;
137   else 
138     bytes_ready = 128 - *AT91C_US1_RCR;
139   if (bytes_ready  > in_buf_idx) ret |= 1;
140   if ((*AT91C_US1_TCR != 0) || (*AT91C_US1_TNCR != 0)) ret |= 2;
141   return ret;
142 }
143
144
145 void bt_clear_arm7_cmd(void)
146 {
147   *AT91C_PIOA_CODR  = BT_ARM7_CMD_PIN;
148 }
149
150 void bt_set_arm7_cmd(void)
151 {
152   *AT91C_PIOA_SODR  = BT_ARM7_CMD_PIN;
153 }
154
155 void bt_set_reset_high(void)
156 {
157   *AT91C_PIOA_SODR = BT_RST_PIN;
158 }
159
160 void bt_receive(U8 * buf)
161 {
162   int bytes_ready, total_bytes_ready;
163   int cmd_len, i;
164   U8* tmp_ptr;
165   
166   buf[0] = 0;
167   buf[1] = 0;
168   
169   if (*AT91C_US1_RNCR == 0) {
170         bytes_ready = 128;
171         total_bytes_ready = 256 - *AT91C_US1_RCR;
172   }
173   else total_bytes_ready = bytes_ready = 128 - *AT91C_US1_RCR;
174   
175   // At least 2 bytes ready to be processed?
176   
177   if (total_bytes_ready > in_buf_idx + 1)
178   {
179         cmd_len = (int) buf_ptr[in_buf_idx];
180         
181         // Data mode kludge - data cannot be more than 255 bytes
182         
183         if (in_buf_idx < 127)
184         {
185                 if (buf_ptr[in_buf_idx+1] == 0) cmd_len++;
186         } 
187         else
188         {
189           tmp_ptr = &(in_buf[(in_buf_in_ptr+1)%2][0]);
190       if (tmp_ptr[0] == 0) cmd_len++;
191         }
192
193     // Is whole command in the buffer?
194   
195     if (bytes_ready >= in_buf_idx + cmd_len + 1)
196     {   
197           for(i=0;i<cmd_len+1;i++) buf[i] = buf_ptr[in_buf_idx++];
198     }
199     else
200     {
201       if (total_bytes_ready >= in_buf_idx + cmd_len + 1)
202       {
203         for(i=0;i<cmd_len+1 && in_buf_idx < 128;i++) buf[i] = buf_ptr[in_buf_idx++];
204         in_buf_idx = 0;
205         tmp_ptr = &(in_buf[(in_buf_in_ptr+1)%2][0]);
206         for(;i<cmd_len+1;i++) buf[i] = tmp_ptr[in_buf_idx++];
207         in_buf_idx += 128;
208       }
209       else return; // wait for all bytes to be ready
210     } 
211   }
212   
213   // Current buffer full and fully processed
214   
215   if (in_buf_idx >= 128 && *AT91C_US1_RNCR == 0)
216   {     
217         // Switch current buffer, and set up next 
218         
219         in_buf_idx -= 128;
220         *AT91C_US1_RNPR = (unsigned int) buf_ptr;
221         *AT91C_US1_RNCR = 128;
222         in_buf_in_ptr = (in_buf_in_ptr+1) % 2;
223         buf_ptr = &(in_buf[in_buf_in_ptr][0]);
224   }   
225 }
226
227 U32 bt_read(U8 * buf, U32 off, U32 len)
228 {
229   int bytes_ready, total_bytes_ready;
230   int cmd_len, i;
231   U8* tmp_ptr;
232   
233   cmd_len = 0;
234   if (*AT91C_US1_RNCR == 0) {
235     bytes_ready = 128;
236     total_bytes_ready = 256 - *AT91C_US1_RCR;
237   }
238   else
239     total_bytes_ready = bytes_ready = 128 - *AT91C_US1_RCR;
240   
241   if (total_bytes_ready > in_buf_idx)
242   {
243     cmd_len = (int) (total_bytes_ready - in_buf_idx);
244     if (cmd_len > len) cmd_len = len;
245         
246     if (bytes_ready >= in_buf_idx + cmd_len)
247     {   
248       for(i=0;i<cmd_len;i++) buf[off+i] = buf_ptr[in_buf_idx++];
249     }
250     else
251     {
252       for(i=0;i<cmd_len && in_buf_idx < 128;i++) buf[off+i] = buf_ptr[in_buf_idx++];
253       in_buf_idx = 0;
254       tmp_ptr = &(in_buf[(in_buf_in_ptr+1)%2][0]);
255       for(;i<cmd_len;i++) buf[off+i] = tmp_ptr[in_buf_idx++];
256       in_buf_idx += 128;
257     } 
258   }
259   
260   // Current buffer full and fully processed
261   
262   if (in_buf_idx >= 128 && *AT91C_US1_RNCR == 0)
263   {     
264         // Switch current buffer, and set up next 
265         
266         in_buf_idx -= 128;
267         *AT91C_US1_RNPR = (unsigned int) buf_ptr;
268         *AT91C_US1_RNCR = 128;
269         in_buf_in_ptr = (in_buf_in_ptr+1) % 2;
270         buf_ptr = &(in_buf[in_buf_in_ptr][0]);
271   }
272   return cmd_len;   
273 }
274
275 void bt_set_reset_low(void)
276 {
277   *AT91C_PIOA_CODR = BT_RST_PIN;
278 }
279
280 void bt_reset(void)
281 {
282   // Perform hardware reset. This function has some relatively long
283   // delays in it and so should probably only be called during application
284   // initialisation and termination. Calling it at other times may cause
285   // problems for other real time tasks.
286
287   // If power is currently off to the BC4 do not reset it!
288   if ((*AT91C_PIOA_ODSR & BT_RST_PIN) == 0) return; 
289   //display_goto_xy(0, 1);
290   //display_string("BT Reset....");
291   //display_update();
292   //systick_wait_ms(10000);
293   // Ask for command mode
294   bt_clear_arm7_cmd();
295   // BC4 reset sequence. First take the reset line low for 100ms
296   bt_set_reset_low();
297   // Wait and discard any packets that may be around
298   int cnt = 100;
299   U8 *buf = out_buf[0];
300   while (cnt-- > 0)
301   {
302     bt_receive(buf);
303     systick_wait_ms(1);
304   }
305   bt_set_reset_high();
306   // Now wait either for 5000ms or for the BC4 chip to signal reset
307   // complete. Note we use the out buffer as a scratch area here
308   // this id safe since we are forcing a reset.
309   cnt = 5000;
310   while (cnt-- > 0)
311   {
312     bt_receive(buf);
313     // Look for the reset indication and the checksum
314     if ((buf[0] == 3) && (buf[1] == MSG_RESET_INDICATION) && 
315         (buf[2] == 0xff) && (buf[3] == 0xe9))
316         break;
317     systick_wait_ms(1);
318   }
319   // Force command mode
320   bt_clear_arm7_cmd();
321   //display_goto_xy(10, 1);
322   //display_int(cnt, 5);
323   //display_update();
324   //systick_wait_ms(10000);
325 }