Stand Alone mBed OS Text To Speech Click Board Example
Fork of Hexi_Click_Relay-v3_Example by
main.cpp
- Committer:
- daveyclk
- Date:
- 2016-10-26
- Revision:
- 2:84ca2f63ecdf
- Parent:
- 1:070fc531e5cb
File content as of revision 2:84ca2f63ecdf:
/****************************************************************************
* Title : Hexiware Text To Speech Click
* Filename : Hexi_talking_one_main
* Author : Dave Clarke
* Origin Date : 26/10/2016
* Notes : mBed OS Text to Speech Click Interface (rough)
*****************************************************************************/
/**************************CHANGE LIST **************************************
*
* Date Software Version Initials Description
* 26/10/16 1.0.0 DC Interface Created.
*
*****************************************************************************/
/**
* @page TEST_CFG Test Configurations
* <h3> Test configuration : </h3>
* @par
* <ul>
* <li><b> MCU </b> : MK64FN1M0XXX12 </li>
* <li><b> Dev. Board </b> : HEXIWEAR </li>
* <li><b> Oscillator </b> : 12 MHz external </li>
* <li><b> Ext. Modules </b> : none </li>
* <li><b> Ext. Modules </b> : TTS Click on mikroBUS 2 </li>
* <li><b> SW </b> : mBed OS5 </li>
* </ul>
*/
/**
* @mainpage
* <h3> Text To Speech with HEXIWEAR and mBed OS 5 </h3>
* @par Using mBed)S and a Hexiware you can now use the Text To Speech Click Board
*
*
*
* <h3> Speech Features </h3>
* @par Text to Speech Click, Hexiwear docking station, Hexiware
*/
/******************************************************************************
* Includes
*******************************************************************************/
#include "mbed.h"
#include "text_to_speech.h"
#include "text_to_speech_hal.h"
#include "text_to_speech_hw.h"
#include "text_to_speech_img.h"
#include "string.h"
#include <stdbool.h>
#include <stdlib.h>
/******************************************************************************
* Module Variable Definitions
*******************************************************************************/
/* Indication Flags */
static volatile bool _tts_rdy_f;
static volatile bool _spc_rdy_f;
static volatile bool _tts_fin_f;
static volatile bool _spc_fin_f;
/* Error Buffers */
static uint16_t _req_err;
static uint16_t _err_code;
/* Default Configuration */
static ACONF_t _audio_conf;
static TTSCONF_t _tts_conf;
static PMANCONF_t _pman_conf;
static bool _flush_enable;
/* Timer flag and counter */
static volatile bool _ticker_f;
static volatile uint16_t _ticker;
/* Input and output buffers */
static ISC_REQ_t _last_req;
static ISC_RESP_t _last_rsp;
/* Text Buffer */
char text[20];
static uint8_t test[ 8 ] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
int frequency = 750000;
VER_t *version;
/******************************************************************************
* Function Prototypes
*******************************************************************************/
/* Checks for indications */
static int _parse_ind( void );
/* Message block and error callback function pointers */
static void ( *_fatal_err_callback )( uint16_t *err_code );
static void ( *_err_callback )( uint16_t *err_code );
static void ( *_msg_block_callback )( uint16_t *msg_code,
uint16_t *err_code );
/* Instantiate the Click Text to Speech pinout */
DigitalOut TTS_RST(PTB19);
DigitalOut TTS_CS(PTC3);
DigitalOut TTS_MUTE(PTB3);
DigitalIn TTS_RDY(PTB8);
//Instantiate SPI for comms with Speak module
SPI TextToSpeech(PTC6, PTC7, PTC5); // MOSI, MISO, SCK
// Debug Serial
Serial pc(USBTX, USBRX);
void SysInit(void)
{
tts_hal_cs_high();
TextToSpeech.format(8,3);
TextToSpeech.frequency(frequency);
}
void fatal_err( uint16_t *err );
void msg_blk( uint16_t *req, uint16_t *err );
int main()
{
SysInit();
pc.printf("System Init Done!\r\n");
tts_init();
pc.printf("tts Init Done!\r\n");
tts_setup();
pc.printf("tts setup Done!\r\n");
tts_msg_block_callback( msg_blk );
tts_fatal_err_callback( fatal_err );
tts_config( 0x01, false, TTSV_US, 0x0090 );
//tts_mute();
//tts_speak( "[:nw][:dv ap 195 pr 80]" );
//tts_speak( "[:np][:dv ap 100 pr 50]" );
//tts_speak( "[:nw]" );
//wait( 2 );
//tts_unmute();
while(1)
{
/* frozen
verse one
tts_speak( "The snow glows white on the mountain tonight, Not a footprint to be seen. " );
wait(0.1);
tts_speak( "A kingdom of isolation, and it looks like I'm the Queen. " );
wait(0.1);
tts_speak( "The wind is howling like this swirling storm inside. " );
wait(0.1);
tts_speak( "Couldn't keep it in. " );
wait(0.1);
tts_speak( "Heaven knows I've tried. " );
wait(0.1);
tts_speak( "Don't let them in, don't let them see. " );
wait(0.1);
tts_speak( "Be the good girl you always have to be. " );
wait(0.1);
tts_speak( "Conceal, don't feel, don't let them know. " );
wait(0.1);
tts_speak( "Well now they know. " );
wait(0.1);
chorus one
tts_speak( "Let it go, let it go. " );
wait(0.1);
tts_speak( "Can't hold it back anymore. " );
wait(0.1);
tts_speak( "I don't care " );
wait(0.1);
tts_speak( "what they're going to say" );
wait(0.1);
tts_speak( "Let the storm rage on." );
wait(0.1);
tts_speak( "The cold never bothered me anyway" );
wait(0.1);
verse two
tts_speak( "It's funny how some distance " );
wait(0.1);
tts_speak( "Makes everything seem small " );
wait(0.1);
tts_speak( "And the fears that once controlled me " );
wait(0.1);
tts_speak( "Can't get to me at all " );
wait(0.1);
tts_speak( "It's time to see what I can do " );
wait(0.1);
tts_speak( "To test the limits and break through" );
wait(0.1);
tts_speak( "No right, no wrong, no rules for me, " );
wait(0.1);
tts_speak( "I'm free! " );
wait(0.1);
chorus two
tts_speak( "Let it go, let it go. " );
wait(0.1);
tts_speak( "I am one with the wind and sky " );
wait(0.1);
tts_speak( "Let it go, let it go " );
wait(0.1);
tts_speak( "You'll never see me cry" );
wait(0.1);
tts_speak( "Here I stand" );
wait(0.1);
tts_speak( "And here I'll stay" );
wait(0.1);
tts_speak( "Let the storm rage on" );
wait(0.1);
middle eight
tts_speak( "My power flurries through the air into the ground " );
wait(0.1);
tts_speak( "My soul is spiraling in frozen fractals all around " );
wait(0.1);
tts_speak( "And one thought crystallizes like an icy blast " );
wait(0.1);
tts_speak( "I'm never going back, the past is in the past" );
wait(0.1);
last chorus
tts_speak( "Let it go, let it go" );
wait(0.1);
tts_speak( "And I'll rise like the break of dawn" );
wait(0.1);
tts_speak( "Let it go, let it go" );
wait(0.1);
tts_speak( "That perfect girl is gone" );
wait(0.1);
tts_speak( "Here I stand" );
wait(0.1);
tts_speak( "In the light of day" );
wait(0.1);
tts_speak( "Let the storm rage on" );
wait(0.5);
tts_speak( "The cold never bothered me anyway" );
wait(1);
*/
// keep talking
tts_speak( "For millions of years mankind lived just like the animals." );
wait(0.5);
tts_speak( "Then something happenend which unleashed the power of our imagination" );
wait(0.5);
tts_speak( "We learned to talk" );
wait(10);
}
}
void msg_blk( uint16_t *req, uint16_t *err )
{
char txt[ 6 ];
pc.printf( " MSG BLOCKED \r\n" );
sprintf( txt, "%x\r\n", *req );
pc.printf( txt );
sprintf( txt, "%x\r\n", *err );
pc.printf( txt );
}
void fatal_err( uint16_t *err )
{
pc.printf( "Fatal Error Detected" );
tts_init();
tts_fatal_err_callback( fatal_err );
}
///////////////////text_to_speech_hal.c///////////////
void tts_hal_cs_high()
{
TTS_CS = 1;
}
void tts_hal_cs_low()
{
TTS_CS = 0;
}
void tts_hal_mut_high()
{
TTS_MUTE = 1;
}
void tts_hal_mut_low()
{
TTS_MUTE = 0;
}
/*
void tts_hal_reset( void )
{
TTS_RST = 0;
wait(0.01);
TTS_RST = 1;
//wait(1);
wait(POR_TIME / 1000);
}
*/
void tts_hal_reset( void )
{
tts_hal_cs_high();
TTS_RST = 0;
tts_hal_write_pad(1);
wait(0.01);
TTS_RST = 1;
wait(POR_TIME);
}
bool tts_hal_msg_rdy( void )
{
return TTS_RDY;
}
void tts_hal_init()
{
tts_hal_reset();
tts_hal_cs_high();
tts_hal_mut_low();
}
void tts_hal_write( uint8_t *buffer,
uint16_t count, bool boot )
{
while( count-- )
{
if(!boot)
pc.printf("%02X\r\n", *buffer);
TextToSpeech.write( *buffer++ );
}
}
void tts_hal_write_pad( int cnt )
{
tts_hal_cs_low();
while(cnt--)
{
TextToSpeech.write( PADDING_BYTE );
}
tts_hal_cs_high();
}
void tts_hal_read( uint8_t *buffer,
uint16_t count )
{
while(count--)
{
*buffer++ = TextToSpeech.write( DUMMY_BYTE ); //read spi bus
//pc.printf("buffer = %X\n\r", *buffer);
}
}
////////////////text_to_speech.c///////////////////////////////
static int _parse_ind( void )
{
uint16_t rsp_idx = tts_rsp_idx();
if ( rsp_idx == ISC_MSG_BLOCKED_RESP )
{
uint8_t rsp_data[ 4 ] = { 0 };
_req_err = 0;
_err_code = 0;
tts_rsp_data( rsp_data );
_req_err |= rsp_data[ 0 ];
_req_err |= rsp_data[ 1 ] << 8;
_err_code |= rsp_data[ 2 ];
_err_code |= rsp_data[ 3 ] << 8;
if( _msg_block_callback != NULL )
_msg_block_callback( &_req_err, &_err_code );
return 1;
} else if ( rsp_idx == ISC_ERROR_IND ) {
uint8_t rsp_data[ 4 ] = { 0 };
_req_err = 0;
_err_code = 0;
tts_rsp_data( rsp_data );
_err_code |= rsp_data[ 0 ];
_err_code |= rsp_data[ 1 ] << 8;
if ( _err_code && _err_code < 0x8000 )
{
if( _err_callback != NULL )
_err_callback( &_err_code );
} else if ( _err_code && _err_code > 0x7FFF ) {
if( _fatal_err_callback != NULL )
_fatal_err_callback( &_err_code );
}
return 1;
} else if ( rsp_idx == ISC_TTS_READY_IND ) {
_tts_rdy_f = 1;
} else if ( rsp_idx == ISC_SPCODEC_READY_IND ) {
_spc_rdy_f = 1;
} else if ( rsp_idx == ISC_TTS_FINISHED_IND ) {
_tts_fin_f = 1;
} else if ( rsp_idx == ISC_SPCODEC_FINISHED_IND ) {
_spc_fin_f = 1;
}
return 0;
}
/******************************************************************************
* Public Function Definitions
*******************************************************************************/
void tts_init()
{
_req_err = 0;
_err_code = 0;
_tts_rdy_f = true;
_spc_rdy_f = true;
_tts_fin_f = true;
_spc_fin_f = true;
_audio_conf.as = 0x00;
_audio_conf.ag = 0x43;
_audio_conf.amp = 0x00;
_audio_conf.asr = ASR_11KHZ;
_audio_conf.ar = 0x00;
_audio_conf.atc = 0x00;
_audio_conf.acs = 0x00;
_audio_conf.dc = 0x00;
_tts_conf.sr = 0x01;
_tts_conf.voice = 0x00;
_tts_conf.ep = 0x00;
_tts_conf.lang = TTSV_US;
_tts_conf.sr_wpm_lsb = 0xc8;
_tts_conf.sr_wpm_msb = 0x00;
_tts_conf.ds = 0x00;
_tts_conf.res = 0x00;
_pman_conf.am_lsb = 0x01;
_pman_conf.am_msb = 0x00;
_pman_conf.spi_clk = 0x01;
_pman_conf.pad = PADDING_BYTE;
_flush_enable = false;
_msg_block_callback = NULL;
_fatal_err_callback = NULL;
_err_callback = NULL;
tts_hw_init();
}
void tts_msg_block_callback( void( *msg_blk_ptr )( uint16_t *req_ptr,
uint16_t *err_ptr ) )
{
_msg_block_callback = msg_blk_ptr;
}
void tts_fatal_err_callback( void( *fatal_err_ptr )( uint16_t *err_ptr ) )
{
_fatal_err_callback = fatal_err_ptr;
}
void tts_err_callback( void( *error_ptr )( uint16_t *err_ptr ) )
{
_err_callback = error_ptr;
}
void tts_mute()
{
tts_mute_cmd( true );
}
void tts_unmute()
{
tts_mute_cmd( false );
}
void tts_setup()
{
// pc.printf( "tts init data size: %i\n\r", sizeof(TTS_INIT_DATA2));
tts_version_boot();
int succ = tts_image_load( (uint8_t*)TTS_INIT_DATA, sizeof( TTS_INIT_DATA ) );
if ( succ != 0x0001 )
{
pc.printf("tts init data failed!\n\r");
pc.printf("returned value: %04X\n\r", succ);
wait(100);
}
pc.printf("tts image load done\n\r"); //executes OK
succ = tts_image_exec(); // executes ok
if ( succ != 0x0001 )
{
pc.printf("tts image exec failed!\n\r");
pc.printf("returned value: %04X\n\r", succ);
wait(100);
}
pc.printf("tts image exec done\n\r");
tts_interface_test();
pc.printf("tts interface test done\n\r");
tts_power_default_config();
pc.printf("tts power default done\n\r");
tts_audio_default_config();
pc.printf("tts audio default done\n\r");
tts_volume_set( 0 );
pc.printf("tts volume set done\n\r");
tts_default_config();
pc.printf("tts default config done\n\r");
}
void tts_version_boot( void )
{
uint8_t tmp_resp[ 16 ] = { 0 };
wait( RESET_TO_BOOT_TIME );
tts_parse_req( ISC_VERSION_REQ_BOOT, NULL, 0 );
while( !tts_rsp_chk( ISC_VERSION_RESP_BOOT ) )
{
tts_get_resp();
}
tts_hal_write_pad( 16);
tts_rsp_data( tmp_resp );
pc.printf("hwver0 %X \n\r", tmp_resp[ 0 ]);
pc.printf("hwver1 %X \n\r", tmp_resp[ 1 ]);
}
uint16_t tts_image_load(const uint8_t *image,
uint16_t count )
{
uint16_t tmp_resp = 0;
uint16_t index = 0;
uint8_t raw_resp[ 2 ] = { 0 };
while ( ( count - index ) > ( BOOT_MESSAGE_MAX - 4 ) )
{
tts_parse_boot_img( image + index, BOOT_MESSAGE_MAX - 4 );
wait(0.01);
index += ( BOOT_MESSAGE_MAX - 4 );
}
tts_parse_boot_img( image + index, count - index );
wait(0.01);
while( !tts_rsp_chk( ISC_BOOT_LOAD_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
//return ( tmp_resp == 1 ) ? tmp_resp : 0x0000;
}
uint16_t tts_image_exec()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
tts_parse_req( ISC_BOOT_RUN_REQ, NULL, 0 );
while( !tts_rsp_chk( ISC_BOOT_RUN_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_interface_test()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
wait( BOOT_TO_MAIN_MODE );
tts_parse_req( ISC_TEST_REQ, test, 8 );
while( !tts_rsp_chk( ISC_TEST_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_version_main( VER_t *buffer )
{
char tmp_char[ 3 ] = { 0 };
uint32_t tmp_fwf = 0;
uint32_t tmp_fwef = 0;
uint8_t tmp_resp[ 20 ] = { 0 };
tts_parse_req( ISC_VERSION_REQ_MAIN, NULL, 0 );
while( !tts_rsp_chk( ISC_VERSION_RESP_MAIN ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( tmp_resp );
sprintf(tmp_char, "%c", tmp_resp[ 0 ]);
strcpy( buffer->hwver, tmp_char );
strcat( buffer->hwver, "." );
sprintf(tmp_char, "%c", tmp_resp[ 1 ]);
strcat( buffer->hwver, tmp_char );
sprintf(tmp_char, "%c", tmp_resp[ 2 ]);
strcpy( buffer->fwver, tmp_char );
strcat( buffer->fwver, "." );
sprintf(tmp_char, "%c", tmp_resp[ 3 ]);
strcat( buffer->fwver, tmp_char );
strcat( buffer->fwver, "." );
sprintf(tmp_char, "%c", tmp_resp[ 12 ]);
strcat( buffer->fwver, tmp_char );
tmp_fwf |= tmp_resp[ 4 ];
tmp_fwf |= tmp_resp[ 5 ] << 8;
tmp_fwf |= tmp_resp[ 6 ] << 16;
tmp_fwf |= tmp_resp[ 7 ] << 24;
buffer->fwf = (FF_t)tmp_fwf;
tmp_fwef |= tmp_resp[ 8 ];
tmp_fwef |= tmp_resp[ 9 ] << 8;
tmp_fwef |= tmp_resp[ 10 ] << 16;
tmp_fwef |= tmp_resp[ 11 ] << 24;
buffer->fwef = (EFF_t)tmp_fwef;
return 0x0000;
}
uint16_t tts_power_default_config()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
tts_parse_req( ISC_PMAN_CONFIG_REQ, ( uint8_t* )&_pman_conf, 4 );
while( !tts_rsp_chk( ISC_PMAN_CONFIG_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_standby_enter()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
tts_parse_req( ISC_PMAN_STANDBY_ENTRY_REQ, NULL, 0 );
while( !tts_rsp_chk( ISC_PMAN_STANDBY_ENTRY_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_standby_exit()
{
wait( STBY_MODE_ENTERY );
tts_parse_req( ISC_PMAN_STANDBY_EXIT_IND, NULL, 0 );
while( !tts_rsp_chk( ISC_PMAN_STANDBY_EXIT_IND ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
return 0x0000;
}
uint16_t tts_audio_default_config()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
tts_parse_req( ISC_AUDIO_CONFIG_REQ, ( uint8_t* )&_audio_conf, 8 );
while( !tts_rsp_chk( ISC_AUDIO_CONFIG_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_audio_config( int8_t audio_gain,
ASR_t sample_rate,
bool dac_control )
{
ACONF_t audio_conf;
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
if ( audio_gain < -48 || audio_gain > 18 )
return 0xFFFF;
if ( sample_rate != 0 || sample_rate != 1 || sample_rate != 3 )
return 0xFFFF;
audio_conf.ag = ( uint8_t )audio_gain;
audio_conf.asr = sample_rate;
audio_conf.dc = dac_control;
tts_parse_req( ISC_AUDIO_CONFIG_REQ, ( uint8_t* )&audio_conf, 8 );
while( !tts_rsp_chk( ISC_AUDIO_CONFIG_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_volume_set( int16_t gain )
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_gain[ 2 ] = { 0 };
tmp_gain[ 0 ] = gain & 0x00FF;
tmp_gain[ 1 ] = ( gain & 0xFF00 ) >> 8;
tts_parse_req( ISC_AUDIO_VOULME_REQ, tmp_gain, 2 );
while( !tts_rsp_chk( ISC_AUDIO_VOLUME_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_audio_mute()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_mute[ 2 ] = { 1, 0 };
tts_parse_req( ISC_AUDIO_MUTE_REQ, tmp_mute, 2 );
while( !tts_rsp_chk( ISC_AUDIO_MUTE_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_audio_unmute()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_mute[ 2 ] = { 0, 0 };
tts_parse_req( ISC_AUDIO_MUTE_REQ, tmp_mute, 2 );
while( !tts_rsp_chk( ISC_AUDIO_MUTE_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_default_config()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
tts_parse_req( ISC_TTS_CONFIG_REQ, ( uint8_t* )&_tts_conf, 8 );
while( !tts_rsp_chk( ISC_TTS_CONFIG_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_config( uint8_t voice_type,
bool epson_parse,
TTSV_t language,
uint16_t speaking_rate )
{
TTSCONF_t tts_conf;
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
if ( voice_type > 8 )
return 0xFFFF;
if ( language > 4 )
return 0xFFFF;
if ( speaking_rate < 0x004B || speaking_rate > 0x0258 )
return 0xFFFF;
tts_conf.voice = voice_type;
tts_conf.ep = epson_parse;
tts_conf.lang = language;
tts_conf.sr_wpm_lsb = ( speaking_rate & 0x00FF );
tts_conf.sr_wpm_msb = ( speaking_rate & 0xFF00 ) >> 8;
tts_parse_req( ISC_TTS_CONFIG_REQ, ( uint8_t* )&tts_conf, 8 );
while( !tts_rsp_chk( ISC_TTS_CONFIG_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_speak( char *word )
{
bool tmp_f = false;
char *wptr = word;
uint8_t raw_resp[ 2 ] = { 0 };
uint16_t tmp_resp = 0;
uint32_t wlen = strlen( wptr );
tts_parse_speak_req( ISC_TTS_SPEAK_REQ, _flush_enable, wptr, wlen );
_tts_rdy_f = 0;
_tts_fin_f = 0;
while( !( tmp_f && _tts_rdy_f ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
if( tts_rsp_chk( ISC_TTS_SPEAK_RESP ) )
{
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
tmp_f = true;
}
}
return tmp_resp;
}
uint16_t tts_pause( void )
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_pause[ 2 ] = { 1, 0 };
tts_parse_req( ISC_TTS_PAUSE_REQ, tmp_pause, 2 );
while( !tts_rsp_chk( ISC_TTS_PAUSE_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_unpause( void )
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_pause[ 2 ] = { 0 };
tts_parse_req( ISC_TTS_PAUSE_REQ, tmp_pause, 2 );
while( !tts_rsp_chk( ISC_TTS_PAUSE_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_stop( bool reset )
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_reset[ 2 ] = { 0 };
if( reset )
tmp_reset[ 0 ] = 0x01;
tts_parse_req( ISC_TTS_STOP_REQ, tmp_reset, 2 );
while( !tts_rsp_chk( ISC_TTS_STOP_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_user_dict( bool erase,
uint8_t *udict_data,
uint16_t count )
{
uint16_t cnt = 2;
uint16_t tmp_rsp = 0;
uint8_t rsp_data[ 2 ] = { 0 };
uint8_t tmp_data[ BOOT_MESSAGE_MAX ] = { 0 };
if ( erase )
tmp_data[ 0 ] = 1;
while ( count-- )
tmp_data[ cnt ++ ] = *( udict_data++ );
tts_parse_req( ISC_TTS_UDICT_DATA_REQ, tmp_data, count + 2 );
while( !tts_rsp_chk( ISC_TTS_UDICT_DATA_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( rsp_data );
tmp_rsp |= rsp_data[ 0 ];
tmp_rsp |= rsp_data[ 1 ] << 8;
return tmp_rsp;
}
uint16_t tts_codec_configure()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_codec[ 32 ] = { 0 };
tmp_codec[ 0 ] = 0x01;
tmp_codec[ 1 ] = 0x01;
tmp_codec[ 24 ] = 0x02;
tts_parse_req( ISC_SPCODEC_CONFIG_REQ , tmp_codec, 32 );
while( !tts_rsp_chk( ISC_SPCODEC_CONFIG_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_codec_start( uint8_t *codec_data,
uint16_t count )
{
bool tmp_f = false;
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
if ( count != 512 || count != 1024 || count != 2048 )
return 0xFFFF;
while( !_spc_fin_f )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_parse_req( ISC_SPCODEC_START_REQ , codec_data, count );
_spc_rdy_f = 0;
_spc_fin_f = 0;
while( !( tmp_f && _spc_rdy_f ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
if( tts_rsp_chk( ISC_TTS_SPEAK_RESP ) )
{
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
tmp_f = true;
}
}
return tmp_resp;
}
uint16_t tts_codec_pause()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_data[ 2 ] = { 1, 0 };
tts_parse_req( ISC_SPCODEC_PAUSE_REQ , tmp_data, 2 );
while( !tts_rsp_chk( ISC_SPCODEC_PAUSE_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_codec_unpause()
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_data[ 2 ] = { 0 };
tts_parse_req( ISC_SPCODEC_PAUSE_REQ , tmp_data, 2 );
while( !tts_rsp_chk( ISC_SPCODEC_PAUSE_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
uint16_t tts_codec_stop( bool reset )
{
uint16_t tmp_resp = 0;
uint8_t raw_resp[ 2 ] = { 0 };
uint8_t tmp_data[ 2 ] = { 0 };
if( reset )
tmp_data[ 0 ] = 1;
tts_parse_req( ISC_SPCODEC_STOP_REQ, tmp_data, 2 );
while( !tts_rsp_chk( ISC_SPCODEC_PAUSE_RESP ) )
{
tts_get_resp();
if( _parse_ind() )
return _err_code;
}
tts_rsp_data( raw_resp );
tmp_resp |= raw_resp[ 0 ];
tmp_resp |= raw_resp[ 1 ] << 8;
return tmp_resp;
}
/******************************************************************************
* text_to_speech_hw.c
*******************************************************************************/
void _read_rsp()
{
uint8_t tmp_byte = 0;
uint16_t tmp_len = 0;
tts_hal_cs_low();
tts_hal_read( &tmp_byte, 1 );
if( tmp_byte == START_MESSAGE )
{
tts_hal_read( ( uint8_t* )&_last_rsp, 2 );
tmp_len |= _last_rsp.len[ 0 ];
tmp_len |= _last_rsp.len[ 1 ] << 8;
tts_hal_read( ( uint8_t* )&_last_rsp + 2, tmp_len );
} else {
wait( 0.005 );
}
tts_hal_cs_high();
}
void _write_req(bool boot)
{
uint16_t cnt = 0;
uint8_t start = START_MESSAGE;
cnt |= _last_req.len[ 0 ];
cnt |= _last_req.len[ 1 ] << 8;
tts_hal_cs_low();
if(boot)
{
tts_hal_write( &start, 1, true );
tts_hal_write( ( uint8_t* )&_last_req, cnt, true);
}
else
{
tts_hal_write( &start, 1, false );
tts_hal_write( ( uint8_t* ) &_last_req, cnt, false );
}
tts_hal_cs_high();
}
/******************************************************************************
* Public Function Definitions
*******************************************************************************/
void tts_hw_init( void )
{
tts_hal_init();
_ticker_f = false;
_ticker = 0;
_last_req.idx[ 0 ] = 0;
_last_req.idx[ 1 ] = 0;
_last_req.len[ 0 ] = 0;
_last_req.len[ 1 ] = 0;
memset( _last_req.payload, 0, MAIN_MESSAGE_MAX );
_last_rsp.idx[ 0 ] = 255;
_last_rsp.idx[ 1 ] = 255;
_last_rsp.len[ 0 ] = 0;
_last_rsp.len[ 1 ] = 0;
memset( _last_rsp.payload, 0, RESP_MESSAGE_MAX );
}
void tts_tick_isr()
{
_ticker++;
if( _ticker > 500 )
_ticker_f == true;
}
void tts_mute_cmd( bool cmd )
{
if( cmd )
tts_hal_mut_high();
else
tts_hal_mut_low();
}
void tts_parse_req( uint16_t req,
uint8_t *payload,
uint16_t pl_len )
{
uint8_t *pl = payload;
uint16_t i = 0;
uint16_t tmp = pl_len + 4;
_last_req.len[ 0 ] = tmp & 0x00FF;
_last_req.len[ 1 ] = ( tmp & 0xFF00 ) >> 8;
_last_req.idx[ 0 ] = req & 0x00FF;
_last_req.idx[ 1 ] = ( req & 0xFF00 ) >> 8;
_last_rsp.idx[ 0 ] = 0xFF;
_last_rsp.idx[ 1 ] = 0xFF;
if ( payload != NULL )
{
while ( pl_len-- )
_last_req.payload[ i++ ] = *( pl++ );
}
_write_req(true);
}
void tts_parse_boot_img( const uint8_t *payload,
uint16_t pl_len )
{
uint16_t i = 0;
uint16_t tmp = pl_len + 0x04;
_last_req.len[ 0 ] = tmp & 0x00FF;
_last_req.len[ 1 ] = ( tmp & 0xFF00 ) >> 8;
_last_req.idx[ 0 ] = 0x00;
_last_req.idx[ 1 ] = 0x10;
_last_rsp.idx[ 0 ] = 0xFF;
_last_rsp.idx[ 1 ] = 0xFF;
if ( payload != NULL )
{
while ( pl_len-- )
_last_req.payload[ i++ ] = payload[ i ];
}
_write_req(true);
}
void tts_parse_speak_req( uint16_t req,
uint8_t flush_en,
char *word,
uint16_t word_len )
{
char *ptr = word;
uint16_t i = 1;
uint16_t tmp = word_len;
word_len += 7;
_last_req.len[ 0 ] = word_len & 0x00FF;
_last_req.len[ 1 ] = ( word_len & 0xFF00 ) >> 8;
_last_req.idx[ 0 ] = req & 0x00FF;
_last_req.idx[ 1 ] = ( req & 0xFF00 ) >> 8;
_last_rsp.idx[ 0 ] = 0xFF;
_last_rsp.idx[ 1 ] = 0xFF;
if( flush_en )
{
_last_req.payload[ 0 ] = 1;
} else {
_last_req.payload[ 0 ] = 0;
}
while( tmp-- )
_last_req.payload[ i++ ] = *( ptr++ );
_last_req.payload[ i++ ] = 0x20;
_last_req.payload[ i ] = 0x00;
_write_req(true);
}
void tts_get_resp()
{
if( tts_hal_msg_rdy() )
{
_read_rsp();
}
}
bool tts_rsp_chk( uint16_t idx )
{
uint16_t tmp = 0;
tmp |= _last_rsp.idx[ 0 ];
tmp |= _last_rsp.idx[ 1 ] << 8;
// pc.printf(" idx = %X\n\r", tmp);
return ( idx == tmp ) ? true : false;
}
uint16_t tts_rsp_idx()
{
uint16_t tmp = 0;
tmp |= _last_rsp.idx[ 0 ];
tmp |= _last_rsp.idx[ 1 ] << 8;
return tmp;
}
void tts_rsp_data( uint8_t *buffer )
{
uint8_t *bfr = buffer;
uint16_t cnt = 0;
uint8_t *ptr = _last_rsp.payload;
cnt |= _last_rsp.len[ 0 ];
cnt |= _last_rsp.len[ 1 ] << 8;
cnt -= 4;
while( cnt-- )
*( bfr++ ) = *( ptr++ );
}
/*************** END OF FUNCTIONS *********************************************/
Dave Clarke
