Dave Clarke / Mbed OS Talking_breathalyzer

Dependencies:   Hexi_KW40Z Hexi_OLED_SSD1351 text_to_speak_mbed

Fork of iBreathe_Breathalyzer by Dave Clarke

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /****************************************************************************
00002 * Title                 :   iBreathe Breathalyzer
00003 * Filename              :   Talking_breathalyzer
00004 * Author                :   Dave Clarke
00005 * Origin Date           :   27/09/2016
00006 * Notes                 :   Breathalyzer utilizing Hexiware, Alcohol click and 
00007                             Wolksense. Now with added voice thanks to the 
00008                             Text-To-Speech Click board
00009 *****************************************************************************/
00010 /**************************CHANGE LIST **************************************
00011 *
00012 *    Date    Software Version    Initials       Description
00013 *  07/10/16       1.0.0            DC        Interface Created.
00014 *
00015 *****************************************************************************/
00016 
00017 /**
00018  * @page TEST_CFG Test Configurations
00019  * <h3> Test configuration : </h3>
00020  * @par
00021  * <ul>
00022  * <li><b> MCU           </b> :      MK64FN1M0XXX12               </li>
00023  * <li><b> Dev. Board    </b> :      HEXIWEAR                     </li>
00024  * <li><b> Oscillator    </b> :      12 MHz external              </li>
00025  * <li><b> Ext. Modules  </b> :      Alcohol Click on mikroBUS 1  </li>
00026  * <li><b> Ext. Modules  </b> :      TTS Click on mikroBUS 2      </li>
00027  * <li><b> SW            </b> :      mBed OS5    </li>
00028  * </ul>
00029  */
00030 
00031 /**
00032  * @mainpage
00033  * <h3> Breathalyser created with HEXIWEAR and mBed OS 5 </h3>
00034  * @par This will show you how much you've drunk and tell you with an Emoticon if
00035  * you're too hammered to even consider driving. Using the Hexiware app the readings
00036  * are transmitted to the cloud via bluetooth. Is it time to give up drinking yet?!
00037  * It now talks to you! 
00038  
00039  * <h3> Alcohol Features </h3>
00040  * @par Text to Speech Click, Alcohol click, Hexiwear docking station, Hexiware
00041  */
00042 
00043 /******************************************************************************
00044 * Includes
00045 *******************************************************************************/
00046 
00047 #include "mbed.h"
00048 #include "Hexi_KW40Z.h"
00049 #include "Hexi_OLED_SSD1351.h"
00050 #include "OLED_types.h"
00051 #include "OpenSans_Font.h"
00052 #include "string.h"
00053 #include "iBreatheImages.h"
00054 #include "text_to_speech.h"
00055 #include "text_to_speech_hal.h"
00056 #include "text_to_speech_hw.h"
00057 #include "text_to_speech_img.h"
00058 
00059 
00060 /******************************************************************************
00061 * Module Variable Definitions
00062 *******************************************************************************/
00063 
00064 #define LED_ON      0
00065 #define LED_OFF     1
00066 
00067                           // Pointers to:  
00068 const uint8_t   *welcome, // Welcome screen image
00069                 *blank,   // blank image
00070                 *blow,    // Start Blowing Image
00071                 *drink,   // You've been drinking image
00072                 *drive,   // Don't drive image
00073                 *hang,    // You'll have a hangover image
00074                 *ini,     // Initialising image
00075                 *sober;   // Sober as a judge image
00076 
00077 const float     Vadc_3V3  = 0.00005035;    // 16-Bit ADC step 3V3/65535   = 0.05035 mV
00078        
00079 float           Vrl = 0,                   // Output voltage
00080                 ambientAlc = 0,            // Abmient Output voltage from sensor
00081                 SensorRes = 0,             // SensorRes (Ohm) - Sensor resistance
00082                 SensorRes1 = 0,            // SensorRes (Ohm) - Sensor resistance
00083                 ppm = 0,                   // ppm
00084                 ppm_1 = 0,                 // Ambient ppm variable  
00085                 ratio = 0;                 // SensorRes/LoadRes ratio
00086               
00087 unsigned short  adc_rd = 0; //Initialise anologue read variable
00088 
00089 const uint8_t   ppmText[] = "ppm:"; // text for PPM label
00090 
00091 char            text[20],           // Text array variables
00092                 text2[20],
00093                 text3[20];
00094 
00095 float           value[20],  // initial sensor set up values
00096                 value1[20]; // initial sensor set up values
00097 
00098 bool            isFirstBoot = true;                   
00099               
00100 
00101 /* Indication Flags */
00102 static volatile bool        _tts_rdy_f;
00103 static volatile bool        _spc_rdy_f;
00104 static volatile bool        _tts_fin_f;
00105 static volatile bool        _spc_fin_f;
00106 
00107 /* Error Buffers */
00108 static uint16_t             _req_err;
00109 static uint16_t             _err_code;
00110 
00111 /* Default Configuration */
00112 static ACONF_t              _audio_conf;
00113 static TTSCONF_t            _tts_conf;
00114 static PMANCONF_t           _pman_conf;
00115 
00116 static bool                 _flush_enable;
00117 
00118 /* Timer flag and counter */
00119 static volatile bool        _ticker_f;
00120 static volatile uint16_t    _ticker;
00121 
00122 /* Input and output buffers */
00123 static  ISC_REQ_t   _last_req;
00124 static  ISC_RESP_t  _last_rsp;
00125 
00126 static uint8_t test[ 8 ] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00127 int frequency = 750000;
00128 VER_t *version;
00129 /******************************************************************************
00130 * Function Prototypes
00131 *******************************************************************************/
00132 /* Checks for indications */
00133 static int _parse_ind( void );
00134 
00135 /* Message block and error callback function pointers */
00136 static void ( *_fatal_err_callback )( uint16_t *err_code );
00137 static void ( *_err_callback )( uint16_t *err_code );
00138 static void ( *_msg_block_callback )( uint16_t *msg_code,
00139                                       uint16_t *err_code ); 
00140 
00141 void voiceinit(void);
00142 void sysinit(void);
00143 void ReadSensor();
00144 void CalculatePPM(int times, bool amb);
00145 void ambient(int times);
00146 void StartHaptic(void);
00147 void StopHaptic(void const *n);
00148 void ButtonUp(void);
00149 void txTask(void);
00150 void fatal_err( uint16_t *err );
00151 void msg_blk( uint16_t *req, uint16_t *err );
00152 
00153 /******************************************************************************
00154 * Instance setups
00155 *******************************************************************************/
00156 
00157 
00158 /* Define timer for haptic feedback */
00159 RtosTimer hapticTimer(StopHaptic, osTimerOnce);
00160 
00161 //set up Analog read pin for alcohol sensor
00162 AnalogIn Alcohol(PTB2);
00163 
00164 /* Instantiate the SSD1351 OLED Driver */ 
00165 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); /* (MOSI,SCLK,POWER,CS,RST,DC) */
00166       
00167 /* Get OLED Class Default Text Properties */
00168 oled_text_properties_t textProperties = {0};
00169 
00170 /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */ 
00171 KW40Z kw40z_device(PTE24, PTE25);
00172 
00173 /* LED and Haptic Set ups */
00174 DigitalOut redLed(LED1);
00175 DigitalOut greenLed(LED2);
00176 DigitalOut blueLed(LED3);
00177 DigitalOut haptic(PTB9);
00178 
00179 /* Instantiate the Click Text to Speech pinout */ 
00180 DigitalOut TTS_RST(PTB19);
00181 DigitalOut TTS_CS(PTC3);
00182 DigitalOut TTS_MUTE(PTB3);
00183 DigitalIn  TTS_RDY(PTB8);
00184 
00185 //Instantiate SPI for comms with Speak module
00186 SPI TextToSpeech(PTC6, PTC7, PTC5); // MOSI, MISO, SCK
00187 
00188 // Debug Serial
00189 Serial pc(USBTX, USBRX);
00190 
00191 /******************************************************************************
00192 * Bluetooth button functions and passkey function
00193 *******************************************************************************/
00194 
00195 void ButtonRight(void)
00196 {
00197     StartHaptic();
00198     kw40z_device.ToggleAdvertisementMode();
00199     blueLed = kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
00200     redLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
00201     greenLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
00202 }
00203 
00204 void ButtonLeft(void)
00205 {
00206     StartHaptic();
00207     kw40z_device.ToggleAdvertisementMode();
00208     blueLed = kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
00209     redLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
00210     greenLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
00211 }
00212 
00213 void PassKey(void)
00214 {
00215     StartHaptic();
00216     strcpy((char *) text,"PAIR CODE");
00217     oled.TextBox((uint8_t *)text,0,25,95,18);
00218   
00219     /* Display Bond Pass Key in a 95px by 18px textbox at x=0,y=40 */
00220     sprintf(text3,"%d", kw40z_device.GetPassKey());
00221     oled.TextBox((uint8_t *)text3,0,40,95,18);
00222 }
00223 
00224 /******************************************************************************
00225 * Main
00226 *******************************************************************************/
00227 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00228 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00229 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00230 int main()
00231 {
00232    
00233      
00234      /* Set pointers to the BMPs stored in  iBreatheImages.c */
00235      welcome = iBreatheWS_bmp;    // Welcome screen image 
00236      blank = iBreatheBlank_bmp;   // blank image
00237      blow = iBreatheBlow_bmp;    // Start Blowing Image
00238      drink = iBreatheDrink_bmp;   // You've been drinking image
00239      drive = iBreatheDrive_bmp;   // Don't drive image
00240      hang = iBreatheHang_bmp;    // You'll have a hangover image
00241      ini = iBreatheini_bmp;     // Initialising image
00242      sober = iBreatheSober_bmp;   // Sober as a judge image
00243      
00244     /* Set initial Values */
00245      sysinit(); 
00246     
00247     /* initialise voice engine */  
00248      voiceinit();
00249      
00250     /* Welcome message on reset */    
00251      tts_speak( "Hello, welcome to the eye brethalizer " );
00252      wait(0.5);
00253      tts_speak( "please press start.  " ); 
00254 }
00255 
00256 /******************************************************************************
00257 * Public Function Definitions
00258 *******************************************************************************/
00259 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00260 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00261 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00262 /**************************************************************************************************
00263 * Function readSensor(void)
00264 * -------------------------------------------------------------------------------------------------
00265 * Overview: Read sensor
00266 * Input: None
00267 * Output: None
00268 **************************************************************************************************/
00269 
00270 void ReadSensor()
00271 {
00272     /* Read 16 Bit Analog value */
00273     adc_rd = Alcohol.read_u16();
00274 
00275     // pause 200ms 
00276     Thread::wait(200);
00277 }
00278 
00279 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00280 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00281 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00282 /**************************************************************************************************
00283 * Function CalculatePPM(Int times, bool amb)
00284 * -------------------------------------------------------------------------------------------------
00285 * Overview: Calculation of PPM
00286 * Input: times = Number of samples to take, amb sets either ambient reading or test reading (true for test)
00287 * Output: None
00288 **************************************************************************************************/
00289 
00290 void CalculatePPM(int times, bool amb)
00291 {
00292         float   lgPPM;
00293         
00294         /* Read values x times */
00295         for(int x = 0; x < times; x++)
00296         {
00297             ReadSensor();    
00298             value[x] = ((float)adc_rd  * Vadc_3V3);
00299             StartHaptic();
00300             Thread::wait(50);
00301         }    
00302         
00303         /* Calculate the average value for accuratcy */
00304         for(int y = 0; y < times; y++)
00305         {
00306             Vrl += value[y];
00307         }
00308         Vrl = Vrl / times;       
00309 
00310         /* Set SensorRes reference value */
00311         SensorRes =    (Vrl / 3.3);
00312         
00313         /* Set ratio */
00314         ratio     = SensorRes1 / SensorRes;
00315 
00316         /* Convert to PPM */
00317         lgPPM = ( log10( ratio ) * -1.5512 ) + 2.5911;
00318         
00319         /* If true create test result, flase creates reference result */
00320         if (amb == true)
00321         {
00322             ppm = pow( 10, lgPPM );
00323         }
00324         else
00325         {
00326             ppm_1 = pow( 10, lgPPM );
00327         }    
00328 }
00329 
00330 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00331 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00332 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00333 /**************************************************************************************************
00334 * Function void ambient(int times)
00335 * -------------------------------------------------------------------------------------------------
00336 * Overview: Reading of the Ambient Voltgage of the sensor for reference
00337 * Input: times = Number of samples to take
00338 * Output: None
00339 **************************************************************************************************/
00340 
00341 void ambient(int times)
00342 {
00343     /* Read ambient values x times flashing green led*/
00344     for(int x = 0; x < times; x++)
00345     {
00346         redLed      = LED_OFF;
00347         greenLed    = LED_OFF;
00348         blueLed     = LED_OFF;
00349         
00350         ReadSensor();
00351         value1[x] = (float)adc_rd  * Vadc_3V3; 
00352         
00353         redLed      = LED_OFF;
00354         greenLed    = LED_ON;
00355         blueLed     = LED_OFF;
00356         Thread::wait(48);   
00357     }
00358     
00359     /* Calculate the average value for accuratcy */
00360     for(int y = 0; y < times; y++)
00361     {
00362         ambientAlc+=value1[y];            
00363     }
00364     ambientAlc = ambientAlc / times;
00365   
00366     /* Set SensorRes1 reference value */
00367     SensorRes1 =   (ambientAlc / 3.3);
00368 }
00369 
00370 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00371 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00372 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00373 /**************************************************************************************************
00374 * Function void StartHaptic(void)
00375 * -------------------------------------------------------------------------------------------------
00376 * Overview: Start Buzzing haptic motor
00377 * Input:  None
00378 * Output: None
00379 **************************************************************************************************/
00380 
00381 void StartHaptic(void)
00382 {
00383     hapticTimer.start(50);
00384     haptic = 1;
00385 }
00386 
00387 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00388 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00389 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00390 /**************************************************************************************************
00391 * Function void StopHaptic(void)
00392 * -------------------------------------------------------------------------------------------------
00393 * Overview: Stop Buzzing haptic motor
00394 * Input:  None
00395 * Output: None
00396 **************************************************************************************************/
00397 
00398 void StopHaptic(void const *n) {
00399     haptic = 0;
00400     hapticTimer.stop();
00401 }
00402 
00403 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00404 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00405 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00406 /**************************************************************************************************
00407 * Function void ButtonUp(void)
00408 * -------------------------------------------------------------------------------------------------
00409 * Overview: Function called whe up button pressed, Begins Breathilyzer testing procedure
00410 * Input:  None
00411 * Output: None
00412 **************************************************************************************************/
00413 
00414 void ButtonUp(void)
00415 {
00416     StartHaptic();
00417     
00418     bool Ref = false;
00419     bool Test = true;
00420         
00421     /* LED set to green for test beginning*/
00422     redLed      = LED_OFF;
00423     greenLed    = LED_ON;
00424     blueLed     = LED_OFF;
00425     
00426     /* Fill 96px by 96px Screen with 96px by 96px Initialising Image starting at x=0,y=0 */   
00427     oled.DrawImage(ini,0,0);
00428     
00429     /* first boot bug work around to stop junk values */
00430     if (isFirstBoot == true)
00431     {
00432         /*read ambient atmosphere levels with 10 samples and set flag to show it's ambient basline figure*/
00433         ambient(1);
00434         CalculatePPM(1,Ref);
00435         isFirstBoot = false;
00436     }
00437     
00438     
00439     /*read ambient atmosphere levels with 10 samples and set flag to show it's ambient basline figure*/
00440     tts_speak( "initializing" );
00441     ambient(10);
00442     CalculatePPM(10,Ref);
00443     
00444     
00445     /* Fill 96px by 96px Screen with 96px by 96px Blowing Image starting at x=0,y=0 */  
00446     oled.DrawImage(blow,0,0);
00447     tts_speak( "please blow until buzzing stops" );
00448     /*read breathe alcohol levels with 10 samples and set flag to show it's breathilyzer test figure*/
00449     CalculatePPM(10,Test);
00450     
00451     /*Calculate the difference in Alcohol level based on Ambient and test sample*/
00452     ppm = ppm - ppm_1;
00453     
00454     /*Throw away any values less than 0*/
00455     if (ppm < 0)
00456     {
00457          ppm = 0;
00458     }     
00459     
00460     /* Fill 96px by 96px Screen with 96px by 96px Blank Background Image starting at x=0,y=0 */
00461     oled.DrawImage(blank,0,0);     
00462     tts_speak( "Test Complete" );
00463     Thread::wait(500);
00464     /* Show Calculated alcohol level in PPM and send data via bluetooth to the cloud */
00465     oled.SetTextProperties(&textProperties);
00466     oled.Label(ppmText,20,36);
00467     tts_speak( "you blew" );
00468     sprintf(text,"%.2f",ppm);
00469     Thread::wait(50);
00470     tts_speak( text );
00471     oled.Label((uint8_t *)text,50,36);
00472     Thread::wait(50);
00473     tts_speak( "pee pee emm" );
00474     Thread::wait(1000);
00475     
00476     /* Currently sending to the Pressure variable as a temp place holder */
00477     kw40z_device.SendiBreathe(ppm); // this is used for custom Hexiware app
00478     kw40z_device.SendPressure(ppm * 10); // using this to record on Wolksense Cloud
00479     
00480     
00481     /* You've got a Hangover coming!*/
00482     if ( ppm > 200)
00483     {
00484         tts_speak("you have got a hang over coming");
00485         redLed      = LED_ON;
00486         greenLed    = LED_OFF;
00487         blueLed     = LED_OFF;
00488         
00489         StartHaptic();
00490         
00491         /* Fill 96px by 96px Screen with 96px by 96px Hangover Image starting at x=0,y=0 */
00492         oled.DrawImage(hang,0,0);
00493     }   
00494     
00495     /* You Shouldn't drive */
00496     else if (ppm < 200 && ppm > 150)
00497     {
00498         tts_speak("you shouldn't drive");
00499         redLed      = LED_ON;
00500         greenLed    = LED_OFF;
00501         blueLed     = LED_ON;
00502         
00503         StartHaptic();
00504       
00505         /* Fill 96px by 96px Screen with 96px by 96px Don't Drive Image starting at x=0,y=0 */      
00506         oled.DrawImage(drive,0,0);
00507     } 
00508     
00509     /* You've had a drink */
00510     else if (ppm < 150 && ppm > 50)
00511     {
00512         tts_speak("you have had a drinky");
00513         redLed      = LED_OFF;
00514         greenLed    = LED_ON;
00515         blueLed     = LED_ON;
00516         
00517         StartHaptic();
00518     
00519         /* Fill 96px by 96px Screen with 96px by 96px Had a drink Image starting at x=0,y=0 */     
00520         oled.DrawImage(drink,0,0);
00521     }
00522     
00523     /* Sober as a judge*/   
00524     else
00525     {
00526         tts_speak("you are as sober as a judge");
00527         redLed      = LED_OFF;
00528         greenLed    = LED_ON;
00529         blueLed     = LED_OFF;
00530         
00531         StartHaptic();
00532         oled.DrawImage(sober,0,0);    
00533     }
00534     Thread::wait(5000);
00535     
00536     /* Go back to start screen */
00537     sysinit();   
00538 }
00539 
00540 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00541 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00542 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00543 /**************************************************************************************************
00544 * Function void sysint(void)
00545 * -------------------------------------------------------------------------------------------------
00546 * Overview: System Initial Values Set up
00547 * Input: None
00548 * Output: None
00549 **************************************************************************************************/
00550 void sysinit(void)
00551 {
00552      /* Set LED to Blue by default*/      
00553     redLed      = LED_OFF;
00554     greenLed    = LED_OFF;
00555     blueLed     = LED_ON;
00556     
00557     /* Turn on the backlight of the OLED Display */
00558     oled.DimScreenON();
00559     
00560     /* Fill 96px by 96px Screen with 96px by 96px Welcome Image starting at x=0,y=0 */
00561     oled.DrawImage(welcome,0,0);
00562     
00563     /* Register callbacks to application functions */
00564     kw40z_device.attach_buttonUp(&ButtonUp);
00565     kw40z_device.attach_buttonLeft(&ButtonLeft);
00566     kw40z_device.attach_buttonRight(&ButtonRight);
00567     kw40z_device.attach_passkey(&PassKey);
00568     
00569     /* Send sensor data to bluetooth */
00570     kw40z_device.SendSetApplicationMode(GUI_CURRENT_APP_SENSOR_TAG);
00571     
00572     /* Change font color to White */
00573     oled.GetTextProperties(&textProperties); 
00574     textProperties.fontColor   = COLOR_WHITE;
00575     oled.SetTextProperties(&textProperties);
00576 }
00577 
00578 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00579 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00580 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00581 /**************************************************************************************************
00582 * Function void voiceinit(void)
00583 * -------------------------------------------------------------------------------------------------
00584 * Overview: initialise voice engine
00585 * Input: None
00586 * Output: None
00587 **************************************************************************************************/
00588 void voiceinit(void)
00589 {
00590     
00591     /*setting up the SPI defaults*/
00592     TextToSpeech.lock();
00593     TextToSpeech.format(8,3);
00594     TextToSpeech.frequency(frequency);
00595     TextToSpeech.unlock();
00596     
00597     /* initialise voice */
00598     pc.printf("System Init Done!\r\n");
00599     tts_init();
00600     pc.printf("tts Init Done!\r\n");
00601     tts_setup();
00602     pc.printf("tts setup Done!\r\n");
00603     tts_msg_block_callback( msg_blk );
00604     tts_fatal_err_callback( fatal_err );
00605     tts_config( 0x10, false, TTSV_US, 0x0080 );
00606     tts_unmute();
00607     
00608 }
00609 
00610 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00611 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00612 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00613 /**************************************************************************************************
00614 * Function msg_blk( uint16_t *req, uint16_t *err )
00615 * -------------------------------------------------------------------------------------------------
00616 * Overview: receive a blocked message from  S1V30120;
00617 **************************************************************************************************/
00618 void msg_blk( uint16_t *req, uint16_t *err )
00619 {
00620     char txt[ 6 ];
00621     
00622     pc.printf( " MSG BLOCKED \r\n" );
00623     sprintf( txt, "%x\r\n", *req );
00624     pc.printf( txt );
00625     sprintf( txt, "%x\r\n", *err );
00626     pc.printf( txt );
00627 }
00628 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00629 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00630 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00631 /**************************************************************************************************
00632 * Function fatal_err( uint16_t *err )
00633 * -------------------------------------------------------------------------------------------------
00634 * Overview: error detected
00635 **************************************************************************************************/
00636 void fatal_err( uint16_t *err )
00637 {
00638     pc.printf( "Fatal Error Detected" );
00639     tts_init();
00640     tts_fatal_err_callback( fatal_err );
00641 }
00642 
00643 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00644 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00645 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00646 /**************************************************************************************************
00647 * text_to_speech_hal.c
00648 * -------------------------------------------------------------------------------------------------
00649 * Overview: Functions to control SPI interface.
00650 **************************************************************************************************/
00651 
00652 void tts_hal_cs_high()
00653 {
00654     
00655     TTS_CS = 1;
00656 }
00657 
00658 void tts_hal_cs_low()
00659 {
00660     TTS_CS = 0;
00661     
00662 }
00663 
00664 void tts_hal_mut_high()
00665 {
00666     TTS_MUTE = 1;
00667 }
00668 
00669 void tts_hal_mut_low()
00670 {
00671     TTS_MUTE = 0;
00672 }
00673 
00674 void tts_hal_reset( void )
00675 {
00676     tts_hal_cs_high();
00677     TTS_RST = 0;
00678     tts_hal_write_pad(1);
00679     wait(0.01);
00680     TTS_RST = 1;
00681     wait(POR_TIME);
00682 }
00683 
00684 bool tts_hal_msg_rdy( void )
00685 {
00686     return TTS_RDY;
00687 }
00688 
00689 void tts_hal_init()
00690 {
00691     tts_hal_reset();
00692     tts_hal_cs_high();
00693     tts_hal_mut_low();
00694 }
00695 
00696 void tts_hal_write( uint8_t *buffer,
00697                     uint16_t count, bool boot )
00698 {
00699     TextToSpeech.lock();
00700     while( count-- )
00701     {
00702         if(!boot)
00703             pc.printf("%02X\r\n", *buffer);
00704         
00705         TextToSpeech.write( *buffer++  );
00706         
00707      }   
00708     TextToSpeech.unlock();
00709 }
00710 
00711 
00712 void tts_hal_write_pad( int cnt )
00713 {
00714     TextToSpeech.lock();
00715     tts_hal_cs_low();
00716     while(cnt--)
00717     {
00718          TextToSpeech.write( PADDING_BYTE );
00719     }  
00720 
00721     tts_hal_cs_high();
00722     TextToSpeech.unlock();
00723 }
00724 
00725 void tts_hal_read( uint8_t *buffer,
00726                    uint16_t count )
00727 {
00728     TextToSpeech.lock();
00729     while(count--)
00730     {   
00731         *buffer++ = TextToSpeech.write( DUMMY_BYTE ); //read spi bus
00732       
00733        
00734         //pc.printf("buffer = %X\n\r", *buffer);
00735     }
00736     TextToSpeech.unlock();
00737 }
00738 
00739 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00740 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00741 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
00742 /**************************************************************************************************
00743 * text_to_speech.c
00744 * -------------------------------------------------------------------------------------------------
00745 * Overview: Functions to control the setup and speech controls
00746 **************************************************************************************************/
00747 
00748 static int _parse_ind( void )
00749 {
00750     uint16_t rsp_idx = tts_rsp_idx();
00751     if ( rsp_idx == ISC_MSG_BLOCKED_RESP )
00752     {
00753         uint8_t rsp_data[ 4 ] = { 0 };
00754 
00755         _req_err = 0;
00756         _err_code = 0;
00757 
00758         tts_rsp_data( rsp_data );
00759 
00760         _req_err |= rsp_data[ 0 ];
00761         _req_err |= rsp_data[ 1 ] << 8;
00762         _err_code |= rsp_data[ 2 ];
00763         _err_code |= rsp_data[ 3 ] << 8;
00764 
00765         if( _msg_block_callback != NULL )
00766             _msg_block_callback( &_req_err, &_err_code );
00767 
00768         return 1;
00769 
00770     } else if ( rsp_idx == ISC_ERROR_IND ) {
00771 
00772          uint8_t rsp_data[ 4 ] = { 0 };
00773 
00774         _req_err = 0;
00775         _err_code = 0;
00776 
00777         tts_rsp_data( rsp_data );
00778 
00779         _err_code |= rsp_data[ 0 ];
00780         _err_code |= rsp_data[ 1 ] << 8;
00781 
00782         if ( _err_code && _err_code < 0x8000 )
00783         {
00784             if( _err_callback != NULL )
00785                 _err_callback( &_err_code );
00786 
00787         } else if ( _err_code && _err_code > 0x7FFF ) {
00788 
00789             if( _fatal_err_callback != NULL )
00790                 _fatal_err_callback( &_err_code );
00791         }
00792 
00793         return 1;
00794 
00795     } else if ( rsp_idx == ISC_TTS_READY_IND ) {
00796 
00797         _tts_rdy_f = 1;
00798 
00799     } else if ( rsp_idx == ISC_SPCODEC_READY_IND ) {
00800 
00801         _spc_rdy_f = 1;
00802 
00803     } else if ( rsp_idx == ISC_TTS_FINISHED_IND ) {
00804 
00805         _tts_fin_f = 1;
00806 
00807     } else if ( rsp_idx == ISC_SPCODEC_FINISHED_IND ) {
00808 
00809         _spc_fin_f = 1;
00810     }
00811 
00812     return 0;
00813 }
00814 
00815 void tts_init()
00816 {
00817     _req_err = 0;
00818     _err_code = 0;
00819 
00820     _tts_rdy_f = true;
00821     _spc_rdy_f = true;
00822     _tts_fin_f = true;
00823     _spc_fin_f = true;
00824 
00825     _audio_conf.as = 0x00;
00826     _audio_conf.ag = 0x43;
00827     _audio_conf.amp = 0x00;
00828     _audio_conf.asr = ASR_11KHZ;
00829     _audio_conf.ar = 0x00;
00830     _audio_conf.atc = 0x00;
00831     _audio_conf.acs = 0x00;
00832     _audio_conf.dc = 0x00;
00833 
00834     _tts_conf.sr = 0x01;
00835     _tts_conf.voice = 0x00;
00836     _tts_conf.ep = 0x00;
00837     _tts_conf.lang = TTSV_US;
00838     _tts_conf.sr_wpm_lsb = 0xc8;
00839     _tts_conf.sr_wpm_msb = 0x00;
00840     _tts_conf.ds = 0x00;
00841     _tts_conf.res = 0x00;
00842 
00843     _pman_conf.am_lsb = 0x01;
00844     _pman_conf.am_msb = 0x00;
00845     _pman_conf.spi_clk = 0x01;
00846     _pman_conf.pad = PADDING_BYTE;
00847 
00848     _flush_enable = false;
00849 
00850     _msg_block_callback = NULL;
00851     _fatal_err_callback = NULL;
00852     _err_callback = NULL;
00853 
00854     tts_hw_init();
00855 }
00856 
00857 void tts_msg_block_callback( void( *msg_blk_ptr )( uint16_t *req_ptr,
00858                                                    uint16_t *err_ptr ) )
00859 {
00860     _msg_block_callback = msg_blk_ptr;
00861 }
00862 
00863 void tts_fatal_err_callback( void( *fatal_err_ptr )( uint16_t *err_ptr ) )
00864 {
00865     _fatal_err_callback = fatal_err_ptr;
00866 }
00867 
00868 void tts_err_callback( void( *error_ptr )( uint16_t *err_ptr ) )
00869 {
00870     _err_callback = error_ptr;
00871 }
00872 
00873 void tts_mute()
00874 {
00875     tts_mute_cmd( true );
00876 }
00877 
00878 void tts_unmute()
00879 {
00880     tts_mute_cmd( false );
00881 }
00882 
00883 
00884 void tts_setup()
00885 {
00886     //check HW version
00887     tts_version_boot(); 
00888     
00889     int succ = tts_image_load( (uint8_t*)TTS_INIT_DATA, sizeof( TTS_INIT_DATA ) );
00890    
00891     if ( succ != 0x0001 )
00892     {
00893             // image load failed, try turning it off and on again
00894             pc.printf("tts init data failed!\n\r");
00895             pc.printf("returned value: %X\n\r", succ);
00896             while(1);
00897     }        
00898     pc.printf("tts image load done\n\r"); 
00899     succ =  tts_image_exec();
00900     
00901     if ( succ != 0x0001 )
00902     {
00903         // image boot failed, try turning it off and on again
00904         pc.printf("tts image exec failed!\n\r");
00905         pc.printf("returned value: %X\n\r", succ);
00906         while(1);
00907     } 
00908     pc.printf("tts image exec done\n\r");
00909     
00910     tts_interface_test();
00911     pc.printf("tts interface test done\n\r");
00912     
00913     tts_power_default_config();
00914     pc.printf("tts power default done\n\r");
00915     
00916     tts_audio_default_config();
00917     pc.printf("tts audio default done\n\r");
00918     
00919     tts_volume_set( 0 );
00920     pc.printf("tts volume set done\n\r");
00921     
00922     tts_default_config();
00923     pc.printf("tts default config done\n\r");
00924 }
00925 
00926 void tts_version_boot( void )
00927 {
00928     
00929     uint8_t tmp_resp[ 16 ] = { 0 };
00930 
00931     wait( RESET_TO_BOOT_TIME );
00932    
00933     tts_parse_req( ISC_VERSION_REQ_BOOT, NULL, 0 );
00934    
00935     while( !tts_rsp_chk( ISC_VERSION_RESP_BOOT ) )
00936     {
00937         tts_get_resp();
00938     }
00939     tts_hal_write_pad( 16);
00940     tts_rsp_data( tmp_resp );
00941     pc.printf("hwver0 %X \n\r", tmp_resp[ 0 ]);
00942     pc.printf("hwver1 %X \n\r", tmp_resp[ 1 ]);
00943 }
00944 
00945 uint16_t tts_image_load(const uint8_t *image,
00946                          uint16_t count )
00947 {
00948     uint16_t tmp_resp = 0;
00949     uint16_t index = 0;
00950     uint8_t raw_resp[ 2 ] = { 0 };
00951    
00952     while ( ( count - index ) > ( BOOT_MESSAGE_MAX - 4  ) )
00953     {
00954        
00955        tts_parse_boot_img( image + index, BOOT_MESSAGE_MAX - 4  );
00956        wait(0.01);
00957        index += ( BOOT_MESSAGE_MAX - 4 );
00958     }
00959     tts_parse_boot_img( image + index, count - index );
00960     wait(0.01);           
00961     
00962     while( !tts_rsp_chk( ISC_BOOT_LOAD_RESP ) )
00963     {
00964         tts_get_resp();
00965           
00966         if( _parse_ind() )
00967             return _err_code;
00968     }
00969     tts_rsp_data( raw_resp );
00970 
00971     tmp_resp |= raw_resp[ 0 ];
00972     tmp_resp |= raw_resp[ 1 ] << 8;
00973   
00974     return tmp_resp;
00975 }
00976 
00977 uint16_t tts_image_exec()
00978 {
00979     uint16_t tmp_resp = 0;
00980     uint8_t raw_resp[ 2 ] = { 0 };
00981 
00982     tts_parse_req( ISC_BOOT_RUN_REQ, NULL, 0 );
00983      
00984     while( !tts_rsp_chk( ISC_BOOT_RUN_RESP ) )
00985     {
00986        tts_get_resp();
00987        
00988         if( _parse_ind() )
00989             return _err_code;
00990     }
00991     tts_rsp_data( raw_resp );
00992 
00993     tmp_resp |= raw_resp[ 0 ];
00994     tmp_resp |= raw_resp[ 1 ] << 8;
00995 
00996     return  tmp_resp;
00997 }
00998 
00999 uint16_t tts_interface_test()
01000 {
01001     uint16_t tmp_resp = 0;
01002     uint8_t raw_resp[ 2 ] = { 0 };
01003     
01004     wait( BOOT_TO_MAIN_MODE );
01005     
01006     tts_parse_req( ISC_TEST_REQ, test, 8 );
01007            
01008     while( !tts_rsp_chk( ISC_TEST_RESP ) )
01009     {
01010         tts_get_resp();
01011       
01012         if( _parse_ind() )
01013             return _err_code;
01014     }
01015 
01016     tts_rsp_data( raw_resp );
01017 
01018     tmp_resp |= raw_resp[ 0 ];
01019     tmp_resp |= raw_resp[ 1 ] << 8;
01020 
01021     return tmp_resp;
01022 }
01023 
01024  uint16_t tts_version_main( VER_t *buffer )
01025 {
01026     char tmp_char[ 3 ] = { 0 };
01027     uint32_t tmp_fwf = 0;
01028     uint32_t tmp_fwef = 0;
01029     uint8_t tmp_resp[ 20 ] = { 0 };
01030 
01031     tts_parse_req( ISC_VERSION_REQ_MAIN, NULL, 0 );
01032 
01033     while( !tts_rsp_chk( ISC_VERSION_RESP_MAIN ) )
01034     {
01035         tts_get_resp();
01036 
01037         if( _parse_ind() )
01038             return _err_code;
01039     }
01040 
01041     tts_rsp_data( tmp_resp );
01042     sprintf(tmp_char, "%c", tmp_resp[ 0 ]);
01043     strcpy( buffer->hwver, tmp_char );
01044     strcat( buffer->hwver, "." );
01045     sprintf(tmp_char, "%c", tmp_resp[ 1 ]);
01046     strcat( buffer->hwver, tmp_char );
01047     sprintf(tmp_char, "%c", tmp_resp[ 2 ]);
01048     strcpy( buffer->fwver, tmp_char );
01049     strcat( buffer->fwver, "." );
01050     sprintf(tmp_char, "%c", tmp_resp[ 3 ]);
01051     strcat( buffer->fwver, tmp_char );
01052     strcat( buffer->fwver, "." );
01053     sprintf(tmp_char, "%c", tmp_resp[ 12 ]);
01054     strcat( buffer->fwver, tmp_char );
01055 
01056     tmp_fwf |= tmp_resp[ 4 ];
01057     tmp_fwf |= tmp_resp[ 5 ] << 8;
01058     tmp_fwf |= tmp_resp[ 6 ] << 16;
01059     tmp_fwf |= tmp_resp[ 7 ] << 24;
01060     buffer->fwf = (FF_t)tmp_fwf;
01061     tmp_fwef |= tmp_resp[ 8 ];
01062     tmp_fwef |= tmp_resp[ 9 ] << 8;
01063     tmp_fwef |= tmp_resp[ 10 ] << 16;
01064     tmp_fwef |= tmp_resp[ 11 ] << 24;
01065     buffer->fwef = (EFF_t)tmp_fwef;
01066 
01067     return 0x0000;
01068 }
01069 
01070 uint16_t tts_power_default_config()
01071 {
01072     uint16_t tmp_resp = 0;
01073     uint8_t raw_resp[ 2 ] = { 0 };
01074 
01075     tts_parse_req( ISC_PMAN_CONFIG_REQ, ( uint8_t* )&_pman_conf, 4 );
01076 
01077     while( !tts_rsp_chk( ISC_PMAN_CONFIG_RESP ) )
01078     {
01079         tts_get_resp();
01080 
01081         if( _parse_ind() )
01082             return _err_code;
01083     }
01084 
01085     tts_rsp_data( raw_resp );
01086 
01087     tmp_resp |= raw_resp[ 0 ];
01088     tmp_resp |= raw_resp[ 1 ] << 8;
01089 
01090     return tmp_resp;
01091 }
01092 
01093 uint16_t tts_standby_enter()
01094 {
01095     uint16_t tmp_resp = 0;
01096     uint8_t raw_resp[ 2 ] = { 0 };
01097 
01098     tts_parse_req( ISC_PMAN_STANDBY_ENTRY_REQ, NULL, 0 );
01099 
01100     while( !tts_rsp_chk( ISC_PMAN_STANDBY_ENTRY_RESP ) )
01101     {
01102         tts_get_resp();
01103 
01104         if( _parse_ind() )
01105             return _err_code;
01106     }
01107 
01108     tts_rsp_data( raw_resp );
01109 
01110     tmp_resp |= raw_resp[ 0 ];
01111     tmp_resp |= raw_resp[ 1 ] << 8;
01112 
01113     return tmp_resp;
01114 }
01115 
01116 uint16_t tts_standby_exit()
01117 {
01118     wait( STBY_MODE_ENTERY );
01119     tts_parse_req( ISC_PMAN_STANDBY_EXIT_IND, NULL, 0 );
01120 
01121     while( !tts_rsp_chk( ISC_PMAN_STANDBY_EXIT_IND ) )
01122     {
01123         tts_get_resp();
01124 
01125         if( _parse_ind() )
01126             return _err_code;
01127     }
01128 
01129     return 0x0000;
01130 }
01131 
01132 uint16_t tts_audio_default_config()
01133 {
01134     uint16_t tmp_resp = 0;
01135     uint8_t raw_resp[ 2 ] = { 0 };
01136 
01137     tts_parse_req( ISC_AUDIO_CONFIG_REQ, ( uint8_t* )&_audio_conf, 8 );
01138 
01139     while( !tts_rsp_chk( ISC_AUDIO_CONFIG_RESP ) )
01140     {
01141         tts_get_resp();
01142 
01143         if( _parse_ind() )
01144             return _err_code;
01145     }
01146 
01147     tts_rsp_data( raw_resp );
01148 
01149     tmp_resp |= raw_resp[ 0 ];
01150     tmp_resp |= raw_resp[ 1 ] << 8;
01151 
01152     return tmp_resp;
01153 }
01154 
01155 uint16_t tts_audio_config( int8_t audio_gain,
01156                            ASR_t sample_rate,
01157                            bool dac_control )
01158 {
01159     ACONF_t audio_conf;
01160     uint16_t tmp_resp = 0;
01161     uint8_t raw_resp[ 2 ] = { 0 };
01162 
01163     if ( audio_gain < -48 || audio_gain > 18 )
01164         return 0xFFFF;
01165 
01166     if ( sample_rate != 0 || sample_rate != 1 || sample_rate != 3 )
01167         return 0xFFFF;
01168 
01169     audio_conf.ag = ( uint8_t )audio_gain;
01170     audio_conf.asr = sample_rate;
01171     audio_conf.dc = dac_control;
01172 
01173     tts_parse_req( ISC_AUDIO_CONFIG_REQ, ( uint8_t* )&audio_conf, 8 );
01174 
01175     while( !tts_rsp_chk( ISC_AUDIO_CONFIG_RESP ) )
01176     {
01177         tts_get_resp();
01178 
01179         if( _parse_ind() )
01180             return _err_code;
01181     }
01182 
01183     tts_rsp_data( raw_resp );
01184 
01185     tmp_resp |= raw_resp[ 0 ];
01186     tmp_resp |= raw_resp[ 1 ] << 8;
01187 
01188     return tmp_resp;
01189 }
01190 
01191 uint16_t tts_volume_set( int16_t gain )
01192 {
01193     uint16_t tmp_resp = 0;
01194     uint8_t raw_resp[ 2 ] = { 0 };
01195     uint8_t tmp_gain[ 2 ] = { 0 };
01196 
01197     tmp_gain[ 0 ] = gain & 0x00FF;
01198     tmp_gain[ 1 ] = ( gain & 0xFF00 ) >> 8;
01199 
01200     tts_parse_req( ISC_AUDIO_VOULME_REQ, tmp_gain, 2 );
01201 
01202     while( !tts_rsp_chk( ISC_AUDIO_VOLUME_RESP ) )
01203     {
01204         tts_get_resp();
01205 
01206         if( _parse_ind() )
01207             return _err_code;
01208     }
01209 
01210     tts_rsp_data( raw_resp );
01211 
01212     tmp_resp |= raw_resp[ 0 ];
01213     tmp_resp |= raw_resp[ 1 ] << 8;
01214 
01215     return tmp_resp;
01216 }
01217 
01218 uint16_t tts_audio_mute()
01219 {
01220     uint16_t tmp_resp = 0;
01221     uint8_t raw_resp[ 2 ] = { 0 };
01222     uint8_t tmp_mute[ 2 ] = { 1, 0 };
01223 
01224     tts_parse_req( ISC_AUDIO_MUTE_REQ, tmp_mute, 2 );
01225 
01226     while( !tts_rsp_chk( ISC_AUDIO_MUTE_RESP ) )
01227     {
01228         tts_get_resp();
01229 
01230         if( _parse_ind() )
01231             return _err_code;
01232     }
01233 
01234     tts_rsp_data( raw_resp );
01235 
01236     tmp_resp |= raw_resp[ 0 ];
01237     tmp_resp |= raw_resp[ 1 ] << 8;
01238 
01239     return tmp_resp;
01240 }
01241 
01242 uint16_t tts_audio_unmute()
01243 {
01244     uint16_t tmp_resp = 0;
01245     uint8_t raw_resp[ 2 ] = { 0 };
01246     uint8_t tmp_mute[ 2 ] = { 0, 0 };
01247 
01248     tts_parse_req( ISC_AUDIO_MUTE_REQ, tmp_mute, 2 );
01249 
01250     while( !tts_rsp_chk( ISC_AUDIO_MUTE_RESP ) )
01251     {
01252         tts_get_resp();
01253 
01254         if( _parse_ind() )
01255             return _err_code;
01256     }
01257 
01258     tts_rsp_data( raw_resp );
01259 
01260     tmp_resp |= raw_resp[ 0 ];
01261     tmp_resp |= raw_resp[ 1 ] << 8;
01262 
01263     return tmp_resp;
01264 }
01265 
01266 uint16_t tts_default_config()
01267 {
01268     uint16_t tmp_resp = 0;
01269     uint8_t raw_resp[ 2 ] = { 0 };
01270 
01271     tts_parse_req( ISC_TTS_CONFIG_REQ, ( uint8_t* )&_tts_conf, 8 );
01272 
01273     while( !tts_rsp_chk( ISC_TTS_CONFIG_RESP ) )
01274     {
01275         tts_get_resp();
01276 
01277         if( _parse_ind() )
01278             return _err_code;
01279     }
01280 
01281     tts_rsp_data( raw_resp );
01282 
01283     tmp_resp |= raw_resp[ 0 ];
01284     tmp_resp |= raw_resp[ 1 ] << 8;
01285 
01286     return tmp_resp;
01287 }
01288 
01289 uint16_t tts_config( uint8_t voice_type,
01290                      bool epson_parse,
01291                      TTSV_t language,
01292                      uint16_t speaking_rate )
01293 {
01294     TTSCONF_t tts_conf;
01295     uint16_t tmp_resp = 0;
01296     uint8_t raw_resp[ 2 ] = { 0 };
01297 
01298     if ( voice_type > 8 )
01299         return 0xFFFF;
01300 
01301     if ( language > 4 )
01302         return 0xFFFF;
01303 
01304     if ( speaking_rate < 0x004B || speaking_rate > 0x0258 )
01305         return 0xFFFF;
01306 
01307     tts_conf.voice = voice_type;
01308     tts_conf.ep = epson_parse;
01309     tts_conf.lang = language;
01310     tts_conf.sr_wpm_lsb = ( speaking_rate & 0x00FF );
01311     tts_conf.sr_wpm_msb = ( speaking_rate & 0xFF00 ) >> 8;
01312 
01313     tts_parse_req( ISC_TTS_CONFIG_REQ, ( uint8_t* )&tts_conf, 8 );
01314 
01315     while( !tts_rsp_chk( ISC_TTS_CONFIG_RESP ) )
01316     {
01317         tts_get_resp();
01318 
01319         if( _parse_ind() )
01320             return _err_code;
01321     }
01322 
01323     tts_rsp_data( raw_resp );
01324 
01325     tmp_resp |= raw_resp[ 0 ];
01326     tmp_resp |= raw_resp[ 1 ] << 8;
01327 
01328     return tmp_resp;
01329 }
01330 
01331 uint16_t tts_speak( char *word )
01332 {
01333     bool tmp_f              = false;
01334     char *wptr              = word;
01335     uint8_t raw_resp[ 2 ]   = { 0 };
01336     uint16_t tmp_resp       = 0;
01337     uint32_t wlen           = strlen( wptr );
01338 
01339     tts_parse_speak_req( ISC_TTS_SPEAK_REQ, _flush_enable, wptr, wlen );
01340 
01341     _tts_rdy_f = 0;
01342     _tts_fin_f = 0;
01343 
01344     while( !( tmp_f && _tts_rdy_f ) )
01345     {
01346         tts_get_resp();
01347 
01348         if( _parse_ind() )
01349             return _err_code;
01350 
01351         if( tts_rsp_chk( ISC_TTS_SPEAK_RESP ) )
01352         {
01353             tts_rsp_data( raw_resp );
01354 
01355             tmp_resp |= raw_resp[ 0 ];
01356             tmp_resp |= raw_resp[ 1 ] << 8;
01357             tmp_f = true;
01358         }
01359     }
01360 
01361     return tmp_resp;
01362 }
01363 
01364 uint16_t tts_pause( void )
01365 {
01366     uint16_t tmp_resp = 0;
01367     uint8_t raw_resp[ 2 ] = { 0 };
01368     uint8_t tmp_pause[ 2 ] = { 1, 0 };
01369 
01370     tts_parse_req( ISC_TTS_PAUSE_REQ, tmp_pause, 2 );
01371 
01372     while( !tts_rsp_chk( ISC_TTS_PAUSE_RESP ) )
01373     {
01374         tts_get_resp();
01375 
01376         if( _parse_ind() )
01377             return _err_code;
01378     }
01379 
01380     tts_rsp_data( raw_resp );
01381 
01382     tmp_resp |= raw_resp[ 0 ];
01383     tmp_resp |= raw_resp[ 1 ] << 8;
01384 
01385     return tmp_resp;
01386 }
01387 
01388 uint16_t tts_unpause( void )
01389 {
01390     uint16_t tmp_resp = 0;
01391     uint8_t raw_resp[ 2 ] = { 0 };
01392     uint8_t tmp_pause[ 2 ] = { 0 };
01393 
01394     tts_parse_req( ISC_TTS_PAUSE_REQ, tmp_pause, 2 );
01395 
01396     while( !tts_rsp_chk( ISC_TTS_PAUSE_RESP ) )
01397     {
01398         tts_get_resp();
01399 
01400         if( _parse_ind() )
01401             return _err_code;
01402     }
01403 
01404     tts_rsp_data( raw_resp );
01405 
01406     tmp_resp |= raw_resp[ 0 ];
01407     tmp_resp |= raw_resp[ 1 ] << 8;
01408 
01409     return tmp_resp;
01410 }
01411 
01412 uint16_t tts_stop( bool reset )
01413 {
01414     uint16_t tmp_resp = 0;
01415     uint8_t raw_resp[ 2 ] = { 0 };
01416     uint8_t tmp_reset[ 2 ] = { 0 };
01417 
01418     if( reset )
01419         tmp_reset[ 0 ] = 0x01;
01420 
01421     tts_parse_req( ISC_TTS_STOP_REQ, tmp_reset, 2 );
01422 
01423     while( !tts_rsp_chk( ISC_TTS_STOP_RESP ) )
01424     {
01425         tts_get_resp();
01426 
01427         if( _parse_ind() )
01428             return _err_code;
01429     }
01430 
01431     tts_rsp_data( raw_resp );
01432 
01433     tmp_resp |= raw_resp[ 0 ];
01434     tmp_resp |= raw_resp[ 1 ] << 8;
01435 
01436     return tmp_resp;
01437 }
01438 
01439 uint16_t tts_user_dict( bool erase,
01440                         uint8_t *udict_data,
01441                         uint16_t count )
01442 {
01443     uint16_t cnt = 2;
01444     uint16_t tmp_rsp = 0;
01445     uint8_t rsp_data[ 2 ] = { 0 };
01446     uint8_t tmp_data[ BOOT_MESSAGE_MAX ] = { 0 };
01447 
01448     if ( erase )
01449         tmp_data[ 0 ] = 1;
01450 
01451     while ( count-- )
01452         tmp_data[ cnt ++ ] = *( udict_data++ );
01453 
01454     tts_parse_req( ISC_TTS_UDICT_DATA_REQ, tmp_data, count + 2 );
01455 
01456     while( !tts_rsp_chk( ISC_TTS_UDICT_DATA_RESP ) )
01457     {
01458         tts_get_resp();
01459 
01460         if( _parse_ind() )
01461             return _err_code;
01462     }
01463 
01464     tts_rsp_data( rsp_data );
01465 
01466     tmp_rsp |= rsp_data[ 0 ];
01467     tmp_rsp |= rsp_data[ 1 ] << 8;
01468 
01469     return tmp_rsp;
01470 }
01471 
01472 uint16_t tts_codec_configure()
01473 {
01474     uint16_t tmp_resp = 0;
01475     uint8_t raw_resp[ 2 ] = { 0 };
01476     uint8_t tmp_codec[ 32 ] = { 0 };
01477 
01478     tmp_codec[ 0 ] = 0x01;
01479     tmp_codec[ 1 ] = 0x01;
01480     tmp_codec[ 24 ] = 0x02;
01481 
01482     tts_parse_req( ISC_SPCODEC_CONFIG_REQ , tmp_codec, 32 );
01483 
01484     while( !tts_rsp_chk( ISC_SPCODEC_CONFIG_RESP ) )
01485     {
01486         tts_get_resp();
01487 
01488         if( _parse_ind() )
01489             return _err_code;
01490     }
01491 
01492     tts_rsp_data( raw_resp );
01493 
01494     tmp_resp |= raw_resp[ 0 ];
01495     tmp_resp |= raw_resp[ 1 ] << 8;
01496 
01497     return tmp_resp;
01498 }
01499 
01500 uint16_t tts_codec_start( uint8_t *codec_data,
01501                           uint16_t count )
01502 {
01503     bool tmp_f = false;
01504     uint16_t tmp_resp = 0;
01505     uint8_t raw_resp[ 2 ] = { 0 };
01506 
01507     if ( count != 512 || count != 1024 || count != 2048 )
01508         return 0xFFFF;
01509 
01510     while( !_spc_fin_f )
01511     {
01512         tts_get_resp();
01513 
01514         if( _parse_ind() )
01515             return _err_code;
01516     }
01517 
01518     tts_parse_req( ISC_SPCODEC_START_REQ , codec_data, count );
01519 
01520     _spc_rdy_f = 0;
01521     _spc_fin_f = 0;
01522 
01523     while( !( tmp_f && _spc_rdy_f ) )
01524     {
01525         tts_get_resp();
01526 
01527         if( _parse_ind() )
01528             return _err_code;
01529 
01530         if( tts_rsp_chk( ISC_TTS_SPEAK_RESP ) )
01531         {
01532             tts_rsp_data( raw_resp );
01533 
01534             tmp_resp |= raw_resp[ 0 ];
01535             tmp_resp |= raw_resp[ 1 ] << 8;
01536             tmp_f = true;
01537         }
01538     }
01539 
01540     return tmp_resp;
01541 }
01542 
01543 uint16_t tts_codec_pause()
01544 {
01545     uint16_t tmp_resp = 0;
01546     uint8_t raw_resp[ 2 ] = { 0 };
01547     uint8_t tmp_data[ 2 ] = { 1, 0 };
01548 
01549     tts_parse_req( ISC_SPCODEC_PAUSE_REQ , tmp_data, 2 );
01550 
01551     while( !tts_rsp_chk( ISC_SPCODEC_PAUSE_RESP ) )
01552     {
01553         tts_get_resp();
01554 
01555         if( _parse_ind() )
01556             return _err_code;
01557     }
01558 
01559     tts_rsp_data( raw_resp );
01560 
01561     tmp_resp |= raw_resp[ 0 ];
01562     tmp_resp |= raw_resp[ 1 ] << 8;
01563 
01564     return tmp_resp;
01565 }
01566 
01567 uint16_t tts_codec_unpause()
01568 {
01569     uint16_t tmp_resp = 0;
01570     uint8_t raw_resp[ 2 ] = { 0 };
01571     uint8_t tmp_data[ 2 ] = { 0 };
01572 
01573     tts_parse_req( ISC_SPCODEC_PAUSE_REQ , tmp_data, 2 );
01574 
01575     while( !tts_rsp_chk( ISC_SPCODEC_PAUSE_RESP ) )
01576     {
01577         tts_get_resp();
01578 
01579         if( _parse_ind() )
01580             return _err_code;
01581     }
01582 
01583     tts_rsp_data( raw_resp );
01584 
01585     tmp_resp |= raw_resp[ 0 ];
01586     tmp_resp |= raw_resp[ 1 ] << 8;
01587 
01588     return tmp_resp;
01589 }
01590 
01591 uint16_t tts_codec_stop( bool reset )
01592 {
01593     uint16_t tmp_resp = 0;
01594     uint8_t raw_resp[ 2 ] = { 0 };
01595     uint8_t tmp_data[ 2 ] = { 0 };
01596 
01597     if( reset )
01598         tmp_data[ 0 ] = 1;
01599 
01600     tts_parse_req( ISC_SPCODEC_STOP_REQ, tmp_data, 2 );
01601 
01602     while( !tts_rsp_chk( ISC_SPCODEC_PAUSE_RESP ) )
01603     {
01604         tts_get_resp();
01605 
01606         if( _parse_ind() )
01607             return _err_code;
01608     }
01609 
01610     tts_rsp_data( raw_resp );
01611 
01612     tmp_resp |= raw_resp[ 0 ];
01613     tmp_resp |= raw_resp[ 1 ] << 8;
01614 
01615     return tmp_resp;
01616 }
01617 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
01618 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
01619 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
01620 /**************************************************************************************************
01621 * text_to_speech_hw.c
01622 * -------------------------------------------------------------------------------------------------
01623 * Overview: Mainly read and write functions with parsing
01624 **************************************************************************************************/
01625 
01626 void _read_rsp()
01627 {
01628     uint8_t tmp_byte = 0;
01629     uint16_t tmp_len = 0;
01630 
01631     tts_hal_cs_low();
01632     
01633     tts_hal_read( &tmp_byte, 1 );
01634 
01635     if( tmp_byte == START_MESSAGE )
01636     {
01637         tts_hal_read( ( uint8_t* )&_last_rsp, 2 );
01638         tmp_len |= _last_rsp.len[ 0 ];
01639         tmp_len |= _last_rsp.len[ 1 ] << 8;
01640         tts_hal_read( ( uint8_t* )&_last_rsp + 2, tmp_len );
01641         
01642     } else {
01643 
01644         wait( 0.005 );
01645     }
01646    
01647     tts_hal_cs_high();
01648 }
01649 
01650 void _write_req(bool boot)
01651 {
01652     uint16_t cnt = 0;
01653     uint8_t start = START_MESSAGE;
01654 
01655     cnt |= _last_req.len[ 0 ];
01656     cnt |= _last_req.len[ 1 ] << 8;
01657     
01658     tts_hal_cs_low();
01659     
01660     
01661     if(boot) // use for debug - displays the current buffer on serial
01662     {
01663         tts_hal_write( &start, 1, true );
01664         tts_hal_write( ( uint8_t* )&_last_req, cnt, true);
01665     }
01666     else
01667     {
01668         tts_hal_write( &start, 1, false );
01669         tts_hal_write( ( uint8_t* ) &_last_req, cnt, false );
01670     }    
01671    
01672     tts_hal_cs_high();
01673     
01674 }
01675 
01676 /******************************************************************************
01677 * Public Function Definitions
01678 *******************************************************************************/
01679 void tts_hw_init( void )
01680 {
01681     tts_hal_init();
01682 
01683     _ticker_f = false;
01684     _ticker = 0;
01685 
01686     _last_req.idx[ 0 ] = 0;
01687     _last_req.idx[ 1 ] = 0;
01688     _last_req.len[ 0 ] = 0;
01689     _last_req.len[ 1 ] = 0;
01690     memset( _last_req.payload, 0, MAIN_MESSAGE_MAX );
01691 
01692     _last_rsp.idx[ 0 ] = 255;
01693     _last_rsp.idx[ 1 ] = 255;
01694     _last_rsp.len[ 0 ] = 0;
01695     _last_rsp.len[ 1 ] = 0;
01696     memset( _last_rsp.payload, 0, RESP_MESSAGE_MAX );
01697 }
01698 
01699 void tts_tick_isr()
01700 {
01701     _ticker++;
01702 
01703     if( _ticker > 500 )
01704         _ticker_f == true;
01705 }
01706 
01707 void tts_mute_cmd( bool cmd )
01708 {
01709     if( cmd )
01710         tts_hal_mut_high();
01711     else
01712         tts_hal_mut_low();
01713 }
01714 
01715 void tts_parse_req( uint16_t req,
01716                     uint8_t *payload,
01717                     uint16_t pl_len )
01718 {
01719     uint8_t *pl = payload;
01720     uint16_t i = 0;
01721     uint16_t tmp = pl_len + 4;
01722      
01723     _last_req.len[ 0 ] = tmp & 0x00FF;
01724     _last_req.len[ 1 ] = ( tmp & 0xFF00 ) >> 8;
01725     _last_req.idx[ 0 ] = req & 0x00FF;
01726     _last_req.idx[ 1 ] = ( req & 0xFF00 ) >> 8;
01727     _last_rsp.idx[ 0 ] = 0xFF;
01728     _last_rsp.idx[ 1 ] = 0xFF;
01729     
01730     if ( payload != NULL )
01731     {
01732         while ( pl_len-- )
01733             _last_req.payload[ i++ ] = *( pl++ );
01734            
01735     }
01736     
01737     _write_req(true);
01738 }
01739 
01740 void tts_parse_boot_img( const uint8_t *payload,
01741                          uint16_t pl_len )
01742 {
01743     uint16_t i = 0;
01744     uint16_t tmp = pl_len + 0x04;
01745     
01746     _last_req.len[ 0 ] = tmp & 0x00FF;
01747     _last_req.len[ 1 ] = ( tmp & 0xFF00 ) >> 8;
01748     _last_req.idx[ 0 ] = 0x00;
01749     _last_req.idx[ 1 ] = 0x10;
01750     _last_rsp.idx[ 0 ] = 0xFF;
01751     _last_rsp.idx[ 1 ] = 0xFF;
01752 
01753     if ( payload != NULL )
01754     {
01755         while ( pl_len-- )
01756             _last_req.payload[ i++ ] = payload[ i ];  
01757     }
01758 
01759     _write_req(true);
01760 }
01761 
01762 void tts_parse_speak_req( uint16_t req,
01763                           uint8_t flush_en,
01764                           char *word,
01765                           uint16_t word_len )
01766 {
01767     char *ptr = word;
01768     uint16_t i = 1;
01769     uint16_t tmp = word_len;
01770 
01771     word_len += 7;
01772 
01773     _last_req.len[ 0 ] = word_len & 0x00FF;
01774     _last_req.len[ 1 ] = ( word_len & 0xFF00 ) >> 8;
01775     _last_req.idx[ 0 ] = req & 0x00FF;
01776     _last_req.idx[ 1 ] = ( req & 0xFF00 ) >> 8;
01777     _last_rsp.idx[ 0 ] = 0xFF;
01778     _last_rsp.idx[ 1 ] = 0xFF;
01779 
01780     if( flush_en )
01781     {
01782         _last_req.payload[ 0 ] = 1;
01783 
01784     } else {
01785 
01786         _last_req.payload[ 0 ] = 0;
01787     }
01788 
01789     while( tmp-- )
01790         _last_req.payload[ i++ ] = *( ptr++ );
01791 
01792     _last_req.payload[ i++ ] = 0x20;
01793     _last_req.payload[ i ] =   0x00;
01794 
01795     _write_req(true);
01796 }
01797 
01798 void tts_get_resp()
01799 {
01800     // only read if ready
01801     if( tts_hal_msg_rdy() )
01802     {
01803         _read_rsp();
01804     }
01805 }
01806 
01807 bool tts_rsp_chk( uint16_t idx )
01808 {
01809     uint16_t tmp = 0;
01810 
01811     tmp |= _last_rsp.idx[ 0 ];
01812     tmp |= _last_rsp.idx[ 1 ] << 8;
01813  
01814    return ( idx == tmp ) ? true : false;
01815 }
01816 
01817 uint16_t tts_rsp_idx()
01818 {
01819     uint16_t tmp = 0;
01820 
01821     tmp |= _last_rsp.idx[ 0 ];
01822     tmp |= _last_rsp.idx[ 1 ] << 8;
01823 
01824     return tmp;
01825 }
01826 
01827 void tts_rsp_data( uint8_t *buffer )
01828 {
01829     uint8_t *bfr = buffer;
01830     uint16_t cnt = 0;
01831     uint8_t *ptr = _last_rsp.payload;
01832 
01833     cnt |= _last_rsp.len[ 0 ];
01834     cnt |= _last_rsp.len[ 1 ] << 8;
01835     cnt -= 4;
01836 
01837     while( cnt-- )
01838         *( bfr++ ) = *( ptr++ );
01839 }
01840 
01841 /*************** END OF FUNCTIONS *********************************************/