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
00055 #if (defined __AVR32_UC3A3256__) || (defined __AVR32_UC3A3128__) || (defined __AVR32_UC3A364__) || \
00056 (defined __AVR32_UC3A3256S__) || (defined __AVR32_UC3A3128S__) || (defined __AVR32_UC3A364S__) || \
00057 (defined __AT32UC3A3256__) || (defined __AT32UC3A3128__) || (defined __AT32UC3A364__) || \
00058 (defined __AT32UC3A3256S__) || (defined __AT32UC3A3128S__) || (defined __AT32UC3A364S__)
00059 #include "twim.h"
00060 #else
00061 #include "twi.h"
00062 #endif
00063
00064
00065
00066
00067 #define TPA6130_CONTROL 0x1
00068 #define TPA6130_VOLUME_AND_MUTE 0x2
00069 #define TPA6130_OUTPUT_IMPEDANCE 0x3
00070 #define TPA6130_I2C_ADDRESS_VERSION 0x4
00071
00072
00073 #define TPA6130_CONTROL_DEFAULT 0x00
00074
00075 #define TPA6130_VOLUME_AND_MUTE_DEFAULT 0x0F
00076 #define TPA6130_OUTPUT_IMPEDANCE_DEFAULT 0x00
00077 #define TPA6130_I2C_ADDRESS_VERSION_DEFAULT 0x02
00078
00079
00080 #define HP_EN_L 0x80
00081 #define HP_EN_R 0x40
00082 #define STEREO_HP 0x00
00083 #define DUAL_MONO_HP 0x10
00084 #define BRIDGE_TIED_LOAD 0x20
00085 #define SW_SHUTDOWN 0x01
00086 #define THERMAL 0x02
00087
00088 #define MUTE_L 0x80
00089 #define MUTE_R 0x40
00090
00091 #define HIZ_L 0x80
00092 #define HIZ_R 0x40
00093
00094 #define VERSION 0x02
00095
00096
00097
00098
00099 #define TPA6130_MAX_VOLUME 0x3F
00100
00101
00102
00103 #define TWI_READ_HW 0
00104
00105 #define TWI_READ_SR 1
00106
00107
00108
00109
00110
00111
00112 #if(TPA6130_MODE == TPA6130_MODE_STEREO)
00113 #if(TPA6130_SIG == TPA6130_SIG_DIFF)
00114 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00115 {
00116 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION},
00117 {TPA6130_DATA1_PIN, TPA6130_DATA1_FUNCTION},
00118 {TPA6130_DATAN0_PIN, TPA6130_DATAN0_FUNCTION},
00119 {TPA6130_DATAN1_PIN, TPA6130_DATAN1_FUNCTION}
00120 };
00121 #elif(TPA6130_SIG == TPA6130_SIG_POS)
00122 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00123 {
00124 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION},
00125 {TPA6130_DATA1_PIN, TPA6130_DATA1_FUNCTION}
00126 };
00127 #else
00128 #error No valid TPA6130_SIG is defined
00129 #endif
00130 #elif((TPA6130_MODE == TPA6130_MODE_MONO)
00131 #if(TPA6130_SIG == TPA6130_SIG_DIFF)
00132 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00133 {
00134 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION},
00135 {TPA6130_DATAN0_PIN, TPA6130_DATAN0_FUNCTION}
00136 };
00137 #elif(TPA6130_SIG == TPA6130_SIG_POS)
00138 static const gpio_map_t TPA6130_ABDAC_GPIO_MAP =
00139 {
00140 {TPA6130_DATA0_PIN, TPA6130_DATA0_FUNCTION}
00141 };
00142 #else
00143 #error No valid TPA6130_SIG is defined
00144 #endif
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 #else
00163 #error No output mode defined in configuration setup
00164 #endif
00165
00166
00167
00168 static struct
00169 {
00170 U8 num_channels;
00171 void (*callback)(U32 arg);
00172 U32 callback_opt;
00173 } tpa6130_output_param =
00174 {
00175 .num_channels = 0,
00176 .callback = NULL,
00177 .callback_opt = 0,
00178 };
00179
00182 static struct
00183 {
00184 U8 control;
00185 U8 volume_and_mute;
00186 U8 output_impedance;
00187 U8 i2c_address_version;
00188 } tpa6130_shadow_regs =
00189 {
00190 .control = TPA6130_CONTROL_DEFAULT,
00191 .volume_and_mute = TPA6130_VOLUME_AND_MUTE_DEFAULT,
00192 .output_impedance = TPA6130_OUTPUT_IMPEDANCE_DEFAULT,
00193 .i2c_address_version = TPA6130_I2C_ADDRESS_VERSION_DEFAULT,
00194 };
00195
00196 #if (defined __GNUC__) && (defined __AVR32__)
00197 __attribute__((__interrupt__))
00198 #elif (defined __ICCAVR32__)
00199 __interrupt
00200 #endif
00201 static void tpa6130_abdac_tx_pdca_int_handler(void)
00202 {
00203 if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
00204 {
00205 pdca_disable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
00206 if (tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00207 tpa6130_output_param.callback(AUDIO_DAC_OUT_OF_SAMPLE_CB);
00208 }
00209
00210 if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
00211 {
00212 pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00213 if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB)
00214 tpa6130_output_param.callback(AUDIO_DAC_RELOAD_CB);
00215 }
00216 }
00217
00223 static void tpa6130_write_data(U8 reg, U8 data)
00224 {
00225 U16 message = (reg << 8) | data;
00226 int twi_status;
00227
00228 twi_package_t twi_package =
00229 {
00230 .chip = TPA6130_TWI_ADDRESS,
00231 .addr_length = 0,
00232 .buffer = &message,
00233 .length = sizeof(message)
00234 };
00235
00236 do
00237 {
00238 twi_status=twi_master_write(TPA6130_TWI, &twi_package);
00239 }
00240 while( twi_status != TWI_SUCCESS );
00241
00242
00243 *(((U8 *) &tpa6130_shadow_regs) + reg - 1) = data;
00244 }
00245
00253 static U8 tpa6130_read_data(U8 reg, Bool shadow)
00254 {
00255 U8 data;
00256
00257 if(shadow)
00258 {
00259 data = *((U8 *) &tpa6130_shadow_regs + reg - 1);
00260 }
00261 else
00262 {
00263 twi_package_t twi_package =
00264 {
00265 .chip = TPA6130_TWI_ADDRESS,
00266 .addr_length = 1,
00267 .addr = reg,
00268 .buffer = &data,
00269 .length = sizeof(data)
00270 };
00271 twi_master_read(TPA6130_TWI, &twi_package);
00272 }
00273
00274
00275
00276
00277
00278
00279 return data;
00280 }
00281
00292 S8 tpa6130_init(void)
00293 {
00294
00295 if(twi_probe(TPA6130_TWI, TPA6130_TWI_ADDRESS) != TWI_SUCCESS)
00296 return TWI_NO_CHIP_FOUND;
00297
00298 if(tpa6130_read_data(TPA6130_I2C_ADDRESS_VERSION, TWI_READ_HW)!= VERSION)
00299 {
00300 return -8;
00301 }
00302
00303
00304 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, tpa6130_shadow_regs.volume_and_mute);
00305
00306 tpa6130_write_data(TPA6130_CONTROL,(TPA6130_MODE << 4) | HP_EN_L | HP_EN_R);
00307
00308 return TWI_SUCCESS;
00309 }
00310
00314 void tpa6130_shutdown(void)
00315 {
00316 U8 data;
00317 data = tpa6130_read_data(TPA6130_CONTROL, TWI_READ_HW);
00318 tpa6130_write_data(TPA6130_CONTROL, data | SW_SHUTDOWN);
00319 }
00322 void tpa6130_powerup(void)
00323 {
00324 U8 data;
00325 data = tpa6130_read_data(TPA6130_CONTROL, TWI_READ_HW);
00326 tpa6130_write_data(TPA6130_CONTROL, data & (~SW_SHUTDOWN));
00327 }
00335 void tpa6130_set_volume(S8 volume)
00336 {
00337 S8 new_volume = volume;
00338
00339 if(volume > TPA6130_VOL_MAX)
00340 {
00341 new_volume = TPA6130_VOL_MAX;
00342 }
00343 else if(volume <= TPA6130_VOL_MIN )
00344 {
00345
00346 new_volume = MUTE_L|MUTE_R;
00347 }
00348
00349 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, new_volume );
00350 }
00351
00356 S8 tpa6130_get_volume(void)
00357 {
00358 return tpa6130_read_data(TPA6130_VOLUME_AND_MUTE, TWI_READ_SR);
00359 }
00360
00370 void tpa6130_dac_start(U32 sample_rate_hz,
00371 U8 num_channels,
00372 U8 bits_per_sample,
00373 Bool swap_channels,
00374 void (*callback)(U32 arg),
00375 U32 callback_opt,
00376 U32 pba_hz)
00377 {
00378
00379 tpa6130_dac_stop();
00380
00381
00382 gpio_enable_module(TPA6130_ABDAC_GPIO_MAP,
00383 sizeof(TPA6130_ABDAC_GPIO_MAP) /
00384 sizeof(TPA6130_ABDAC_GPIO_MAP[0]));
00385
00386
00387 tpa6130_dac_setup(sample_rate_hz,
00388 num_channels,
00389 bits_per_sample,
00390 swap_channels,
00391 callback,
00392 callback_opt,
00393 pba_hz);
00394
00395
00396
00397
00398 INTC_register_interrupt(&tpa6130_abdac_tx_pdca_int_handler,
00399 TPA6130_ABDAC_PDCA_IRQ,
00400 TPA6130_ABDAC_PDCA_INT_LEVEL);
00401
00402 tpa6130_powerup();
00403
00404 }
00405
00410 void tpa6130_dac_setup(U32 sample_rate_hz,
00411 U8 num_channels,
00412 U8 bits_per_sample,
00413 Bool swap_channels,
00414 void (*callback)(U32 arg),
00415 U32 callback_opt,
00416 U32 pba_hz)
00417 {
00418
00419 tpa6130_output_param.num_channels = num_channels;
00420 tpa6130_output_param.callback = callback;
00421 tpa6130_output_param.callback_opt = callback_opt;
00422
00423
00424 tpa6130_init();
00425
00426 #if defined(TPA6130_DAC_CLOCK_SET_CALLBACK)
00427 TPA6130_DAC_CLOCK_SET_CALLBACK(sample_rate_hz);
00428 #else
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 if(!abdac_set_dac_sample_rate(sample_rate_hz)) {
00440
00441
00442 abdac_set_dac_hz(TPA6130_ABDAC, TPA6130_ABDAC_GCLK_INPUT_HZ,sample_rate_hz);
00443 }
00444 #endif
00445
00446 if(swap_channels)
00447 {
00448 abdac_swap_channels(TPA6130_ABDAC);
00449 }
00450 abdac_enable(TPA6130_ABDAC);
00451
00452
00453
00454
00455
00456 pdca_channel_options_t tpa6130_abdac_pdca_options =
00457 {
00458 .addr = NULL,
00459 .size = 0,
00460 .r_addr = 0,
00461 .r_size = 0,
00462 .pid = TPA6130_ABDAC_PDCA_PID,
00463 .transfer_size = PDCA_TRANSFER_SIZE_WORD
00464 };
00465
00466
00467
00468
00469
00470 pdca_init_channel(TPA6130_ABDAC_PDCA_CHANNEL,
00471 &tpa6130_abdac_pdca_options);
00472
00473
00474 pdca_enable(TPA6130_ABDAC_PDCA_CHANNEL);
00475
00476 }
00477
00484 Bool tpa6130_dac_output(void *sample_buffer, size_t sample_length)
00485 {
00486
00487
00488
00489
00490
00491 if(!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) &
00492 PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
00493 {
00494 return FALSE;
00495 }
00496
00497
00498 if(sample_length)
00499 {
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 pdca_reload_channel(TPA6130_ABDAC_PDCA_CHANNEL,
00510 sample_buffer, sample_length);
00511
00512
00513
00514
00515
00516
00517 if(tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00518 pdca_enable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
00519 if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB)
00520 pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00521 }
00522 return TRUE;
00523 }
00524
00525 Bool tpa6130_dac_is_volume_muted(void)
00526 {
00527 return FALSE;
00528 }
00529
00530 void tpa6130_dac_mute(Bool mute)
00531 {
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 S8 volume = tpa6130_get_volume();
00556 if (mute)
00557 {
00558 U32 save_dac_reload_callback_opt;
00559
00560
00561 volume = volume | MUTE_L | MUTE_R;
00562 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume);
00563
00564 save_dac_reload_callback_opt = tpa6130_output_param.callback_opt;
00565 tpa6130_output_param.callback_opt = 0;
00566
00567 pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00568 while (!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE));
00569
00570 tpa6130_output_param.callback_opt = save_dac_reload_callback_opt;
00571 }
00572 else
00573 {
00574
00575 pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00576
00577 volume = volume & (~(MUTE_L | MUTE_R));
00578 tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume);
00579 }
00580 }
00581
00582 Bool tpa6130_dac_is_volume_boosted(void)
00583 {
00584 return FALSE;
00585 }
00586
00590 U8 tpa6130_dac_get_volume(void)
00591 {
00592
00593
00594
00595
00596 U16 raw_volume;
00597 raw_volume = (tpa6130_get_volume() & (~(MUTE_L | MUTE_R)));
00598 return (U8) ((raw_volume * 255) / TPA6130_VOL_MAX);
00599 }
00600
00603 void tpa6130_dac_set_volume(U8 volume)
00604 {
00605 tpa6130_set_volume(volume);
00606 }
00607
00612 void tpa6130_dac_increase_volume(void)
00613 {
00614 S8 volume = tpa6130_get_volume()& (~(MUTE_L | MUTE_R));
00615 if( volume < TPA6130_VOL_MIN )
00616 volume = TPA6130_VOL_MIN;
00617 tpa6130_set_volume(volume+1);
00618 }
00619
00624 void tpa6130_dac_decrease_volume(void)
00625 {
00626 S8 volume = tpa6130_get_volume()& (~(MUTE_L | MUTE_R));;
00627 if( volume > TPA6130_VOL_MIN )
00628 --volume;
00629 tpa6130_set_volume( volume );
00630 }
00631
00634 void tpa6130_dac_flush(void)
00635 {
00636 pdca_disable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL);
00637 pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL);
00638
00639
00640
00641
00642
00643 pdca_disable (TPA6130_ABDAC_PDCA_CHANNEL );
00644 pdca_load_channel (TPA6130_ABDAC_PDCA_CHANNEL,0x0, 0);
00645 pdca_reload_channel(TPA6130_ABDAC_PDCA_CHANNEL,0x0, 0);
00646 pdca_enable (TPA6130_ABDAC_PDCA_CHANNEL );
00647 }
00648
00653 void tpa6130_dac_stop(void)
00654 {
00655
00656 tpa6130_shutdown();
00657
00658
00659
00660
00661
00662
00663 abdac_disable(TPA6130_ABDAC);
00664
00665
00666 pdca_disable(TPA6130_ABDAC_PDCA_CHANNEL);
00667
00668
00669 gpio_enable_gpio(TPA6130_ABDAC_GPIO_MAP,
00670 sizeof(TPA6130_ABDAC_GPIO_MAP)
00671 / sizeof(TPA6130_ABDAC_GPIO_MAP[0]));
00672
00673 tpa6130_output_param.num_channels = 0;
00674 tpa6130_output_param.callback = NULL;
00675 tpa6130_output_param.callback_opt = 0;
00676 }