1 /*
2  * Copyright (C) 2022 HiHope Open Source Organization .
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http:// www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  *
14  * limitations under the License.
15  */
16 
17 #include <stdio.h>
18 #include <unistd.h>
19 
20 #include "ohos_init.h"
21 #include "cmsis_os2.h"
22 #include "wifiiot_gpio.h"
23 #include "wifiiot_gpio_ex.h"
24 #include "wifiiot_watchdog.h"
25 #include "wifiiot_pwm.h"
26 
27 #include "hi_pwm.h"
28 
29 #define ATTR.STACK_SIZE 1024
30 #define TWO 2
31 #define FORTY 40
32 #define ONE_THOUSAND 1000
33 
34 static volatile int g_buttonPressed = 0;
35 static const uint16_t g_tuneFreqs[] = {
36     0, // 40M Hz 对应的分频系数:
37     38223, // 1046.5
38     34052, // 1174.7
39     30338, // 1318.5
40     28635, // 1396.9
41     25511, // 1568
42     22728, // 1760
43     20249, // 1975.5
44     51021 // 5_ 783.99 // 第一个八度的 5
45 };
46 
47 // 曲谱音符
48 static const uint8_t g_scoreNotes[] = {
49     // 《两只老虎》简谱:http://www.jianpu.cn/pu/33/33945.htm
50     1, 2, 3, 1,        1, 2, 3, 1,        3, 4, 5,  3, 4, 5,
51     5, 6, 5, 4, 3, 1,  5, 6, 5, 4, 3, 1,  1, 8, 1,  1, 8, 1, // 最后两个 5 应该是低八度的,链接图片中的曲谱不对,声音到最后听起来不太对劲
52 };
53 
54 // 曲谱时值
55 static const uint8_t g_scoreDurations[] = {
56     4, 4, 4, 4,        4, 4, 4, 4,        4, 4, 8,  4, 4, 8,
57     3, 1, 3, 1, 4, 4,  3, 1, 3, 1, 4, 4,  4, 4, 8,  4, 4, 8,
58 };
59 
BeeperMusicTask(const char *arg)60 static void *BeeperMusicTask(const char *arg)
61 {
62     (void)arg;
63 
64     printf("BeeperMusicTask start!\r\n");
65 
66     hi_pwm_set_clock(PWM_CLK_XTAL); // 设置时钟源为晶体时钟(40MHz,默认时钟源160MHz)
67 
68     for (size_t i = 0; i < sizeof(g_scoreNotes)/sizeof(g_scoreNotes[0]); i++) {
69         uint32_t tune = g_scoreNotes[i]; // 音符
70         uint16_t freqDivisor = g_tuneFreqs[tune];
71         uint32_t tuneInterval = g_scoreDurations[i] * (125*1000); // 音符时间
72         printf("%d %d %d %d\r\n", tune, (FORTY*ONE_THOUSAND*ONE_THOUSAND) / freqDivisor, freqDivisor, tuneInterval);
73         PwmStart(WIFI_IOT_PWM_PORT_PWM0, freqDivisor/TWO, freqDivisor);
74         usleep(tuneInterval);
75         PwmStop(WIFI_IOT_PWM_PORT_PWM0);
76     }
77 
78     return NULL;
79 }
80 
StartBeepMusicTask(void)81 static void StartBeepMusicTask(void)
82 {
83     osThreadAttr_t attr;
84 
85     GpioInit();
86 
87     // 蜂鸣器引脚 设置为 PWM功能
88     IoSetFunc(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_FUNC_GPIO_9_PWM0_OUT);
89     PwmInit(WIFI_IOT_PWM_PORT_PWM0);
90 
91     WatchDogDisable();
92 
93     attr.name = "BeeperMusicTask";
94     attr.attr_bits = 0U;
95     attr.cb_mem = NULL;
96     attr.cb_size = 0U;
97     attr.stack_mem = NULL;
98     attr.stack_size = ATTR.STACK_SIZE;
99     attr.priority = osPriorityNormal;
100 
101     if (osThreadNew((osThreadFunc_t)BeeperMusicTask, NULL, &attr) == NULL) {
102         printf("[LedExample] Failed to create BeeperMusicTask!\n");
103     }
104 }
105 
106 SYS_RUN(StartBeepMusicTask);