OSDN Git Service

* public snapshot of sid simulator
[pf3gnuchains/pf3gnuchains3x.git] / sid / demos / voice-pager / VoicePager.cxx
1 // VoicePager.cxx - description.  -*- C++ -*-
2
3 // Copyright (C) 1999, 2000 Red Hat.
4 // This file is part of SID and is licensed under the GPL.
5 // See the file COPYING.SID for conditions for redistribution.
6
7 // This is the main controller will send msgs to rtc, lcd, and snack.
8 // Gets input from  parallel port and also has look up table.
9
10 #include <stdio.h>
11 #include "VoicePager.h"
12
13 static const int TIME_DIFFHRS = 7;      // CA time(-3) and no light sav. (-4)
14
15 static const int MAX_IDNUM = 20;        // max num of messages to be stored
16 static const int MAX_RNDTELNUM = 12;    // max num of random telphone numbers.
17
18 VoicePager::VoicePager()
19 {
20   lcdpager_ptr = new PagerUI(lcd_drobj);
21   record_process = play_process = 0;
22   last_cmd = inuse_idnum = 0;
23   init_idvector();
24   init_rndtelnum();
25
26   for (unsigned char k = 1; k <= MAX_IDNUM; ++k)
27     rec_msgs[k] = string ();
28 }
29
30 VoicePager::~VoicePager()
31 {
32   delete lcdpager_ptr;
33 }
34
35 void 
36 VoicePager::initialize_components()
37 {
38   initialize_lcd();
39
40   pport_drobj.set_ctl(0xF0); // keeping bits 4 & 5 1
41
42   time_t time_val = time(NULL);
43   // time_val -= (TIME_DIFFHRS * 60 * 60); 
44   initialize_rtc(time_val);
45 }
46
47 void
48 VoicePager::init_idvector()
49
50   // Store 1-20 id numbers for snack.
51   for (unsigned char i = 1; i <= MAX_IDNUM; ++i)
52     id_arr.push_back (i);  
53
54
55 void
56 VoicePager::poll_input()
57 {
58   unsigned char curr_cmd = CMD_CLR; // no key depressed
59
60   for ( ; ; )
61     {
62       //     curr_cmd = pport_drobj.read_parport_data(); 
63       // read parallel port PR register
64       curr_cmd = pport_drobj.get_prreg();
65           
66       if (last_cmd != curr_cmd) 
67         {
68           last_cmd = curr_cmd;
69           switch (curr_cmd) {
70           case CMD_UP: 
71             // up button 
72             scroll_up();
73             break;
74
75           case CMD_DN:
76             // down button
77             scroll_down();
78             break;
79
80           case CMD_REC:
81             // Record_pin
82             if (!record_process) 
83               {         // no recording currently in process
84                 if (!play_process)
85                   {     // no play currently in process
86                     record_newmsg();
87                   }
88                 else
89                   {  // Non Blocking play in process. Lets check
90                     if (! play_done() )
91                       display_msg ("Currently Play in Process");
92                     else 
93                       record_newmsg(); // Recording message
94                   }
95               }
96             else
97               {
98                 display_msg ("Prev. Recording in Process");
99               }
100             break;
101
102           case CMD_PLAY:
103             // Play Pin 
104             if  (! play_process)
105               {         // Not Playing any message
106                 if (! record_process)
107                   {     // Not Recoding any message
108                     play_storedmsg();
109                   }
110                 else 
111                   display_msg ("Recording in Process");
112               }
113             else 
114               {
115                 if ( !play_done() )
116                   display_msg ("Play in Process");
117                 else
118                   play_storedmsg();
119               }
120             break;
121
122           case CMD_DEL:
123             // Delete Pin
124             delete_storedmsg ();
125             break;
126
127           case CMD_DONE:
128             // Done Pin - exit program!
129             return;
130
131           case CMD_STOP:
132             // Stop Pin
133             stop_recmsg ();
134             break;
135
136           case CMD_CLR:
137             break;
138
139           default:
140             cerr << " current value of command is  "    << curr_cmd << "\n";
141             break;
142           }
143         }
144
145       if (record_process)
146         adac_drobj.poll_read ();
147       if (play_process)
148         adac_drobj.poll_write ();
149
150       if (record_process && crossed_reclimit())
151         stop_recmsg();
152     }
153 }
154
155 void
156 VoicePager::scroll_up()
157 {
158   lcdpager_ptr -> up();
159   lcdpager_ptr -> draw_screen();
160 }
161
162 void
163 VoicePager::scroll_down()
164 {
165   lcdpager_ptr -> down();
166   lcdpager_ptr -> draw_screen();
167 }
168
169 void 
170 VoicePager::record_newmsg()
171 {
172   if (id_arr.size())
173     {
174       // if size is > 0. New messages can be stored
175       unsigned char avail_id = id_arr[ id_arr.size() - 1 ];
176       id_arr.pop_back();
177
178       string curr_msgtime = get_rtctime(); 
179       string caller_num = get_rndtelnum();
180       string blank_str = " ";
181       string curr_fullmsg = curr_msgtime + blank_str;
182       curr_fullmsg = curr_fullmsg + caller_num;
183
184       record_process = 1; // record in process
185
186       display_msg ("Recording...");
187
188       adac_drobj.begin_read ();
189
190       set_hardrectime(); // set time for max record time
191       inuse_idnum = avail_id; // id number currently in use.
192       lcdpager_ptr -> append(avail_id, curr_fullmsg); // update lcd
193       lcdpager_ptr -> draw_screen();
194     }
195   else {
196     display_msg ("Maximum 20 messages");
197   }
198
199 }
200
201 void
202 VoicePager::play_storedmsg()
203 {
204   unsigned char play_id = lcdpager_ptr -> current_id();
205   if ( play_id != 0 )
206     {
207       send_dacdata(play_id); // send data from target to sound component
208       play_process = 1;
209       inuse_idnum = play_id;
210       // play_snd (play_id); // play sound use send_dacdata
211
212       display_msg ("Playing back...");
213     }
214   else 
215     display_msg ("No message to play"); 
216 }
217
218 void
219 VoicePager::delete_storedmsg()
220 {
221   unsigned char del_msgid = lcdpager_ptr -> current_id();
222   if (del_msgid != 0)
223     {
224       if (del_msgid != inuse_idnum)
225         {
226           delete_msg(del_msgid);
227         }
228       else
229         {
230           if (record_process)
231             display_msg ("Message in record process");
232           else
233             { 
234               if (!play_done() )
235                 display_msg ("Message in play process");
236               else 
237                 delete_msg(del_msgid);
238             }
239         }
240     }
241   else if (del_msgid == 0) display_msg ("No message to Delete");
242 }
243
244 void
245 VoicePager::stop_recmsg()
246 {
247   if ( inuse_idnum > 0)
248     {
249       //      stop_snd (inuse_idnum);
250       //      cout << "entered stop \n";
251       if ((record_process) && (play_process))
252         cerr << " ERROR record & play both in process?? \n";
253
254       else 
255         {
256           if (record_process)
257             {
258               get_adcdata (inuse_idnum); // also call stop snd 
259               clear_hardrectime();
260               //              cout << " stop draw screen \n";
261               lcdpager_ptr -> draw_screen(); // RON brought this
262             }
263
264           else if (play_process)
265             stop_playmsg(inuse_idnum); 
266          
267           inuse_idnum    = 0;
268           record_process = 0;
269           play_process   = 0;
270         }
271     }
272   else
273     {
274       display_msg ("No message to Stop");
275     }
276   //  cout << "Exiting stop \n";
277 }
278
279 string
280 VoicePager::get_rndtelnum()
281 {
282   int temp_rndnum = rand();
283   temp_rndnum %= MAX_RNDTELNUM;
284   return rnd_telnum[temp_rndnum];
285 }   
286
287
288 void
289 VoicePager::init_rndtelnum()
290 {
291   rnd_telnum.push_back("416-482-6299");
292   rnd_telnum.push_back("770-594-3180");
293   rnd_telnum.push_back("408-542-9604");
294   rnd_telnum.push_back("408-542-9600");
295   rnd_telnum.push_back("416-482-2813");
296   rnd_telnum.push_back("780-434-4261");
297   rnd_telnum.push_back("770-649-0922");
298   rnd_telnum.push_back("800-668-0917");
299   rnd_telnum.push_back("800-269-8463");
300   rnd_telnum.push_back("800-284-6781");
301   rnd_telnum.push_back("408-542-9601");
302   rnd_telnum.push_back("416-743-7625");
303   rnd_telnum.push_back("780-492-7452");
304 }
305
306
307 void
308 VoicePager::display_msg(string temp_msg)
309 {
310   unsigned NCOLS = lcd_drobj.get_numcols();
311
312   clear_lcddisplay();  
313   //  string sorry_msg = "Sorry...";
314
315   // show_lcdmsg (sorry_msg, 1*NCOLS);
316   show_lcdmsg (temp_msg,  2*NCOLS);
317
318   // wait for one second
319   unsigned char waitstart, now;
320   read_rtcseconds(waitstart);
321   read_rtcseconds(now);
322   while (now == waitstart)
323     {
324       for (unsigned long j = 0; j < 10000; ++j) ;
325       read_rtcseconds(now);
326     }
327
328   lcdpager_ptr -> draw_screen(); // Back to origiunal screen.
329 }
330
331 void
332 VoicePager::clear_lcddisplay ()
333 {
334   unsigned NCOLS = lcd_drobj.get_numcols();
335   unsigned NROWS = lcd_drobj.get_numrows();
336
337   lcd_drobj.mem_set (0, 0, NROWS*NCOLS);
338 }
339
340 void
341 VoicePager::show_lcdmsg (string lcd_msg, unsigned lcd_rowcolval)
342 {
343    
344   lcd_drobj.set_word_reg( lcd_driver::SET_ADP, lcd_rowcolval, 0 );  
345   lcd_drobj.send_cmd( lcd_driver::SET_AWRITE);
346   for ( unsigned j=0; j < lcd_msg.size(); j++)
347     lcd_drobj.auto_write ( lcd_msg[j] - ' ');
348   lcd_drobj.reset_auto( 8 );
349 }
350
351  
352 bool
353 VoicePager::play_done()
354 {
355   if (adac_drobj.count_pending_write() == 0)
356     {
357       play_process = 0;
358       inuse_idnum = 0;
359       return true;
360     }
361   else
362     {
363       return false;
364     }
365 }
366
367
368 void
369 VoicePager::delete_msg(unsigned char del_msgid)
370 {
371   remove_storedmsg (del_msgid);
372   lcdpager_ptr -> delete_selected ();
373   lcdpager_ptr -> draw_screen ();
374   id_arr.push_back (del_msgid);
375 }
376
377
378 void
379 VoicePager::set_hardrectime()
380 {
381   read_rtcseconds(rec_curtime);
382   rec_seccounter = 0;
383 }               
384
385 void
386 VoicePager::clear_hardrectime()
387 {
388   rec_seccounter = 0;
389 }
390
391 bool
392 VoicePager::crossed_reclimit()
393 {
394   unsigned char curr_seconds;
395   read_rtcseconds(curr_seconds); // Reading from RTC
396  
397   if ( curr_seconds != rec_curtime)
398     {
399       unsigned char diff_secs = 0;
400
401       if ( curr_seconds > rec_curtime)
402         {
403           diff_secs = (curr_seconds - rec_curtime); 
404           rec_curtime += diff_secs;
405         }
406
407       else if ( curr_seconds < rec_curtime) 
408         {
409           diff_secs = (curr_seconds + 1 + 59) - rec_curtime;
410           rec_curtime += diff_secs - 59 - 1;
411           /*   if ( rec_curtime < 0)
412                {
413                cerr << " ERROR rec time < 0 \n";
414                rec_time = 0;
415                }*/
416         }
417       return (increase_reccounter(diff_secs));
418     }
419   else
420     return false;
421 }
422
423 bool
424 VoicePager::increase_reccounter(unsigned char incr_secs)
425 {
426   if (incr_secs > 0)
427     {
428       rec_seccounter+=incr_secs ;
429       return ( (rec_seccounter > TIME_LIMIT)? true : false) ;
430     }
431   else 
432     {
433       cerr << " ERROR increment time is < 0\n ";
434       return true; // lets disconnect this recording 
435     }
436 }
437
438 void
439 VoicePager::initialize_rtc (time_t init_time)
440 {
441   struct tm* curr_time;
442
443   rtc_drobj.set_writemode();
444   curr_time = localtime(&init_time);
445  
446   rtc_drobj.set_century ((1900 + curr_time -> tm_year) / 100);
447   rtc_drobj.set_year ((1900 + curr_time -> tm_year) % 100);
448   rtc_drobj.set_month ((curr_time -> tm_mon) + 1);
449   rtc_drobj.set_date (curr_time -> tm_mday);
450   rtc_drobj.set_day  ((curr_time -> tm_wday) + 1);
451   rtc_drobj.set_hour (curr_time -> tm_hour);
452   rtc_drobj.set_minutes ( curr_time -> tm_min);
453   rtc_drobj.set_seconds ( ((curr_time -> tm_sec) > 59) ? 59:(curr_time ->tm_sec) );
454
455   rtc_drobj.clear_writemode ();
456 }       
457
458
459 string
460 VoicePager::get_rtctime ()
461 {
462   unsigned char yy, mm, dt, hh, min;
463
464   rtc_drobj.set_readmode ();
465
466   rtc_drobj.read_year(yy);
467   rtc_drobj.read_month(mm);
468   rtc_drobj.read_date(dt);
469   rtc_drobj.read_hour(hh);
470   rtc_drobj.read_minutes(min);
471
472   rtc_drobj.clear_readmode();
473   
474   unsigned int y_val = yy;
475   unsigned int mon_val = mm;
476   unsigned int dt_val = dt;
477   unsigned int h_val = hh;
478   unsigned int min_val = min;
479
480   char s[20];
481   sprintf (s, "%d", mon_val); // at most 2 chars
482   unsigned int len = strlen(s);
483   s[len] = '/';
484   sprintf (&s[++len], "%d", dt_val);// at most 2 chars
485   len = strlen (s); 
486   s[len] =  '/';
487   sprintf (&s[++len], "%d", y_val);// at most 2 chars
488   len = strlen (s); 
489   s[len] = ' ';
490   if ( h_val < 10)
491     {                   // if value is one digit put space first
492       s[++len] = ' ';
493     }   
494   sprintf (&s[++len], "%d", h_val);
495   len = strlen (s); 
496   s[len] = ':';
497   sprintf (&s[++len], "%d", min_val);
498   if ( min_val < 10)
499     {                   // if min value is less than 10 put space after
500       s[++len] = ' ';
501       s[++len] = 0 ;    // null terminate the array
502         
503     }
504   string rtc_time (s);  // convert from char* to string
505   return rtc_time;
506 }   
507
508 void 
509 VoicePager::read_rtcseconds(unsigned char& sec_val)
510 {
511   rtc_drobj.set_readmode(); 
512   rtc_drobj.read_seconds (sec_val);
513   rtc_drobj.clear_readmode(); 
514 }
515
516 void
517 VoicePager::initialize_lcd ()
518 {
519   unsigned NCOLS = lcd_drobj.get_numcols();
520   unsigned NROWS = lcd_drobj.get_numrows();
521
522   //intialize the display
523   lcd_drobj.set_word_reg( lcd_driver::SET_TXT_HOME, 0x00, 0x00 );
524   lcd_drobj.set_word_reg( lcd_driver::SET_TXT_AREA, NCOLS, 0 );
525   lcd_drobj.set_word_reg( lcd_driver::SET_GRX_HOME, 0x00, 0x02 );
526   lcd_drobj.set_word_reg( lcd_driver::SET_GRX_AREA, NCOLS, 0 );
527
528   // mode set: OR mode, internal cgen
529   lcd_drobj.send_cmd( 0x80 );                   
530
531   // display: text on, graphics off, no cursor
532   lcd_drobj.send_cmd( 0x94 );
533
534   lcd_drobj.mem_set( 0, 0, NCOLS*NROWS );               // clear display
535
536   lcd_drobj.set_word_reg( lcd_driver::SET_OFFSET, 2, 0 );
537   lcd_drobj.set_word_reg( lcd_driver::SET_ADP, 0, 0x14 );       // cgen area is 0x1400
538
539   lcd_drobj.send_cmd( lcd_driver::SET_AWRITE );
540
541   lcd_drobj.auto_write( 0x8 );  // initialize the arrow
542   lcd_drobj.auto_write( 0xc );
543   lcd_drobj.auto_write( 0xe );
544   lcd_drobj.auto_write( 0xf );
545   lcd_drobj.auto_write( 0xe );
546   lcd_drobj.auto_write( 0xc );
547   lcd_drobj.auto_write( 0x8 );
548   lcd_drobj.auto_write( 0x0 );
549
550   lcd_drobj.reset_auto( 8 );
551 }
552
553
554 void
555 VoicePager::get_adcdata(unsigned char id_num)
556 {
557   string sound = adac_drobj.finish_read ();
558   rec_msgs[id_num] = sound;
559 }
560
561
562 void
563 VoicePager::send_dacdata(unsigned char id_num)
564 {
565   adac_drobj.begin_write (rec_msgs [id_num]);
566 }
567
568
569 void
570 VoicePager::remove_storedmsg (unsigned char del_id)
571 {
572   rec_msgs[del_id] = string();
573
574
575
576 void
577 VoicePager::stop_playmsg (unsigned char play_id)
578 {
579   adac_drobj.finish_write ();
580 }
581
582