It now results in a hissing/noisy sound, but from the right buffer posns.
are not tested, as they are not as vital, and will be much simpler
to debug after one or two sound paths have shown to work.
+Please be careful during these tests -- the sound may suddenly jump
+up in volume, and you should not have the headset anywhere near your
+ears if that happens. Also, avoid elongated high-volume and/or
+high-pitch sounds while working to get sound to behave. Your
+hearing is a precious instrument!
+
To build this, you would normally have to write a driver for the
sound chip or codec. This is best done through DMA, as that is the
best way of assuring a constant playing rate for samples. An
register uint8_t inval = *in++;
switch (codec) {
case CODEC_L8:
- //TODO// *out++ = (inval ^ 0x80) << 8;
-*out++ = 16384 + 1 + (outlen & 0x01)? 0: 32768;
+ *out++ = (inval ^ 0x80) << 8;
+//DOH!// *out++ = 16384 + 1 + (outlen & 0x01)? 0: 32768;
break;
case CODEC_L16:
*out++ = inval;
/* Copy plain samples to encoded samples */
//TODO// Better to switch once and then loop in a separate routine which may even be .asm -- but that could require a codec-specific state storage structure
int16_t codec_encode (codec_t codec, uint16_t *in, uint16_t inlen, uint8_t *out, uint16_t outlen) {
+bottom_printf ("Have %d, %d, %d at %04x\n", (intptr_t) in [0], (intptr_t) in [1], (intptr_t) in [2], (intptr_t) in);
while ((inlen > 0) && (outlen > 0)) {
register uint16_t inval = *in++;
bool signbit;
*out++ = 0x00;
break;
}
- *out++ = *in++ >> 8;
inlen--;
outlen--;
}
return outlen - inlen;
}
-/* If the chip has not been brought up yet, do it now */
-void tlv320aic2x_setup_chip (void) {
- // Now, if not done yet, unreset and setup the TLV320AIC20K codec
- if ((IODATA & (1 << 7)) == 0) {
- volatile uint16_t ctr;
- for (ctr=0; ctr < 7 * (600 / 12); ctr++) /* Wait 7x MCLK */ ;
-for (ctr=0; ctr < 7 * (600 / 12); ctr++) /* Wait 7x MCLK */ ;
-for (ctr=0; ctr < 7 * (600 / 12); ctr++) /* Wait 7x MCLK */ ;
-for (ctr=0; ctr < 7 * (600 / 12); ctr++) /* Wait 7x MCLK */ ;
-for (ctr=0; ctr < 7 * (600 / 12); ctr++) /* Wait 7x MCLK */ ;
- IODATA |= (1 << 7);
- for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ;
-for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ;
-for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ;
-for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ;
-for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ;
- }
-}
-
static int TODO_setratectr = 0;
/* Set a frequency divisor for the intended sample rate */
//TODO// Not all this code is properly split between generic TLV and specific BT200
-void tlv320aic2x_set_samplerate (uint32_t samplerate) {
+void tlv320aic2x_set_samplerate (uint8_t chan, uint32_t samplerate) {
uint16_t m, n, p;
-int chan = 0;
SPCR2_1 |= REGVAL_SPCR2_GRST_NOTRESET | REGVAL_SPCR2_FRST_NOTRESET;
{ uint32_t ctr = 100; while (ctr-- > 0) ; }
SPCR1_1 |= REGVAL_SPCR1_RRST_NOTRESET;
n = 1;
p = 2;
m = ( 30720000 / 16 ) / ( n * p * samplerate );
-// #ifdef TODO_OPTIMISE_PLL_AWAY
if (m % 8 == 0) {
// Save PLL energy without compromising accuracy
p = 8; // Factor 2 -> 8 so multiplied by 4
m >>= 2; // Divide by 4
}
-// #endif
while (m > 128) {
m >>= 1;
n <<= 1;
//
DMAGCR = REGVAL_DMAGCR_FREE;
DMAGTCR = 0x00; // No timeout support
-#ifdef TODO_DMA_CONFIGUREREN_BIJ_OPSTART
DMACCR_0 = REGVAL_DMACCR_SRCAMODE_CONST | REGVAL_DMACCR_DSTAMODE_POSTINC | REGVAL_DMACCR_PRIO | REGVAL_DMACCR_SYNC_MCBSP1_REV | REGVAL_DMACCR_REPEAT | REGVAL_DMACCR_AUTOINIT;
DMACCR_1 = REGVAL_DMACCR_SRCAMODE_POSTINC | REGVAL_DMACCR_DSTAMODE_CONST | REGVAL_DMACCR_PRIO | REGVAL_DMACCR_SYNC_MCBSP1_TEV | REGVAL_DMACCR_REPEAT | REGVAL_DMACCR_AUTOINIT;
DMACICR_0 = REGVAL_DMACICR_FRAMEIE;
DMACFN_0 = 1;
DMACFN_1 = 1;
#endif
-#endif
/* TODO? */
//
// Further initiation follows
tic55x_setup_timers ();
tic55x_setup_interrupts ();
ht162x_setup_lcd ();
- // tlv320aic2x_set_samplerate (8000);
+ // tlv320aic2x_set_samplerate (0, 8000);
tlv320aic2x_setup_sound ();
ksz8842_setup_network ();
// Enable INT0..INT3
uint8_t tlv320aic2x_getreg (uint8_t channel, uint8_t reg);
void tlv320aic2x_setreg (uint8_t channel, uint8_t reg, uint8_t val);
-void tlv320aic2x_set_samplerate (uint32_t samplerate);
+void tlv320aic2x_set_samplerate (uint8_t chan, uint32_t samplerate);
void dmahint_play (void);
void dmahint_record (void);
int16_t codec_decode (codec_t codec, uint8_t *in, uint16_t inlen, uint16_t *out, uint16_t outlen);
int16_t codec_encode (codec_t codec, uint16_t *in, uint16_t inlen, uint8_t *out, uint16_t outlen);
-void tlv320aic2x_setup_chip (void);
-void tlv320aic2x_set_samplerate (uint32_t samplerate);
+void tlv320aic2x_set_samplerate (uint8_t chan, uint32_t samplerate);
void bottom_codec_play_samplerate (uint8_t chan, uint32_t samplerate) {
* TODO: Consider disabling over 52000 (which is already excessive)
* TODO: Consider downsampling of rediculously high rates
*/
- tlv320aic2x_set_samplerate (samplerate);
+ tlv320aic2x_set_samplerate (chan, samplerate);
}
void bottom_codec_record_samplerate (uint8_t chan, uint32_t samplerate) {
samples = ar;
}
retval = codec_encode (codec,
- (uint16_t *) (samplebuf_play + nextread_play), samples,
+ (uint16_t *) (samplebuf_record + nextread_record), samples,
coded_samples, coded_bytes);
nextread_record += samples;
available_record -= samples;
nextread_record += retval;
available_record -= retval;
}
+ if (nextread_record >= BUFSZ) {
+ nextread_record -= BUFSZ;
+ }
dmahint_record ();
return retval;
//TODO:ALT-API-TEST// return available_record;
*/
void tlv320aic2x_setup_sound (void) {
uint8_t chan;
-#if 0
- tlv320aic2x_setreg (0, 3, 0x08); /* Software reset */
-{ uint32_t ctr;
- for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ;
-for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ;
-for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ;
-for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ;
-for (ctr=0; ctr < 132 * (600 / 12); ctr++) /* Wait at least 132 MCLK cycles */ ; }
-#endif
-#if 0
- // tlv320aic2x_setup_chip ();
-#else
- tlv320aic2x_set_samplerate (8000);
-#endif
+ tlv320aic2x_set_samplerate (0, 8000); /* Only once per codec */
// Setup the various registers in the TLV320AIC2x
for (chan = 0; chan < 2; chan++) {
tlv320aic2x_setreg (chan, 1, 0x49); /* Continuous 16-bit, 2.35V bias */
}
-#define top_main_sine_1khz top_main
-// #define top_main_delay_1sec top_main
+// #define top_main_sine_1khz top_main
+#define top_main_delay_1sec top_main
#ifdef CONFIG_FUNCTION_NETCONSOLE
void top_main_sine_1khz (void) {
uint16_t oldirqs = 0;
extern volatile uint16_t available_play;
+extern volatile uint16_t available_record;
uint8_t l16ctr = 1;
top_hook_update (bottom_phone_is_offhook ());
bottom_critical_region_end ();
uint16_t newplayed = tobeplayed;
uint16_t oldplayed = newplayed;
if (oldirqs != plyirqs) {
- bottom_printf ("New playing IRQs detected\n");
+ bottom_printf ("New playing IRQs detected; available_play=%d, available_record=%d\n", (intptr_t) available_play, (intptr_t) available_record);
oldirqs = plyirqs;
}
-#if 1
+#if 0
if (SPCR2_1 & REGVAL_SPCR2_XRDY) { DXR1_1 = sinewaveL16 [l16ctr++]; if (l16ctr == 8) { l16ctr = 0; } }
{ uint16_t _ = DRR1_1; }
#else
newplayed -= 8;
}
#endif
-#if 0
+#if 1
if (oldplayed != newplayed) {
bottom_printf ("available_play := %d\n", (intptr_t) available_play);
- bottom_printf ("Playbuffer reduced from %d to %d\n", (intptr_t) oldplayed, (intptr_t) newplayed);
+ // bottom_printf ("Playbuffer reduced from %d to %d\n", (intptr_t) oldplayed, (intptr_t) newplayed);
}
#endif
uint16_t loop = 0;
bottom_critical_region_end ();
top_hook_update (bottom_phone_is_offhook ());
- bottom_codec_play_samplerate (PHONE_CHANNEL_TELEPHONY, 8000);
- bottom_codec_record_samplerate (PHONE_CHANNEL_TELEPHONY, 8000);
+ memset (samples, 0 + 128, sizeof (samples));
+ bottom_codec_play_samplerate (PHONE_CHANNEL_TELEPHONY, 1000);
+ bottom_codec_record_samplerate (PHONE_CHANNEL_TELEPHONY, 1000);
bottom_soundchannel_setvolume (PHONE_CHANNEL_TELEPHONY, 127);
- bottom_show_fixed_msg (APP_LEVEL_ZERO, FIXMSG_READY); // TODO: Not really necessary
+ bottom_show_fixed_msg (APP_LEVEL_ZERO, FIXMSG_READY);
bottom_printf ("Running the development function \"echo\" (Test sound)\n");
while (true) {
#if 0
rec = 10000 - recpos;
}
if (rec > 0) {
- bottom_printf ("Recording %d extends buffer from %d to %d\n", (intptr_t) rec, (intptr_t) sampled, (intptr_t) (rec+sampled));
+ // bottom_printf ("Recording %d at %d extends buffer from %d to %d\n", (intptr_t) rec, (intptr_t) recpos, (intptr_t) sampled, (intptr_t) (rec+sampled));
+ // bottom_printf ("Recording %d at %d\n", (intptr_t) rec, (intptr_t) recpos);
// Codec implies that #samples and #bytes are the same
- rec -= abs (bottom_codec_record (0, CODEC_G711A, samples + recpos, rec, rec));
+ rec -= abs (bottom_codec_record (0, CODEC_L8, samples + recpos, rec, rec));
+ bottom_printf ("Got 0x%02x, 0x%02x, 0x%02x, ...\n", (intptr_t) samples [recpos], (intptr_t) samples [recpos+1], (intptr_t) samples [recpos+2]);
sampled += rec;
recpos += rec;
if (recpos >= 10000) {
- recpos = 0;
+ recpos -= 10000;
}
bottom_critical_region_begin ();
//TODO:SPYING-ON-NEXT-LINE// toberecorded -= rec;
- { extern uint16_t available_record; toberecorded = available_record; }
+ { extern volatile uint16_t available_record; toberecorded = available_record; }
bottom_critical_region_end ();
}
bottom_led_set (LED_IDX_SPEAKERPHONE, 0);
ply = 10000 - playpos;
}
if (ply > 0) {
- bottom_printf ("Playback of %d samples reduces buffer from %d to %d\n", (intptr_t) ply, (intptr_t) sampled, (intptr_t) (sampled - ply));
- ply -= abs (bottom_codec_play (0, CODEC_G711A, samples + playpos, ply, ply));
+ // bottom_printf ("Playback of %d samples at %d reduces buffer from %d to %d\n", (intptr_t) ply, (intptr_t) playpos, (intptr_t) sampled, (intptr_t) (sampled - ply));
+ // bottom_printf ("Playback of %d samples at %d\n", (intptr_t) ply, (intptr_t) playpos);
+ ply -= abs (bottom_codec_play (0, CODEC_L8, samples + playpos, ply, ply));
sampled -= ply;
playpos += ply;
if (playpos >= 10000) {
- playpos = 0;
+ playpos -= 10000;
}
bottom_led_set (LED_IDX_HANDSET, 0);
}
*/
-/* This mini network stack is designed for very simple targets,
+/**
+ * This mini network stack is designed for very simple targets,
* such as network testing or a bootloader. It only supports
* IEEE 802.2, that is, LLC. And it even does a fairly modest
* job at that.
* a more complete network stack like the phone application's.
* Hence the name llconly.c!
*
+ * Use this minimal network stack where you have no other way of
+ * extracting logs, or exchanging bootloadables. There is an
+ * alternative LLC implementation in the "real" phone firmware,
+ * which is much better because it can rely on resend timers.
+ *
* From: Rick van Rein <rick@openfortress.nl>
*/