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)
http://mpu.up.seesaa.net/image/16bit-wave-player-output-schema.png
USER_BUTTON: PC_13(default button)
Next song: One click in Play mode.
Pause : Push long time .
Play : One click from Pause.

Committer:
mimi3
Date:
Fri Oct 09 07:47:36 2020 +0900
Revision:
21:dc161a192ba7
Parent:
5:4aa4cc29d5ef
trivial change

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mimi3 0:9a5c2fb0d96f 1 /* */
mimi3 0:9a5c2fb0d96f 2
mimi3 0:9a5c2fb0d96f 3 #include "mbed.h"
mimi3 0:9a5c2fb0d96f 4 #include "sys.h"
mimi3 0:9a5c2fb0d96f 5 #include "pwm_lib.h"
mimi3 0:9a5c2fb0d96f 6
mimi3 0:9a5c2fb0d96f 7 /* Using FastPWM library from:
mimi3 0:9a5c2fb0d96f 8 * http://developer.mbed.org/users/Sissors/code/FastPWM/
mimi3 0:9a5c2fb0d96f 9 * Thank you this FastPWM library.
mimi3 0:9a5c2fb0d96f 10 */
mimi3 0:9a5c2fb0d96f 11
mimi3 0:9a5c2fb0d96f 12 static TIM_HandleTypeDef TimHandle_pwm;
mimi3 0:9a5c2fb0d96f 13
mimi3 0:9a5c2fb0d96f 14 /*
mimi3 0:9a5c2fb0d96f 15 * PWM definition
mimi3 0:9a5c2fb0d96f 16 * */
mimi3 0:9a5c2fb0d96f 17 // Use PWM3-1(Right),PWM3-2(Left) with TIM3
mimi3 0:9a5c2fb0d96f 18 TPWM pwmLeftHi( PWM_PORT_LEFT_HI ,PWM_TIMER_PRE_SCALE);
mimi3 0:9a5c2fb0d96f 19 TPWM pwmRightHi(PWM_PORT_RIGHT_HI,PWM_TIMER_PRE_SCALE);
mimi3 0:9a5c2fb0d96f 20 // Use PWM3-3,PWM3-4 with TIM3
mimi3 0:9a5c2fb0d96f 21 TPWM pwmLeftLow( PWM_PORT_LEFT_LOW ,PWM_TIMER_PRE_SCALE);
mimi3 0:9a5c2fb0d96f 22 TPWM pwmRightLow(PWM_PORT_RIGHT_LOW,PWM_TIMER_PRE_SCALE);
mimi3 0:9a5c2fb0d96f 23
mimi3 0:9a5c2fb0d96f 24 /*
mimi3 0:9a5c2fb0d96f 25 * PWM Timer constants value
mimi3 0:9a5c2fb0d96f 26 *
mimi3 0:9a5c2fb0d96f 27 * TIMER_BASE_CLK is assumed that bits
mimi3 0:9a5c2fb0d96f 28 TARGET_NUCLEO_F411RE 96 MHz 11
mimi3 0:9a5c2fb0d96f 29 TARGET_NUCLEO_F401RE 84 MHz 10
mimi3 0:9a5c2fb0d96f 30 72 MHz 10
mimi3 0:9a5c2fb0d96f 31 TARGET_NUCLEO_F103RB 64 MHz 10
mimi3 0:9a5c2fb0d96f 32 TARGET_NUCLEO_F030R8 48 MHz 10
mimi3 0:9a5c2fb0d96f 33 32 MHz 9
mimi3 0:9a5c2fb0d96f 34 TARGET_NUCLEO_L152RE 24 MHz 9
mimi3 0:9a5c2fb0d96f 35 16 MHz 8
mimi3 0:9a5c2fb0d96f 36 12 MHz 8
mimi3 0:9a5c2fb0d96f 37 */
mimi3 0:9a5c2fb0d96f 38 #define TIMER_BASE_CLK ( SystemCoreClock )
mimi3 0:9a5c2fb0d96f 39 #define PERIOD_TIMER_INPUT_CLK ( TIMER_BASE_CLK / PWM_TIMER_PRE_SCALE )
mimi3 0:9a5c2fb0d96f 40 #define PERIOD2TICS(period) ( PERIOD_TIMER_INPUT_CLK / ( period ) )
mimi3 0:9a5c2fb0d96f 41 #define INITIAL_PERIOD 44100 // fs=44.1kHz
mimi3 0:9a5c2fb0d96f 42
mimi3 0:9a5c2fb0d96f 43 /* WAVE signal effective bits
mimi3 0:9a5c2fb0d96f 44 * if fs==44.1kHz then:
mimi3 0:9a5c2fb0d96f 45 * PCM_SIGNIFICANT_BITS = int[ log_2[ (PERIOD_TIMER_INPUT_CLK / 44100 ) ] ]
mimi3 0:9a5c2fb0d96f 46 */
mimi3 0:9a5c2fb0d96f 47 uint8_t gPcmShifNum;
mimi3 0:9a5c2fb0d96f 48
mimi3 0:9a5c2fb0d96f 49 uint8_t calcPcmValidBits( void )
mimi3 0:9a5c2fb0d96f 50 {
mimi3 0:9a5c2fb0d96f 51 if( SystemCoreClock >= 96000000 ){
mimi3 0:9a5c2fb0d96f 52 return 11;
mimi3 0:9a5c2fb0d96f 53 } else if( SystemCoreClock >= 48000000 ){
mimi3 0:9a5c2fb0d96f 54 return 10;
mimi3 0:9a5c2fb0d96f 55 } else if( SystemCoreClock >= 24000000 ){
mimi3 0:9a5c2fb0d96f 56 return 9;
mimi3 0:9a5c2fb0d96f 57 }
mimi3 0:9a5c2fb0d96f 58 return 8;
mimi3 0:9a5c2fb0d96f 59 }
mimi3 0:9a5c2fb0d96f 60
mimi3 0:9a5c2fb0d96f 61 /*
mimi3 0:9a5c2fb0d96f 62 * PWM Timer Interrupt routine
mimi3 0:9a5c2fb0d96f 63 * */
mimi3 0:9a5c2fb0d96f 64 /**********************
mimi3 0:9a5c2fb0d96f 65 pwmPeriodIntr
mimi3 0:9a5c2fb0d96f 66 **********************/
mimi3 5:4aa4cc29d5ef 67 void pwmPeriodIntr( void );
mimi3 0:9a5c2fb0d96f 68
mimi3 0:9a5c2fb0d96f 69 /**********************
mimi3 0:9a5c2fb0d96f 70 setPwmPeriod
mimi3 0:9a5c2fb0d96f 71 **********************/
mimi3 0:9a5c2fb0d96f 72 void setPwmPeriod( int period )
mimi3 0:9a5c2fb0d96f 73 {
mimi3 0:9a5c2fb0d96f 74 pwmLeftHi.period_ticks( PERIOD2TICS(period) );
mimi3 0:9a5c2fb0d96f 75 pwmRightHi.period_ticks( PERIOD2TICS(period) );
mimi3 0:9a5c2fb0d96f 76 pwmLeftLow.period_ticks( PERIOD2TICS(period) );
mimi3 0:9a5c2fb0d96f 77 pwmRightLow.period_ticks(PERIOD2TICS(period) );
mimi3 0:9a5c2fb0d96f 78 }
mimi3 0:9a5c2fb0d96f 79
mimi3 0:9a5c2fb0d96f 80 /**********************
mimi3 0:9a5c2fb0d96f 81 pwmTimerInit
mimi3 0:9a5c2fb0d96f 82 **********************/
mimi3 0:9a5c2fb0d96f 83 void pwmTimerInit(void)
mimi3 0:9a5c2fb0d96f 84 {
mimi3 0:9a5c2fb0d96f 85 TimHandle_pwm.Instance = TIM_PWM;
mimi3 0:9a5c2fb0d96f 86 HAL_NVIC_SetPriority(TIM_PWM_IRQ, 0, 0);
mimi3 0:9a5c2fb0d96f 87 NVIC_SetVector( TIM_PWM_IRQ, (uint32_t)&pwmPeriodIntr );
mimi3 0:9a5c2fb0d96f 88 pwmPeriodIntrEnable();
mimi3 0:9a5c2fb0d96f 89 periodTimerIntrStop();
mimi3 0:9a5c2fb0d96f 90 setPwmPeriod( INITIAL_PERIOD );
mimi3 0:9a5c2fb0d96f 91 }
mimi3 0:9a5c2fb0d96f 92
mimi3 0:9a5c2fb0d96f 93 /******************
mimi3 0:9a5c2fb0d96f 94 pwm_start
mimi3 0:9a5c2fb0d96f 95 *******************/
mimi3 0:9a5c2fb0d96f 96 void pwm_period_timer_start() {
mimi3 0:9a5c2fb0d96f 97 periodTimerIntrStart();
mimi3 0:9a5c2fb0d96f 98 }
mimi3 0:9a5c2fb0d96f 99
mimi3 0:9a5c2fb0d96f 100 /******************
mimi3 0:9a5c2fb0d96f 101 pwm_stop
mimi3 0:9a5c2fb0d96f 102 *******************/
mimi3 0:9a5c2fb0d96f 103 void pwm_period_timer_stop() {
mimi3 0:9a5c2fb0d96f 104 periodTimerIntrStop();
mimi3 0:9a5c2fb0d96f 105 }
mimi3 0:9a5c2fb0d96f 106
mimi3 0:9a5c2fb0d96f 107 /******************
mimi3 0:9a5c2fb0d96f 108 pwm_init
mimi3 0:9a5c2fb0d96f 109 *******************/
mimi3 0:9a5c2fb0d96f 110 void pwm_init() {
mimi3 0:9a5c2fb0d96f 111 pwmTimerInit();
mimi3 0:9a5c2fb0d96f 112 gPcmShifNum = 16 - calcPcmValidBits();
mimi3 0:9a5c2fb0d96f 113 }
mimi3 0:9a5c2fb0d96f 114
mimi3 0:9a5c2fb0d96f 115