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