GadgetSeed  0.9.6
tim12_buzzer.c
[詳解]
1 /** @file
2  @brief 圧電ブザードライバ
3 
4  @date 2017.02.04
5  @author Takashi SHUDO
6 
7  @info
8 
9  接続
10 
11  圧電ブザー STM32F7(CPU PIN)
12  ----------- ----------------
13  DIN PH6
14 
15  ブザー音のパルスはTIM12で作成
16 
17  使用方法
18 
19  ioctl(0:Off/1:On, 周波数(Hz))
20 */
21 
22 #include "sysconfig.h"
23 #include "device.h"
24 #include "device/buzzer_ioctl.h"
25 #include "timer.h"
26 #include "tkprintf.h"
27 
28 #include "stm32f7xx_hal.h"
29 #include "stm32f7xx_hal_tim.h"
30 
31 //#define DEBUGKBITS 0x03
32 #include "dkprintf.h"
33 
34 
35 #define ARDUINO_PWM_D6_Pin GPIO_PIN_6
36 #define ARDUINO_PWM_D6_GPIO_Port GPIOH
37 
38 TIM_HandleTypeDef htim12;
39 
40 /* TIM12 init function */
41 static void MX_TIM12_Init(void)
42 {
43  TIM_ClockConfigTypeDef sClockSourceConfig;
44  TIM_MasterConfigTypeDef sMasterConfig;
45  TIM_OC_InitTypeDef sConfigOC;
46 
47  htim12.Instance = TIM12;
48  htim12.Init.Prescaler = 0;
49  htim12.Init.CounterMode = TIM_COUNTERMODE_UP;
50  htim12.Init.Period = 0;
51  htim12.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
52  //htim12.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
53  if(HAL_TIM_Base_Init(&htim12) != HAL_OK) {
54  SYSERR_PRINT("TIM12 Initialize error.\n");
55  }
56 
57  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
58  if(HAL_TIM_ConfigClockSource(&htim12, &sClockSourceConfig) != HAL_OK) {
59  SYSERR_PRINT("TIM12 Clock Initialize error.\n");
60  }
61 
62  if(HAL_TIM_OC_Init(&htim12) != HAL_OK) {
63  SYSERR_PRINT("TIM12 IC Initialize error.\n");
64  }
65 
66  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
67  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
68  if(HAL_TIMEx_MasterConfigSynchronization(&htim12, &sMasterConfig) != HAL_OK) {
69  SYSERR_PRINT("TIM12 MC Initialize error.\n");
70  }
71 
72  sConfigOC.OCMode = TIM_OCMODE_TIMING;
73  sConfigOC.Pulse = 0;
74  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
75  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
76  if(HAL_TIM_OC_ConfigChannel(&htim12, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
77  SYSERR_PRINT("TIM12 OC Config error.\n");
78  }
79 }
80 
81 void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
82 {
83  GPIO_InitTypeDef GPIO_InitStruct;
84  if(htim_base->Instance==TIM12) {
85  __HAL_RCC_TIM12_CLK_ENABLE();
86 
87  GPIO_InitStruct.Pin = ARDUINO_PWM_D6_Pin;
88  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
89  GPIO_InitStruct.Pull = GPIO_NOPULL;
90  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
91  GPIO_InitStruct.Alternate = GPIO_AF9_TIM12;
92  HAL_GPIO_Init(ARDUINO_PWM_D6_GPIO_Port, &GPIO_InitStruct);
93  }
94 }
95 
96 
97 void start_tim12(void)
98 {
99  MX_TIM12_Init();
100 }
101 
102 void on_buzzer(long cycle)
103 {
104  TIM_OC_InitTypeDef sConfigOC;
105 
106  if(cycle > 0x3FFFF) {
107  DKPRINTF(0x01, "Invalid CYCLE = %d\n", (int)cycle);
108  return;
109  } else if(cycle > 0x1FFFF) {
110  htim12.Init.Prescaler = 2;
111  htim12.Init.Period = cycle/4;
112  } else if(cycle > 0xFFFF) {
113  htim12.Init.Prescaler = 1;
114  htim12.Init.Period = cycle/2;
115  } else {
116  htim12.Init.Prescaler = 0;
117  htim12.Init.Period = cycle;
118  }
119 
120  DKPRINTF(0x01, "Clock Prescaler = %d, Period = %d\n",
121  (int)htim12.Init.Prescaler, (int)htim12.Init.Period);
122 
123  if(HAL_TIM_Base_Init(&htim12) != HAL_OK) {
124  SYSERR_PRINT("TIM12 Initialize error.\n");
125  }
126 
127  sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
128  sConfigOC.Pulse = htim12.Init.Period/2;
129  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
130  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
131  HAL_TIM_OC_ConfigChannel(&htim12, &sConfigOC, TIM_CHANNEL_1);
132 
133  HAL_TIM_OC_Start(&htim12, TIM_CHANNEL_1);
134 }
135 
136 void off_buzzer(void)
137 {
138  HAL_TIM_OC_Stop(&htim12, TIM_CHANNEL_1);
139 }
140 
141 static int buzzer_register(struct st_device *dev, char *param)
142 {
143  start_tim12();
144 
145  return 0;
146 }
147 
148 static int buzzer_unregister(struct st_device *dev)
149 {
150  off_buzzer();
151 
152  return 0;
153 }
154 
155 static int buzzer_open(struct st_device *dev)
156 {
157  return 0;
158 }
159 
160 static int buzzer_close(struct st_device *dev)
161 {
162  off_buzzer();
163 
164  return 0;
165 }
166 
167 static int buzzer_ioctl(struct st_device *dev, long com, long arg)
168 {
169  switch(com) {
170  case IOCMD_BUZZER_OFF: // Stop
171  off_buzzer();
172  break;
173 
174  case IOCMD_BUZZER_ON: // Play
175  {
176  long cycle = (CPU_CLOCK_HZ/4) / arg;
177  DKPRINTF(0x01, "CYCLE = %d\n", (int)cycle);
178  on_buzzer(cycle);
179  }
180  break;
181 
182  default:
183  off_buzzer();
184  SYSERR_PRINT("Unknown ioctl(%08lX)\n", com);
185  return -1;
186  }
187 
188  return 0;
189 }
190 
191 static int buzzer_suspend(struct st_device *dev)
192 {
193  off_buzzer();
194 
195  return 0;
196 }
197 
198 static int buzzer_resume(struct st_device *dev)
199 {
200  start_tim12();
201 
202  return 0;
203 }
204 
205 const device buzzer_device = {
206  .name = DEF_DEV_NAME_BUZZER,
207  .explan = "STM32F7 TIM12 buzzer",
208  .register_dev = buzzer_register,
209  .unregister_dev = buzzer_unregister,
210  .open = buzzer_open,
211  .close = buzzer_close,
212  .ioctl = buzzer_ioctl,
213  .suspend = buzzer_suspend,
214  .resume = buzzer_resume,
215 };
Buzzerドライバ ioctl 用マクロ定義
カーネルタイマ
#define IOCMD_BUZZER_OFF
ブザー音声出力停止
Definition: buzzer_ioctl.h:18
カーネル用機能限定printf
#define DEF_DEV_NAME_BUZZER
標準ブザーデバイス名
Definition: buzzer_ioctl.h:15
#define IOCMD_BUZZER_ON
ブザー音声出力開始
Definition: buzzer_ioctl.h:17
デバイスドライバAPI
デバイスドライバ構造体
Definition: device.h:25
カーネル、ドライバ(非タスク)デバッグ用マクロ