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.
pwm_lib.cpp
- Committer:
- mimi3
- Date:
- 2020-10-09
- Revision:
- 21:dc161a192ba7
- Parent:
- 5:4aa4cc29d5ef
File content as of revision 21:dc161a192ba7:
/* */ #include "mbed.h" #include "sys.h" #include "pwm_lib.h" /* Using FastPWM library from: * http://developer.mbed.org/users/Sissors/code/FastPWM/ * Thank you this FastPWM library. */ static TIM_HandleTypeDef TimHandle_pwm; /* * PWM definition * */ // Use PWM3-1(Right),PWM3-2(Left) with TIM3 TPWM pwmLeftHi( PWM_PORT_LEFT_HI ,PWM_TIMER_PRE_SCALE); TPWM pwmRightHi(PWM_PORT_RIGHT_HI,PWM_TIMER_PRE_SCALE); // Use PWM3-3,PWM3-4 with TIM3 TPWM pwmLeftLow( PWM_PORT_LEFT_LOW ,PWM_TIMER_PRE_SCALE); TPWM pwmRightLow(PWM_PORT_RIGHT_LOW,PWM_TIMER_PRE_SCALE); /* * PWM Timer constants value * * TIMER_BASE_CLK is assumed that bits TARGET_NUCLEO_F411RE 96 MHz 11 TARGET_NUCLEO_F401RE 84 MHz 10 72 MHz 10 TARGET_NUCLEO_F103RB 64 MHz 10 TARGET_NUCLEO_F030R8 48 MHz 10 32 MHz 9 TARGET_NUCLEO_L152RE 24 MHz 9 16 MHz 8 12 MHz 8 */ #define TIMER_BASE_CLK ( SystemCoreClock ) #define PERIOD_TIMER_INPUT_CLK ( TIMER_BASE_CLK / PWM_TIMER_PRE_SCALE ) #define PERIOD2TICS(period) ( PERIOD_TIMER_INPUT_CLK / ( period ) ) #define INITIAL_PERIOD 44100 // fs=44.1kHz /* WAVE signal effective bits * if fs==44.1kHz then: * PCM_SIGNIFICANT_BITS = int[ log_2[ (PERIOD_TIMER_INPUT_CLK / 44100 ) ] ] */ uint8_t gPcmShifNum; uint8_t calcPcmValidBits( void ) { if( SystemCoreClock >= 96000000 ){ return 11; } else if( SystemCoreClock >= 48000000 ){ return 10; } else if( SystemCoreClock >= 24000000 ){ return 9; } return 8; } /* * PWM Timer Interrupt routine * */ /********************** pwmPeriodIntr **********************/ void pwmPeriodIntr( void ); /********************** setPwmPeriod **********************/ void setPwmPeriod( int period ) { pwmLeftHi.period_ticks( PERIOD2TICS(period) ); pwmRightHi.period_ticks( PERIOD2TICS(period) ); pwmLeftLow.period_ticks( PERIOD2TICS(period) ); pwmRightLow.period_ticks(PERIOD2TICS(period) ); } /********************** pwmTimerInit **********************/ void pwmTimerInit(void) { TimHandle_pwm.Instance = TIM_PWM; HAL_NVIC_SetPriority(TIM_PWM_IRQ, 0, 0); NVIC_SetVector( TIM_PWM_IRQ, (uint32_t)&pwmPeriodIntr ); pwmPeriodIntrEnable(); periodTimerIntrStop(); setPwmPeriod( INITIAL_PERIOD ); } /****************** pwm_start *******************/ void pwm_period_timer_start() { periodTimerIntrStart(); } /****************** pwm_stop *******************/ void pwm_period_timer_stop() { periodTimerIntrStop(); } /****************** pwm_init *******************/ void pwm_init() { pwmTimerInit(); gPcmShifNum = 16 - calcPcmValidBits(); }