16bit resolution PWM wave player with SD card, super lite version.
Dependencies: mbed DirectSPI FastPWM
Supported boards (confirmed):
Nucleo-F030R8
Nucleo-L152RE
Nucleo-F401RE
Nucleo-F411RE
Only compilation is OK (unchecked, but may work):
Nucleo-L073RZ
Nucleo-F334R8
Nucleo-F303RE
Nucleo-F429ZI
Nucleo-F446RE
Nucleo-F446ZE
Nucleo-L476RG
Supported SD card:
SDSC/SDHC card,
FAT16 and FAT32.
(1) At first, format SD card using SD Card Formatter
https://www.sdcard.org/downloads/formatter_4/index.html
(2) Copy PCM wav files to the SD card.
Supported file:
PCM wave file that have file extension ".wav" on root directory.
16bit/8bit, fs(sampling rate)=32kHz,44.1kHz,48kHz.
Stereo/Mono.
Hardware setting:
Refer to the file port_setting.txt
PWM output port:
Left upper(Hi) PWM 8bit out: PB_5 (TM3_CH2)
Right upper(Hi) PWM 8bit out: PB4 (TM3_CH1)
Left lower(Low) PWM 8bit out: PC_9 (TM3_CH4)
Right lower(Low) PWM 8bit out: PC_8 (TM3_CH3)
USER_BUTTON: PC_13(default button)
Next song: One click in Play mode.
Pause : Push long time .
Play : One click from Pause.
wave_player_main.cpp@5:4aa4cc29d5ef, 2019-01-19 (annotated)
- Committer:
- mimi3
- Date:
- Sat Jan 19 17:31:23 2019 +0900
- Revision:
- 5:4aa4cc29d5ef
- Parent:
- 0:9a5c2fb0d96f
- Child:
- 6:d9ea630e1ba5
Speed up the entry of period interrupt routin (PWM).
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mimi3 | 0:9a5c2fb0d96f | 1 | #include "sys.h" |
mimi3 | 0:9a5c2fb0d96f | 2 | #include "sd_card.h" |
mimi3 | 0:9a5c2fb0d96f | 3 | #include "fat_lib.h" |
mimi3 | 0:9a5c2fb0d96f | 4 | #include "pwm_lib.h" |
mimi3 | 0:9a5c2fb0d96f | 5 | #include "timers.h" |
mimi3 | 0:9a5c2fb0d96f | 6 | |
mimi3 | 0:9a5c2fb0d96f | 7 | #define CH_STEREO 2 // 2:STEREO, 1:MONO |
mimi3 | 0:9a5c2fb0d96f | 8 | #define wREAD_COUNT 512 |
mimi3 | 0:9a5c2fb0d96f | 9 | #define bHEADER_COUNT 44 |
mimi3 | 0:9a5c2fb0d96f | 10 | #define send_ff() spi_read() |
mimi3 | 0:9a5c2fb0d96f | 11 | #define send_ff16() spi_read16() |
mimi3 | 0:9a5c2fb0d96f | 12 | #define CUT_LAST_TAG_NOISE (30*1000) |
mimi3 | 0:9a5c2fb0d96f | 13 | #if (HAVE_LED_INDICATOR==1) || (HAVE_LED_INDICATOR_2==1) |
mimi3 | 0:9a5c2fb0d96f | 14 | DigitalOut led(IND_LED); |
mimi3 | 0:9a5c2fb0d96f | 15 | #endif |
mimi3 | 0:9a5c2fb0d96f | 16 | |
mimi3 | 0:9a5c2fb0d96f | 17 | /****************** |
mimi3 | 0:9a5c2fb0d96f | 18 | varialble definitions |
mimi3 | 0:9a5c2fb0d96f | 19 | *******************/ |
mimi3 | 0:9a5c2fb0d96f | 20 | #define LED_PERIOD_PLAYNG 75 //[ * 10 msec] |
mimi3 | 0:9a5c2fb0d96f | 21 | #define LED_PERIOD_PAUSING 10 //[ * 10 msec] |
mimi3 | 0:9a5c2fb0d96f | 22 | dword ldwSongFileSectors; |
mimi3 | 0:9a5c2fb0d96f | 23 | dword ldwSample_freq; |
mimi3 | 0:9a5c2fb0d96f | 24 | word lwReadCount; |
mimi3 | 0:9a5c2fb0d96f | 25 | byte lbSample_bits = 16; |
mimi3 | 0:9a5c2fb0d96f | 26 | byte lbCh_mode = CH_STEREO; |
mimi3 | 0:9a5c2fb0d96f | 27 | byte bVolumeUpFactor; |
mimi3 | 0:9a5c2fb0d96f | 28 | sbit fPlaying; |
mimi3 | 0:9a5c2fb0d96f | 29 | sbit lfEndOneSong = true ; //to start music automatically |
mimi3 | 0:9a5c2fb0d96f | 30 | |
mimi3 | 0:9a5c2fb0d96f | 31 | DigitalIn btn_bit_now(USER_BUTTON,PullUp); |
mimi3 | 0:9a5c2fb0d96f | 32 | |
mimi3 | 0:9a5c2fb0d96f | 33 | #if TEST_PORT_ENABLE |
mimi3 | 0:9a5c2fb0d96f | 34 | DigitalOut test_port(TEST_PORT); |
mimi3 | 0:9a5c2fb0d96f | 35 | #endif |
mimi3 | 0:9a5c2fb0d96f | 36 | |
mimi3 | 0:9a5c2fb0d96f | 37 | /********************** |
mimi3 | 0:9a5c2fb0d96f | 38 | Period Timer Interrupt |
mimi3 | 0:9a5c2fb0d96f | 39 | **********************/ |
mimi3 | 0:9a5c2fb0d96f | 40 | /* HAL callback for PWM Timer Intrrupt * */ |
mimi3 | 5:4aa4cc29d5ef | 41 | void pwmPeriodIntr( void ){ |
mimi3 | 5:4aa4cc29d5ef | 42 | if(TIM3->SR & TIM_SR_UIF){ |
mimi3 | 0:9a5c2fb0d96f | 43 | #if TEST_PORT_ENABLE |
mimi3 | 0:9a5c2fb0d96f | 44 | test_port =1; |
mimi3 | 0:9a5c2fb0d96f | 45 | #endif |
mimi3 | 0:9a5c2fb0d96f | 46 | fPlaying = true; |
mimi3 | 0:9a5c2fb0d96f | 47 | #if PWM16BIT |
mimi3 | 0:9a5c2fb0d96f | 48 | word wL_low,wL_hi,wR_low,wR_hi; |
mimi3 | 0:9a5c2fb0d96f | 49 | dword dw; |
mimi3 | 0:9a5c2fb0d96f | 50 | if( lbSample_bits == 16 ) { |
mimi3 | 0:9a5c2fb0d96f | 51 | dw = ((word)(send_ff() + (send_ff()<<8) + 0x8000)) << bVolumeUpFactor; |
mimi3 | 0:9a5c2fb0d96f | 52 | wL_low = wR_low = (dw & 0xff); // get lower 8bit |
mimi3 | 0:9a5c2fb0d96f | 53 | wL_hi = wR_hi = (dw >>8); // get upper 10bit |
mimi3 | 0:9a5c2fb0d96f | 54 | lwReadCount -= 2; |
mimi3 | 0:9a5c2fb0d96f | 55 | if( lbCh_mode == CH_STEREO ) { |
mimi3 | 0:9a5c2fb0d96f | 56 | dw = ((word)(send_ff() + (send_ff()<<8) + 0x8000)) << bVolumeUpFactor; |
mimi3 | 0:9a5c2fb0d96f | 57 | wR_low = (dw & 0xff); |
mimi3 | 0:9a5c2fb0d96f | 58 | wR_hi = (dw >> 8); |
mimi3 | 0:9a5c2fb0d96f | 59 | lwReadCount -= 2; |
mimi3 | 0:9a5c2fb0d96f | 60 | } |
mimi3 | 0:9a5c2fb0d96f | 61 | } |
mimi3 | 0:9a5c2fb0d96f | 62 | #if DATA_8BIT_SUPPORT |
mimi3 | 0:9a5c2fb0d96f | 63 | else { /* 8bit data */ |
mimi3 | 0:9a5c2fb0d96f | 64 | wL_hi = wR_hi = send_ff() << bVolumeUpFactor; // volume up to 10bit (x4) from 8bit |
mimi3 | 0:9a5c2fb0d96f | 65 | wL_low = 0; |
mimi3 | 0:9a5c2fb0d96f | 66 | wR_low = 0; |
mimi3 | 0:9a5c2fb0d96f | 67 | lwReadCount -= 1; |
mimi3 | 0:9a5c2fb0d96f | 68 | if( lbCh_mode == CH_STEREO ) { /* for stereo */ |
mimi3 | 0:9a5c2fb0d96f | 69 | wR_hi = send_ff() << 2; |
mimi3 | 0:9a5c2fb0d96f | 70 | wR_low = 0; |
mimi3 | 0:9a5c2fb0d96f | 71 | lwReadCount -= 1; |
mimi3 | 0:9a5c2fb0d96f | 72 | } |
mimi3 | 0:9a5c2fb0d96f | 73 | } |
mimi3 | 0:9a5c2fb0d96f | 74 | #endif |
mimi3 | 0:9a5c2fb0d96f | 75 | //# change pwm duties |
mimi3 | 0:9a5c2fb0d96f | 76 | pwm_dutyL_hi( wL_hi ) ; |
mimi3 | 0:9a5c2fb0d96f | 77 | pwm_dutyL_low( wL_low ) ; |
mimi3 | 0:9a5c2fb0d96f | 78 | pwm_dutyR_hi( wR_hi ) ; |
mimi3 | 0:9a5c2fb0d96f | 79 | pwm_dutyR_low( wR_low ) ; |
mimi3 | 0:9a5c2fb0d96f | 80 | |
mimi3 | 0:9a5c2fb0d96f | 81 | #else // not PWM16BIT |
mimi3 | 0:9a5c2fb0d96f | 82 | word wL =0,wR = 0; |
mimi3 | 0:9a5c2fb0d96f | 83 | if( lbSample_bits == 16 ) { |
mimi3 | 0:9a5c2fb0d96f | 84 | wL = wR = ((word)(send_ff() + (send_ff()<<8) + 0x8000))>>gPcmShifNum; |
mimi3 | 0:9a5c2fb0d96f | 85 | lwReadCount -= 2; |
mimi3 | 0:9a5c2fb0d96f | 86 | if( lbCh_mode == CH_STEREO ) { |
mimi3 | 0:9a5c2fb0d96f | 87 | wR = (word)(send_ff() + (send_ff()<<8) + 0x8000)>>gPcmShifNum; |
mimi3 | 0:9a5c2fb0d96f | 88 | lwReadCount -= 2; |
mimi3 | 0:9a5c2fb0d96f | 89 | } |
mimi3 | 0:9a5c2fb0d96f | 90 | } |
mimi3 | 0:9a5c2fb0d96f | 91 | #if DATA_8BIT_SUPPORT |
mimi3 | 0:9a5c2fb0d96f | 92 | else { /* 8bit data */ |
mimi3 | 0:9a5c2fb0d96f | 93 | wL = wR = send_ff() << bVolumeUpFactor; // volume up to 10bit (x4) from 8bit |
mimi3 | 0:9a5c2fb0d96f | 94 | lwReadCount -= 1; |
mimi3 | 0:9a5c2fb0d96f | 95 | if( lbCh_mode == CH_STEREO ) { /* for stereo */ |
mimi3 | 0:9a5c2fb0d96f | 96 | wR = send_ff() << bVolumeUpFactor; |
mimi3 | 0:9a5c2fb0d96f | 97 | lwReadCount -= 1; |
mimi3 | 0:9a5c2fb0d96f | 98 | } |
mimi3 | 0:9a5c2fb0d96f | 99 | } |
mimi3 | 0:9a5c2fb0d96f | 100 | #endif |
mimi3 | 0:9a5c2fb0d96f | 101 | //# change pwm duties |
mimi3 | 0:9a5c2fb0d96f | 102 | pwm_dutyL_hi( wL ) ; |
mimi3 | 0:9a5c2fb0d96f | 103 | pwm_dutyR_hi( wR ) ; |
mimi3 | 0:9a5c2fb0d96f | 104 | #endif |
mimi3 | 0:9a5c2fb0d96f | 105 | |
mimi3 | 0:9a5c2fb0d96f | 106 | //; check 512byte sector boundery |
mimi3 | 0:9a5c2fb0d96f | 107 | if( lwReadCount == 0){ |
mimi3 | 0:9a5c2fb0d96f | 108 | //; end 1 sector |
mimi3 | 0:9a5c2fb0d96f | 109 | send_ff() ;// dummy read 1st. discard CRC |
mimi3 | 0:9a5c2fb0d96f | 110 | send_ff() ;// 2nd. |
mimi3 | 0:9a5c2fb0d96f | 111 | while( send_ff() != 0xFE) {} |
mimi3 | 0:9a5c2fb0d96f | 112 | lwReadCount = wREAD_COUNT; |
mimi3 | 0:9a5c2fb0d96f | 113 | ldwSongFileSectors -= 1; |
mimi3 | 0:9a5c2fb0d96f | 114 | } |
mimi3 | 0:9a5c2fb0d96f | 115 | #if TEST_PORT_ENABLE |
mimi3 | 0:9a5c2fb0d96f | 116 | test_port =0; |
mimi3 | 0:9a5c2fb0d96f | 117 | #endif |
mimi3 | 5:4aa4cc29d5ef | 118 | |
mimi3 | 5:4aa4cc29d5ef | 119 | TIM3->SR &= (~TIM_SR_UIF); |
mimi3 | 0:9a5c2fb0d96f | 120 | } |
mimi3 | 0:9a5c2fb0d96f | 121 | } |
mimi3 | 0:9a5c2fb0d96f | 122 | |
mimi3 | 0:9a5c2fb0d96f | 123 | /****************** |
mimi3 | 0:9a5c2fb0d96f | 124 | wave_player_main |
mimi3 | 0:9a5c2fb0d96f | 125 | *******************/ |
mimi3 | 0:9a5c2fb0d96f | 126 | void wave_player_main(){ |
mimi3 | 0:9a5c2fb0d96f | 127 | bVolumeUpFactor = calcPcmValidBits() - 8; |
mimi3 | 0:9a5c2fb0d96f | 128 | word wBtnLowCount = 0; |
mimi3 | 0:9a5c2fb0d96f | 129 | #if HAVE_LED_INDICATOR_2 |
mimi3 | 0:9a5c2fb0d96f | 130 | byte bTimeout_led = 0; |
mimi3 | 0:9a5c2fb0d96f | 131 | #endif |
mimi3 | 0:9a5c2fb0d96f | 132 | sbit btn_bit_prev = true, btn_short_on = false; |
mimi3 | 0:9a5c2fb0d96f | 133 | sbit btn_long_on = false; |
mimi3 | 0:9a5c2fb0d96f | 134 | #if HAVE_POWER_OFF_MODE |
mimi3 | 0:9a5c2fb0d96f | 135 | btn_long_on2 = false; |
mimi3 | 0:9a5c2fb0d96f | 136 | #endif |
mimi3 | 0:9a5c2fb0d96f | 137 | sbit btn_pause_prev = false; |
mimi3 | 0:9a5c2fb0d96f | 138 | #define btn_next_song_on btn_short_on |
mimi3 | 0:9a5c2fb0d96f | 139 | #define btn_pause_on btn_long_on |
mimi3 | 0:9a5c2fb0d96f | 140 | #define btn_power_off_on btn_long_on2 |
mimi3 | 0:9a5c2fb0d96f | 141 | |
mimi3 | 0:9a5c2fb0d96f | 142 | #if HAVE_LED_INDICATOR // pseudo PWM setting |
mimi3 | 0:9a5c2fb0d96f | 143 | const byte LED_OFF_DELAY_PAUSE = 5; |
mimi3 | 0:9a5c2fb0d96f | 144 | const byte LED_OFF_DELAY_PLAY = 50; |
mimi3 | 0:9a5c2fb0d96f | 145 | const sbyte PRD_COUNT = 0x6f ; //max 0x7f |
mimi3 | 0:9a5c2fb0d96f | 146 | const sbyte PAUSE_DUTY_MAX = PRD_COUNT/4; |
mimi3 | 0:9a5c2fb0d96f | 147 | sbyte sbDuty=0, sbCurrent_pos=0, sbDir=1; |
mimi3 | 0:9a5c2fb0d96f | 148 | sbyte sbMode_duty = PRD_COUNT ; //set duty playing |
mimi3 | 0:9a5c2fb0d96f | 149 | sbyte sbPseudo_period = PRD_COUNT ; //period for pseudo PWM |
mimi3 | 0:9a5c2fb0d96f | 150 | byte bOff_delay = LED_OFF_DELAY_PAUSE; |
mimi3 | 0:9a5c2fb0d96f | 151 | #endif |
mimi3 | 0:9a5c2fb0d96f | 152 | |
mimi3 | 0:9a5c2fb0d96f | 153 | init_tickTimer(); |
mimi3 | 0:9a5c2fb0d96f | 154 | |
mimi3 | 0:9a5c2fb0d96f | 155 | while(1){ |
mimi3 | 0:9a5c2fb0d96f | 156 | //; wait 10msec Ticker flag |
mimi3 | 0:9a5c2fb0d96f | 157 | while ( !isTickTimer_IF() ) { |
mimi3 | 0:9a5c2fb0d96f | 158 | if( ldwSongFileSectors == 0 ){ //; found end of file |
mimi3 | 0:9a5c2fb0d96f | 159 | break; //promptly exit and prepare next song |
mimi3 | 0:9a5c2fb0d96f | 160 | } |
mimi3 | 0:9a5c2fb0d96f | 161 | |
mimi3 | 0:9a5c2fb0d96f | 162 | #if HAVE_LED_INDICATOR |
mimi3 | 0:9a5c2fb0d96f | 163 | /*--------------------- |
mimi3 | 0:9a5c2fb0d96f | 164 | pseudo PWM for LED |
mimi3 | 0:9a5c2fb0d96f | 165 | ---------------------*/ |
mimi3 | 0:9a5c2fb0d96f | 166 | if( sbCurrent_pos < sbDuty ){ |
mimi3 | 0:9a5c2fb0d96f | 167 | if( sbDir == 0 ){ |
mimi3 | 0:9a5c2fb0d96f | 168 | led = 0; |
mimi3 | 0:9a5c2fb0d96f | 169 | }else{ |
mimi3 | 0:9a5c2fb0d96f | 170 | led = 1; |
mimi3 | 0:9a5c2fb0d96f | 171 | } |
mimi3 | 0:9a5c2fb0d96f | 172 | } else { |
mimi3 | 0:9a5c2fb0d96f | 173 | led = 0; |
mimi3 | 0:9a5c2fb0d96f | 174 | } |
mimi3 | 0:9a5c2fb0d96f | 175 | sbCurrent_pos = sbCurrent_pos + 1; |
mimi3 | 0:9a5c2fb0d96f | 176 | sbPseudo_period = sbPseudo_period - 1; |
mimi3 | 0:9a5c2fb0d96f | 177 | if( sbPseudo_period == 0 ){ |
mimi3 | 0:9a5c2fb0d96f | 178 | sbPseudo_period = PRD_COUNT; |
mimi3 | 0:9a5c2fb0d96f | 179 | sbCurrent_pos = 0; |
mimi3 | 0:9a5c2fb0d96f | 180 | } |
mimi3 | 0:9a5c2fb0d96f | 181 | #endif |
mimi3 | 0:9a5c2fb0d96f | 182 | } //; end. wait 10msec Ticker flag |
mimi3 | 0:9a5c2fb0d96f | 183 | |
mimi3 | 0:9a5c2fb0d96f | 184 | //------------------- |
mimi3 | 0:9a5c2fb0d96f | 185 | tickTimer_IF_clear(); |
mimi3 | 0:9a5c2fb0d96f | 186 | //------------------- |
mimi3 | 0:9a5c2fb0d96f | 187 | |
mimi3 | 0:9a5c2fb0d96f | 188 | #if HAVE_BUTTON_SW |
mimi3 | 0:9a5c2fb0d96f | 189 | /*------------------- |
mimi3 | 0:9a5c2fb0d96f | 190 | Pause release |
mimi3 | 0:9a5c2fb0d96f | 191 | -------------------*/ |
mimi3 | 0:9a5c2fb0d96f | 192 | if( btn_next_song_on){ |
mimi3 | 0:9a5c2fb0d96f | 193 | if( !fPlaying){ // ; if during pause |
mimi3 | 0:9a5c2fb0d96f | 194 | fPlaying = true ; //release pause |
mimi3 | 0:9a5c2fb0d96f | 195 | btn_next_song_on = false; |
mimi3 | 0:9a5c2fb0d96f | 196 | btn_pause_on = false; |
mimi3 | 0:9a5c2fb0d96f | 197 | #if HAVE_LED_INDICATOR |
mimi3 | 0:9a5c2fb0d96f | 198 | sbDuty = 0; |
mimi3 | 0:9a5c2fb0d96f | 199 | sbDir = 1; |
mimi3 | 0:9a5c2fb0d96f | 200 | #endif |
mimi3 | 0:9a5c2fb0d96f | 201 | pwm_period_timer_start(); |
mimi3 | 0:9a5c2fb0d96f | 202 | } |
mimi3 | 0:9a5c2fb0d96f | 203 | } |
mimi3 | 0:9a5c2fb0d96f | 204 | |
mimi3 | 0:9a5c2fb0d96f | 205 | /*------------------- |
mimi3 | 0:9a5c2fb0d96f | 206 | Pause enter |
mimi3 | 0:9a5c2fb0d96f | 207 | -------------------*/ |
mimi3 | 0:9a5c2fb0d96f | 208 | if( btn_pause_prev ^ btn_pause_on ){ |
mimi3 | 0:9a5c2fb0d96f | 209 | if( btn_pause_on ){ |
mimi3 | 0:9a5c2fb0d96f | 210 | fPlaying = false; |
mimi3 | 0:9a5c2fb0d96f | 211 | pwm_period_timer_stop(); |
mimi3 | 0:9a5c2fb0d96f | 212 | #if HAVE_LED_INDICATOR |
mimi3 | 0:9a5c2fb0d96f | 213 | sbDuty = PAUSE_DUTY_MAX/2; |
mimi3 | 0:9a5c2fb0d96f | 214 | sbDir = -1; |
mimi3 | 0:9a5c2fb0d96f | 215 | #endif |
mimi3 | 0:9a5c2fb0d96f | 216 | } |
mimi3 | 0:9a5c2fb0d96f | 217 | } |
mimi3 | 0:9a5c2fb0d96f | 218 | btn_pause_prev = btn_pause_on; |
mimi3 | 0:9a5c2fb0d96f | 219 | #endif |
mimi3 | 0:9a5c2fb0d96f | 220 | |
mimi3 | 0:9a5c2fb0d96f | 221 | /*------------------- |
mimi3 | 0:9a5c2fb0d96f | 222 | Next song and start |
mimi3 | 0:9a5c2fb0d96f | 223 | -------------------*/ |
mimi3 | 0:9a5c2fb0d96f | 224 | if( lfEndOneSong){ |
mimi3 | 0:9a5c2fb0d96f | 225 | lfEndOneSong = false; |
mimi3 | 0:9a5c2fb0d96f | 226 | searchNextFile(); |
mimi3 | 0:9a5c2fb0d96f | 227 | //; delete about last 30Kbyte to cut tag data in *.wav file |
mimi3 | 0:9a5c2fb0d96f | 228 | ldwSongFileSectors = ( (gdwBPB_FileSize - CUT_LAST_TAG_NOISE) )>>9 ; //512 , change to sector |
mimi3 | 0:9a5c2fb0d96f | 229 | //## Seek to Target file sector |
mimi3 | 0:9a5c2fb0d96f | 230 | sd_start_read( gdwTargetFileSector ); |
mimi3 | 0:9a5c2fb0d96f | 231 | |
mimi3 | 0:9a5c2fb0d96f | 232 | //### get wav header info ### |
mimi3 | 0:9a5c2fb0d96f | 233 | sd_read_pulse_byte(22);// ## Skip part of WAV header |
mimi3 | 0:9a5c2fb0d96f | 234 | lbCh_mode = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 235 | sd_data_byte(); //# dummy read |
mimi3 | 0:9a5c2fb0d96f | 236 | ldwSample_freq = sd_data_byte() + (sd_data_byte() << 8) + |
mimi3 | 0:9a5c2fb0d96f | 237 | (sd_data_byte() << 16) + |
mimi3 | 0:9a5c2fb0d96f | 238 | (sd_data_byte() << 24); |
mimi3 | 0:9a5c2fb0d96f | 239 | setPwmPeriod(ldwSample_freq); |
mimi3 | 0:9a5c2fb0d96f | 240 | sd_read_pulse_byte(6);// ## Skip some headers |
mimi3 | 0:9a5c2fb0d96f | 241 | lbSample_bits = sd_data_byte(); |
mimi3 | 0:9a5c2fb0d96f | 242 | sd_read_pulse_byte(9) ;//## Skip to last position of header |
mimi3 | 0:9a5c2fb0d96f | 243 | //########################### |
mimi3 | 0:9a5c2fb0d96f | 244 | |
mimi3 | 0:9a5c2fb0d96f | 245 | lwReadCount = wREAD_COUNT - bHEADER_COUNT; |
mimi3 | 0:9a5c2fb0d96f | 246 | //; music start |
mimi3 | 0:9a5c2fb0d96f | 247 | pwm_period_timer_start(); |
mimi3 | 0:9a5c2fb0d96f | 248 | |
mimi3 | 0:9a5c2fb0d96f | 249 | #if HAVE_LED_INDICATOR |
mimi3 | 0:9a5c2fb0d96f | 250 | sbDuty = 0; |
mimi3 | 0:9a5c2fb0d96f | 251 | sbDir = 1; |
mimi3 | 0:9a5c2fb0d96f | 252 | #endif |
mimi3 | 0:9a5c2fb0d96f | 253 | } |
mimi3 | 0:9a5c2fb0d96f | 254 | |
mimi3 | 0:9a5c2fb0d96f | 255 | /*------------------- |
mimi3 | 0:9a5c2fb0d96f | 256 | wait end of one song |
mimi3 | 0:9a5c2fb0d96f | 257 | -------------------*/ |
mimi3 | 0:9a5c2fb0d96f | 258 | if ( ( ldwSongFileSectors == 0 ) | btn_next_song_on ){ |
mimi3 | 0:9a5c2fb0d96f | 259 | pwm_period_timer_stop(); |
mimi3 | 0:9a5c2fb0d96f | 260 | fPlaying = false; |
mimi3 | 0:9a5c2fb0d96f | 261 | btn_next_song_on = false; |
mimi3 | 0:9a5c2fb0d96f | 262 | lfEndOneSong = true; |
mimi3 | 0:9a5c2fb0d96f | 263 | sd_stop_read(); |
mimi3 | 0:9a5c2fb0d96f | 264 | } |
mimi3 | 0:9a5c2fb0d96f | 265 | |
mimi3 | 0:9a5c2fb0d96f | 266 | /*------------------- |
mimi3 | 0:9a5c2fb0d96f | 267 | LED indicator 1 --- pseudo PWM |
mimi3 | 0:9a5c2fb0d96f | 268 | -------------------*/ |
mimi3 | 0:9a5c2fb0d96f | 269 | #if HAVE_LED_INDICATOR |
mimi3 | 0:9a5c2fb0d96f | 270 | if( fPlaying ){ |
mimi3 | 0:9a5c2fb0d96f | 271 | sbMode_duty = PRD_COUNT ; //during Playing |
mimi3 | 0:9a5c2fb0d96f | 272 | }else{ |
mimi3 | 0:9a5c2fb0d96f | 273 | #if HAVE_LED_PAUSE_INDICATOR |
mimi3 | 0:9a5c2fb0d96f | 274 | sbMode_duty = PAUSE_DUTY_MAX ;// during Pause |
mimi3 | 0:9a5c2fb0d96f | 275 | #else |
mimi3 | 0:9a5c2fb0d96f | 276 | sbMode_duty = 1; |
mimi3 | 0:9a5c2fb0d96f | 277 | #endif |
mimi3 | 0:9a5c2fb0d96f | 278 | } |
mimi3 | 0:9a5c2fb0d96f | 279 | //--- duty control |
mimi3 | 0:9a5c2fb0d96f | 280 | sbDuty = sbDuty + sbDir; |
mimi3 | 0:9a5c2fb0d96f | 281 | if(sbDuty == sbMode_duty ){ |
mimi3 | 0:9a5c2fb0d96f | 282 | sbDir = -1; |
mimi3 | 0:9a5c2fb0d96f | 283 | } |
mimi3 | 0:9a5c2fb0d96f | 284 | if( sbDuty == 0){ |
mimi3 | 0:9a5c2fb0d96f | 285 | sbDir = 0; |
mimi3 | 0:9a5c2fb0d96f | 286 | sbDuty = 1; |
mimi3 | 0:9a5c2fb0d96f | 287 | bOff_delay = LED_OFF_DELAY_PAUSE ;// during pause |
mimi3 | 0:9a5c2fb0d96f | 288 | if( fPlaying ){ |
mimi3 | 0:9a5c2fb0d96f | 289 | bOff_delay = LED_OFF_DELAY_PLAY ;// during play |
mimi3 | 0:9a5c2fb0d96f | 290 | } |
mimi3 | 0:9a5c2fb0d96f | 291 | } |
mimi3 | 0:9a5c2fb0d96f | 292 | if( sbDir == 0 ){ //; wait for a while at LED OFF |
mimi3 | 0:9a5c2fb0d96f | 293 | if( bOff_delay > 0 ){ |
mimi3 | 0:9a5c2fb0d96f | 294 | bOff_delay = bOff_delay - 1; |
mimi3 | 0:9a5c2fb0d96f | 295 | }else{ |
mimi3 | 0:9a5c2fb0d96f | 296 | sbDir = 1; |
mimi3 | 0:9a5c2fb0d96f | 297 | } |
mimi3 | 0:9a5c2fb0d96f | 298 | } |
mimi3 | 0:9a5c2fb0d96f | 299 | #endif |
mimi3 | 0:9a5c2fb0d96f | 300 | |
mimi3 | 0:9a5c2fb0d96f | 301 | /*------------------- |
mimi3 | 0:9a5c2fb0d96f | 302 | LED indicator 2 --- simple ON/OFF |
mimi3 | 0:9a5c2fb0d96f | 303 | -------------------*/ |
mimi3 | 0:9a5c2fb0d96f | 304 | #if HAVE_LED_INDICATOR_2 |
mimi3 | 0:9a5c2fb0d96f | 305 | if (bTimeout_led == 0){ |
mimi3 | 0:9a5c2fb0d96f | 306 | if( fPlaying ){ |
mimi3 | 0:9a5c2fb0d96f | 307 | bTimeout_led = LED_PERIOD_PLAYNG ;// during Playing, on/off |
mimi3 | 0:9a5c2fb0d96f | 308 | led = !led; |
mimi3 | 0:9a5c2fb0d96f | 309 | }else{ |
mimi3 | 0:9a5c2fb0d96f | 310 | #if HAVE_LED_PAUSE_INDICATOR |
mimi3 | 0:9a5c2fb0d96f | 311 | bTimeout_led = LED_PERIOD_PAUSING ;// during Pause, on/off |
mimi3 | 0:9a5c2fb0d96f | 312 | led = !led; |
mimi3 | 0:9a5c2fb0d96f | 313 | #else |
mimi3 | 0:9a5c2fb0d96f | 314 | bTimeout_led = 1; |
mimi3 | 0:9a5c2fb0d96f | 315 | led = 0; |
mimi3 | 0:9a5c2fb0d96f | 316 | #endif |
mimi3 | 0:9a5c2fb0d96f | 317 | } |
mimi3 | 0:9a5c2fb0d96f | 318 | } |
mimi3 | 0:9a5c2fb0d96f | 319 | bTimeout_led = bTimeout_led - 1; |
mimi3 | 0:9a5c2fb0d96f | 320 | #endif |
mimi3 | 0:9a5c2fb0d96f | 321 | |
mimi3 | 0:9a5c2fb0d96f | 322 | /*------------------- |
mimi3 | 0:9a5c2fb0d96f | 323 | button sw input |
mimi3 | 0:9a5c2fb0d96f | 324 | -------------------*/ |
mimi3 | 0:9a5c2fb0d96f | 325 | #if HAVE_BUTTON_SW |
mimi3 | 0:9a5c2fb0d96f | 326 | if( btn_bit_prev ^ btn_bit_now) { |
mimi3 | 0:9a5c2fb0d96f | 327 | if (btn_bit_now){ // ; 0 --> 1: btn released |
mimi3 | 0:9a5c2fb0d96f | 328 | if( (wBtnLowCount > 10) && (wBtnLowCount < 130)){// ; 100msec < x < 1.3sec |
mimi3 | 0:9a5c2fb0d96f | 329 | btn_short_on = true; |
mimi3 | 0:9a5c2fb0d96f | 330 | } |
mimi3 | 0:9a5c2fb0d96f | 331 | wBtnLowCount = 0; |
mimi3 | 0:9a5c2fb0d96f | 332 | } |
mimi3 | 0:9a5c2fb0d96f | 333 | } |
mimi3 | 0:9a5c2fb0d96f | 334 | btn_bit_prev = btn_bit_now; |
mimi3 | 0:9a5c2fb0d96f | 335 | if (btn_bit_now == false){ |
mimi3 | 0:9a5c2fb0d96f | 336 | wBtnLowCount = wBtnLowCount + 1; |
mimi3 | 0:9a5c2fb0d96f | 337 | } |
mimi3 | 0:9a5c2fb0d96f | 338 | //; recognized pause on |
mimi3 | 0:9a5c2fb0d96f | 339 | if (wBtnLowCount > 120) { // ; 1.2sec > |
mimi3 | 0:9a5c2fb0d96f | 340 | btn_long_on = true; |
mimi3 | 0:9a5c2fb0d96f | 341 | } |
mimi3 | 0:9a5c2fb0d96f | 342 | #if HAVE_POWER_OFF_MODE |
mimi3 | 0:9a5c2fb0d96f | 343 | if (wBtnLowCount > 400){ //; 4sec > |
mimi3 | 0:9a5c2fb0d96f | 344 | //; "long on2" is meaning go to sleep mode |
mimi3 | 0:9a5c2fb0d96f | 345 | btn_long_on2 = true; |
mimi3 | 0:9a5c2fb0d96f | 346 | } |
mimi3 | 0:9a5c2fb0d96f | 347 | #endif |
mimi3 | 0:9a5c2fb0d96f | 348 | #endif |
mimi3 | 0:9a5c2fb0d96f | 349 | } //; [forever loop end] |
mimi3 | 0:9a5c2fb0d96f | 350 | } |
mimi3 | 0:9a5c2fb0d96f | 351 | |
mimi3 | 0:9a5c2fb0d96f | 352 |