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@21:dc161a192ba7, 2020-10-09 (annotated)
- 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?
User | Revision | Line number | New 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 |