00001
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "pdca.h"
00046 #include "abdac.h"
00047 #include "gpio.h"
00048 #include "intc.h"
00049 #include "board.h"
00050 #include "tpa6130.h"
00051 #include "conf_tpa6130.h"
00052 #include "audio.h"
00053
00054 #include "cs2200.h"
00055
00056 #if (defined __AVR32_UC3A3256__) || (defined __AVR32_UC3A3128__) || (defined __AVR32_UC3A364__) || \
00057 (defined __AVR32_UC3A3256S__) || (defined __AVR32_UC3A3128S__) || (defined __AVR32_UC3A364S__) || \
00058 (defined __AT32UC3A3256__) || (defined __AT32UC3A3128__) || (defined __AT32UC3A364__) || \
00059 (defined __AT32UC3A3256S__) || (defined __AT32UC3A3128S__) || (defined __AT32UC3A364S__)
00060 #include "twim.h"
00061 #else
00062 #include "twi.h"
00063 #endif
00064
00065 #include "conf_audio_player.h"
00066
00067
00068
00069
00070 #define TPA6130_CONTROL 0x1
00071 #define TPA6130_VOLUME_AND_MUTE 0x2
00072 #define TPA6130_OUTPUT_IMPEDANCE 0x3
00073 #define TPA6130_I2C_ADDRESS_VERSION 0x4
00074
00075
00076 #define TPA6130_CONTROL_DEFAULT 0x00
00077
00078 #define TPA6130_VOLUME_AND_MUTE_DEFAULT 0x0F
00079 #define TPA6130_OUTPUT_IMPEDANCE_DEFAULT 0x00
00080 #define TPA6130_I2C_ADDRESS_VERSION_DEFAULT 0x02
00081
00082
00083 #define HP_EN_L 0x80
00084 #define HP_EN_R 0x40
00085 #define STEREO_HP 0x00
00086 #define DUAL_MONO_HP 0x10
00087 #define BRIDGE_TIED_LOAD 0x20
00088 #define SW_SHUTDOWN 0x01
00089 #define THERMAL 0x02
00090
00091 #define MUTE_L 0x80
00092 #define MUTE_R 0x40
00093
00094 #define HIZ_L 0x80
00095 #define HIZ_R 0x40
00096
00097 #define VERSION 0x02
00098
00099
00100
00101
00102 #define TPA6130_MAX_VOLUME 0x3F
00103
00104
00105
00106 #define TWI_READ_HW 0
00107
00108 #define TWI_READ_SR 1
00109
00110
00111
00112
00113
00114
00115 #if(TPA6130_MODE == TPA6130_MODE_STEREO)
00116 #if(TPA6130_SIG == TPA6130_SIG_DIFF)
00117 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00118 {
00119 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION},
00120 {TPA6130_DATA1_PIN, TPA6130_DATA1_FUNCTION},
00121 {TPA6130_DATAN0_PIN, TPA6130_DATAN0_FUNCTION},
00122 {TPA6130_DATAN1_PIN, TPA6130_DATAN1_FUNCTION}
00123 };
00124 #elif(TPA6130_SIG == TPA6130_SIG_POS)
00125 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00126 {
00127 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION},
00128 {TPA6130_DATA1_PIN, TPA6130_DATA1_FUNCTION}
00129 };
00130 #else
00131 #error No valid TPA6130_SIG is defined
00132 #endif
00133 #elif((TPA6130_MODE == TPA6130_MODE_MONO)
00134 #if(TPA6130_SIG == TPA6130_SIG_DIFF)
00135 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00136 {
00137 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION},
00138 {TPA6130_DATAN0_PIN, TPA6130_DATAN0_FUNCTION}
00139 };
00140 #elif(TPA6130_SIG == TPA6130_SIG_POS)
00141 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00142 {
00143 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION}
00144 };
00145 #else
00146 #error No valid TPA6130_SIG is defined
00147 #endif
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 #else
00166 #error No output mode defined in configuration setup
00167 #endif
00168
00169
00170
00171 static struct
00172 {
00173 U8 num_channels;
00174 void (*callback)(U32 arg);
00175 U32 callback_opt;
00176 } tpa6130_output_param =
00177 {
00178 .num_channels = 0,
00179 .callback = NULL,
00180 .callback_opt = 0,
00181 };
00182
00184 extern U32 usb_stream_resync_frequency;
00185 volatile avr32_pm_t *pm = &AVR32_PM;
00186
00189 static struct
00190 {
00191 U8 control;
00192 U8 volume_and_mute;
00193 U8 output_impedance;
00194 U8 i2c_address_version;
00195 } tpa6130_shadow_regs =
00196 {
00197 .control = TPA6130_CONTROL_DEFAULT,
00198 .volume_and_mute = TPA6130_VOLUME_AND_MUTE_DEFAULT,
00199 .output_impedance = TPA6130_OUTPUT_IMPEDANCE_DEFAULT,
00200 .i2c_address_version = TPA6130_I2C_ADDRESS_VERSION_DEFAULT,
00201 };
00202
00203 #if (defined __GNUC__) && (defined __AVR32__)
00204 __attribute__((__interrupt__))
00205 #elif (defined __ICCAVR32__)
00206 __interrupt
00207 #endif
00208 static void tpa6130_abdac_tx_pdca_int_handler(void)
00209 {
00210 if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
00211 {
00212 pdca_disable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
00213 if (tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00214 tpa6130_output_param.callback(AUDIO_DAC_OUT_OF_SAMPLE_CB);
00215 }
00216
00217 if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
00218 {
00219 pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00220 if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB)
00221 tpa6130_output_param.callback(AUDIO_DAC_RELOAD_CB);
00222 }
00223 }
00224
00230 static void tpa6130_write_data(U8 reg, U8 data)
00231 {
00232 U16 message = (reg << 8) | data;
00233 int twi_status;
00234
00235 twi_package_t twi_package =
00236 {
00237 .chip = TPA6130_TWI_ADDRESS,
00238 .addr_length = 0,
00239 .buffer = &message,
00240 .length = sizeof(message)
00241 };
00242
00243 do
00244 {
00245 twi_status=twi_master_write(TPA6130_TWI, &twi_package);
00246 }
00247 while( twi_status != TWI_SUCCESS );
00248
00249
00250 *(((U8 *) &tpa6130_shadow_regs) + reg - 1) = data;
00251 }
00252
00260 static U8 tpa6130_read_data(U8 reg, Bool shadow)
00261 {
00262 U8 data;
00263
00264 if(shadow)
00265 {
00266 data = *((U8 *) &tpa6130_shadow_regs + reg - 1);
00267 }
00268 else
00269 {
00270 twi_package_t twi_package =
00271 {
00272 .chip = TPA6130_TWI_ADDRESS,
00273 .addr_length = 1,
00274 .addr = reg,
00275 .buffer = &data,
00276 .length = sizeof(data)
00277 };
00278 twi_master_read(TPA6130_TWI, &twi_package);
00279 }
00280
00281
00282
00283
00284
00285
00286 return data;
00287 }
00288
00299 S8 tpa6130_init(void)
00300 {
00301
00302 if(twi_probe(TPA6130_TWI, TPA6130_TWI_ADDRESS) != TWI_SUCCESS)
00303 return TWI_NO_CHIP_FOUND;
00304
00305 if(tpa6130_read_data(TPA6130_I2C_ADDRESS_VERSION, TWI_READ_HW)!= VERSION)
00306 {
00307 return -8;
00308 }
00309
00310
00311 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, tpa6130_shadow_regs.volume_and_mute);
00312
00313 tpa6130_write_data(TPA6130_CONTROL,(TPA6130_MODE << 4) | HP_EN_L | HP_EN_R);
00314
00315 return TWI_SUCCESS;
00316 }
00317
00321 void tpa6130_shutdown(void)
00322 {
00323 U8 data;
00324 data = tpa6130_read_data(TPA6130_CONTROL, TWI_READ_HW);
00325 tpa6130_write_data(TPA6130_CONTROL, data | SW_SHUTDOWN);
00326 }
00329 void tpa6130_powerup(void)
00330 {
00331 U8 data;
00332 data = tpa6130_read_data(TPA6130_CONTROL, TWI_READ_HW);
00333 tpa6130_write_data(TPA6130_CONTROL, data & (~SW_SHUTDOWN));
00334 }
00342 void tpa6130_set_volume(S8 volume)
00343 {
00344 S8 new_volume = volume;
00345
00346 if(volume > TPA6130_VOL_MAX)
00347 {
00348 new_volume = TPA6130_VOL_MAX;
00349 }
00350 else if(volume <= TPA6130_VOL_MIN )
00351 {
00352
00353 new_volume = MUTE_L|MUTE_R;
00354 }
00355
00356 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, new_volume );
00357 }
00358
00363 S8 tpa6130_get_volume(void)
00364 {
00365 return tpa6130_read_data(TPA6130_VOLUME_AND_MUTE, TWI_READ_SR);
00366 }
00367
00377 void tpa6130_dac_start(U32 sample_rate_hz,
00378 U8 num_channels,
00379 U8 bits_per_sample,
00380 Bool swap_channels,
00381 void (*callback)(U32 arg),
00382 U32 callback_opt,
00383 U32 pba_hz)
00384 {
00385
00386 tpa6130_dac_stop();
00387
00388
00389 gpio_enable_module(TPA6130_ABDAC_GPIO_MAP,
00390 sizeof(TPA6130_ABDAC_GPIO_MAP) /
00391 sizeof(TPA6130_ABDAC_GPIO_MAP[0]));
00392
00393
00394 tpa6130_dac_setup(sample_rate_hz,
00395 num_channels,
00396 bits_per_sample,
00397 swap_channels,
00398 callback,
00399 callback_opt,
00400 pba_hz);
00401
00402
00403
00404
00405 INTC_register_interrupt(&tpa6130_abdac_tx_pdca_int_handler,
00406 TPA6130_ABDAC_PDCA_IRQ,
00407 TPA6130_ABDAC_PDCA_INT_LEVEL);
00408
00409 tpa6130_powerup();
00410
00411 }
00412
00417 void tpa6130_dac_setup(U32 sample_rate_hz,
00418 U8 num_channels,
00419 U8 bits_per_sample,
00420 Bool swap_channels,
00421 void (*callback)(U32 arg),
00422 U32 callback_opt,
00423 U32 pba_hz)
00424 {
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 if (sample_rate_hz < (8000 + 8021) / 2)
00436 {
00437 }
00438 else if (sample_rate_hz < (8021 + 32000) / 2)
00439 {
00440 }
00441 else if (sample_rate_hz < (32000 + 44100) / 2)
00442 {
00443 usb_stream_resync_frequency = 8192000;
00444 cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency));
00445 pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(8192000);
00446 }
00447 else if (sample_rate_hz < (44100 + 48000) / 2)
00448 {
00449 usb_stream_resync_frequency = 11289600;
00450 cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency));
00451 pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(11289600);
00452 }
00453 else if (sample_rate_hz < (48000 + 88200) / 2)
00454 {
00455 usb_stream_resync_frequency = 12288000;
00456 cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency));
00457 pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(12288000);
00458 }
00459 else if (sample_rate_hz < (88200 + 96000) / 2)
00460 {
00461 }
00462 else
00463 {
00464 }
00465
00466
00467
00468
00469 tpa6130_output_param.num_channels = num_channels;
00470 tpa6130_output_param.callback = callback;
00471 tpa6130_output_param.callback_opt = callback_opt;
00472
00473
00474 tpa6130_init();
00475
00476 #if defined(TPA6130_DAC_CLOCK_SET_CALLBACK)
00477 TPA6130_DAC_CLOCK_SET_CALLBACK(sample_rate_hz);
00478 #else
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 pm->GCCTRL[ABDAC_GCLK].div= 0;
00490 pm->GCCTRL[ABDAC_GCLK].diven=0;
00491 pm->GCCTRL[ABDAC_GCLK].pllsel=0;
00492 pm->GCCTRL[ABDAC_GCLK].oscsel=1;
00493 #endif
00494
00495 if(swap_channels)
00496 {
00497 abdac_swap_channels(TPA6130_ABDAC);
00498 }
00499 abdac_enable(TPA6130_ABDAC);
00500
00501
00502
00503
00504
00505 pdca_channel_options_t tpa6130_abdac_pdca_options =
00506 {
00507 .addr = NULL,
00508 .size = 0,
00509 .r_addr = 0,
00510 .r_size = 0,
00511 .pid = TPA6130_ABDAC_PDCA_PID,
00512 .transfer_size = PDCA_TRANSFER_SIZE_WORD
00513 };
00514
00515
00516
00517
00518
00519 pdca_init_channel(TPA6130_ABDAC_PDCA_CHANNEL,
00520 &tpa6130_abdac_pdca_options);
00521
00522
00523 pdca_enable(TPA6130_ABDAC_PDCA_CHANNEL);
00524
00525 }
00526
00533 Bool tpa6130_dac_output(void *sample_buffer, size_t sample_length)
00534 {
00535
00536
00537
00538
00539
00540 if(!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) &
00541 PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
00542 {
00543 return FALSE;
00544 }
00545
00546
00547 if(sample_length)
00548 {
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 pdca_reload_channel(TPA6130_ABDAC_PDCA_CHANNEL,
00559 sample_buffer, sample_length);
00560
00561
00562
00563
00564
00565
00566 if(tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00567 pdca_enable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
00568 if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB)
00569 pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00570 }
00571 return TRUE;
00572 }
00573
00574 Bool tpa6130_dac_is_volume_muted(void)
00575 {
00576 return FALSE;
00577 }
00578
00579 void tpa6130_dac_mute(Bool mute)
00580 {
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 S8 volume = tpa6130_get_volume();
00605 if (mute)
00606 {
00607 U32 save_dac_reload_callback_opt;
00608
00609
00610 volume = volume | MUTE_L | MUTE_R;
00611 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume);
00612
00613 save_dac_reload_callback_opt = tpa6130_output_param.callback_opt;
00614 tpa6130_output_param.callback_opt = 0;
00615
00616 pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00617 while (!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE));
00618
00619 tpa6130_output_param.callback_opt = save_dac_reload_callback_opt;
00620 }
00621 else
00622 {
00623
00624 pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00625
00626 volume = volume & (~(MUTE_L | MUTE_R));
00627 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume);
00628 }
00629 }
00630
00631 Bool tpa6130_dac_is_volume_boosted(void)
00632 {
00633 return FALSE;
00634 }
00635
00639 U8 tpa6130_dac_get_volume(void)
00640 {
00641
00642
00643
00644
00645 U16 raw_volume;
00646 raw_volume = (tpa6130_get_volume() & (~(MUTE_L | MUTE_R)));
00647 return (U8) ((raw_volume * 255) / TPA6130_VOL_MAX);
00648 }
00649
00652 void tpa6130_dac_set_volume(U8 volume)
00653 {
00654 tpa6130_set_volume(volume);
00655 }
00656
00661 void tpa6130_dac_increase_volume(void)
00662 {
00663 S8 volume = tpa6130_get_volume()& (~(MUTE_L | MUTE_R));
00664 if( volume < TPA6130_VOL_MIN )
00665 volume = TPA6130_VOL_MIN;
00666 tpa6130_set_volume(volume+1);
00667 }
00668
00673 void tpa6130_dac_decrease_volume(void)
00674 {
00675 S8 volume = tpa6130_get_volume()& (~(MUTE_L | MUTE_R));;
00676 if( volume > TPA6130_VOL_MIN )
00677 --volume;
00678 tpa6130_set_volume( volume );
00679 }
00680
00683 void tpa6130_dac_flush(void)
00684 {
00685 pdca_disable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
00686 pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00687
00688
00689
00690
00691
00692 pdca_disable (TPA6130_ABDAC_PDCA_CHANNEL );
00693 pdca_load_channel (TPA6130_ABDAC_PDCA_CHANNEL,0x0, 0);
00694 pdca_reload_channel(TPA6130_ABDAC_PDCA_CHANNEL,0x0, 0);
00695 pdca_enable (TPA6130_ABDAC_PDCA_CHANNEL );
00696 }
00697
00702 void tpa6130_dac_stop(void)
00703 {
00704
00705 tpa6130_shutdown();
00706
00707
00708
00709
00710
00711
00712 abdac_disable(TPA6130_ABDAC);
00713
00714
00715 pdca_disable(TPA6130_ABDAC_PDCA_CHANNEL);
00716
00717
00718 gpio_enable_gpio(TPA6130_ABDAC_GPIO_MAP,
00719 sizeof(TPA6130_ABDAC_GPIO_MAP)
00720 / sizeof(TPA6130_ABDAC_GPIO_MAP[0]));
00721
00722 tpa6130_output_param.num_channels = 0;
00723 tpa6130_output_param.callback = NULL;
00724 tpa6130_output_param.callback_opt = 0;
00725 }