OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_STM32F103_Primer_GCC/] [ST_Code/] [buzzer.c] - Blame information for rev 582

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 582 jeremybenn
/********************* (C) COPYRIGHT 2007 RAISONANCE S.A.S. *******************/
2
/**
3
*
4
* @file     buzzer.c
5
* @brief    Buzzer dedicated functions with RTTTL format support.
6
* @author   IB
7
* @date     07/2007
8
*
9
**/
10
/******************************************************************************/
11
 
12
/* Includes ------------------------------------------------------------------*/
13
#include "circle.h"
14
 
15
/// @cond Internal
16
 
17
/* Private typedef -----------------------------------------------------------*/
18
 
19
/*! Octaves */
20
enum eOctave  {
21
      OCT_440  = 0,  /*!< o = 5 */
22
      OCT_880  = 1,  /*!< o = 6 */
23
      OCT_1760 = 2,  /*!< o = 7 */
24
      OCT_3520 = 3,  /*!< o = 8 */
25
      OCT_7040 = 4   /*!< o = 9 */
26
      } octave;
27
 
28
/*! Notes */
29
enum eNotes  {
30
      NOTE_PAUSE = 0,    /*!< P  */
31
      NOTE_LA    = 1,    /*!< A  */
32
      NOTE_LA_H  = 8+1,  /*!< A# */
33
      NOTE_SI    = 2,    /*!< B  */
34
      NOTE_DO    = 3,    /*!< C  */
35
      NOTE_DO_H  = 8+3,  /*!< C# */
36
      NOTE_RE    = 4,    /*!< D  */
37
      NOTE_RE_H  = 8+4,  /*!< D# */
38
      NOTE_MI    = 5,    /*!< E  */
39
      NOTE_FA    = 6,    /*!< F  */
40
      NOTE_FA_H  = 8+6,  /*!< F# */
41
      NOTE_SOL   = 7,    /*!< G  */
42
      NOTE_SOL_H = 8+7   /*!< G# */
43
      } note;
44
 
45
/* Private define ------------------------------------------------------------*/
46
#define BUZZER_SHORTBEEP_DURATION   100
47
#define BUZZER_LONGBEEP_DURATION    1000
48
#define RTTTL_SEP                   ':'
49
 
50
/* Private macro -------------------------------------------------------------*/
51
/* Private variables ---------------------------------------------------------*/
52
int                              buzz_counter         = 0;
53
int                              buzz_in_progress     = 0;
54
static TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
55
static TIM_OCInitTypeDef         TIM_OCInitStructure;
56
u16                              CCR_Val              = 0x2EE0;
57
enum BUZZER_mode                 Buzzer_Mode          = BUZZER_UNDEF;
58
u32                              Buzzer_Counter       = 0;
59
 
60
// For the melody.
61
const u8*                        CurrentMelody        = 0;
62
const u8*                        CurrentMelodySTART   = 0;
63
u8                               DefaultOctave        = OCT_880;
64
u8                               DefaultDuration      = 4;
65
u16                              DefaultBeats         = 63;
66
 
67
u16 Note_Freq [16] = {
68
   0,    //pause
69
   440,  //A=LA
70
   494,  //B=SI
71
   524,  //C=DO
72
   588,  //D=RE
73
   660,  //E=MI
74
   698,  //F=FA
75
   784,  //G=SOL
76
   0,    // "8+n" for "NOTE#"
77
   466,  //A#=LA#
78
   0,
79
   544,  //C#=DO#
80
   622,  //D#=RE#
81
   0,
82
   740,  //F#=FA#
83
   830   //G#=SOL#
84
   };
85
 
86
/* Private function prototypes -----------------------------------------------*/
87
static void PlayMusic( void );
88
static void BUZZER_SetFrequency( u16 freq );
89
 
90
/* Private functions ---------------------------------------------------------*/
91
 
92
/*******************************************************************************
93
*
94
*                                PlayMusic
95
*
96
*******************************************************************************/
97
/**
98
*
99
*  Play the next note of the current melody.
100
*
101
**/
102
/******************************************************************************/
103
static void PlayMusic( void )
104
   {
105
   u8 duration = DefaultDuration;
106
   u8 c;
107
 
108
   // Discard blank characters
109
   while ( *CurrentMelody == ' ')
110
      {
111
      CurrentMelody++;
112
      }
113
 
114
   // Check whether a duration is present.
115
   if ( (*CurrentMelody > '0') && (*CurrentMelody < '9') )
116
      {
117
      duration = *CurrentMelody++ - '0';
118
 
119
      if ( (*CurrentMelody > '0') && (*CurrentMelody < '9') )
120
         {
121
         duration *= 10;
122
         duration += (*CurrentMelody++ - '0');
123
         }
124
      }
125
 
126
   Buzzer_Counter = ( (32/duration) * 256L * 32L) / DefaultBeats;
127
   Buzzer_Counter*= (RCC_ClockFreq.SYSCLK_Frequency / 12000000L); //Adapt to HCLK1
128
 
129
   //read the note
130
   c = *CurrentMelody++;
131
 
132
   if ( (c >= 'a') && (c <= 'z') )
133
      {
134
      c+=('A'-'a');
135
      }
136
 
137
   if ( c == 'P' )
138
      {
139
      note = NOTE_PAUSE;
140
      }
141
   else if ( (c >= 'A') && (c <= 'G') )
142
      {
143
      note = (c - 'A') + NOTE_LA;
144
 
145
      if ( *CurrentMelody == '#' )
146
         {
147
         note|=0x8;
148
         CurrentMelody++;
149
         }
150
      }
151
 
152
   octave = DefaultOctave;
153
   c = *CurrentMelody;
154
 
155
   if ( (c>= '5') && (c<= '8') )
156
      {
157
      octave = OCT_440 + (c-'5');
158
      CurrentMelody++;
159
      }
160
 
161
   BUZZER_SetFrequency ( (Note_Freq [ note ] * (1<<octave)));
162
 
163
   //discard delimiter and ignore special duration
164
   while ( (c = *CurrentMelody++) != 0 )
165
      {
166
      if ( c==',')
167
         break;
168
      }
169
 
170
   if ( *(CurrentMelody-1)==0 )
171
      {
172
      CurrentMelody  = 0;
173
      }
174
 
175
   if ( c == 0 )
176
      {
177
      BUZZER_SetMode ( BUZZER_OFF );
178
      }
179
   }
180
 
181
/***********************************************************************************
182
*
183
*                                BUZZER_SetFrequency
184
*
185
************************************************************************************/
186
/**
187
*
188
*  Set the buzzer frequency
189
*
190
*  @param[in]  freq New frequency.
191
*
192
**/
193
/********************************************************************************/
194
void BUZZER_SetFrequency ( u16 freq )
195
   {
196
   /* Calculate the frequency (depend on the PCLK1 clock value) */
197
   CCR_Val = (RCC_ClockFreq.PCLK1_Frequency / freq);
198
 
199
   TIM_TimeBaseStructure.TIM_Period          = CCR_Val * 2;
200
   TIM_TimeBaseStructure.TIM_Prescaler       = 0x0;
201
   TIM_TimeBaseStructure.TIM_ClockDivision   = 0x0;
202
   TIM_TimeBaseStructure.TIM_CounterMode     = TIM_CounterMode_Up;
203
 
204
   TIM_TimeBaseInit( TIM3, &TIM_TimeBaseStructure );
205
 
206
   /* Output Compare Toggle Mode configuration: Channel3 */
207
   TIM_OCInitStructure.TIM_OCMode   = TIM_OCMode_PWM1;
208
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
209
   TIM_OCInitStructure.TIM_Pulse    = CCR_Val;
210
 
211
   TIM_OC3Init( TIM3, &TIM_OCInitStructure );
212
   TIM_OC3PreloadConfig( TIM3, TIM_OCPreload_Enable );
213
   }
214
 
215
/* Public functions for CircleOS ---------------------------------------------*/
216
 
217
/*******************************************************************************
218
*
219
*                                BUZZER_Init
220
*
221
*******************************************************************************/
222
/**
223
*
224
*  Buzzer Initialization
225
*
226
*  @attention  This function must <b>NOT</b> be called by the user.
227
*
228
**/
229
/******************************************************************************/
230
void BUZZER_Init( void )
231
   {
232
   GPIO_InitTypeDef GPIO_InitStructure;
233
 
234
   /* Enable GPIOB clock  */
235
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
236
 
237
   /* GPIOB Configuration: TIM3 3in Output */
238
   GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;
239
   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
240
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
241
 
242
   GPIO_Init( GPIOB, &GPIO_InitStructure );
243
 
244
   /* TIM3 Configuration ------------------------------------------------------*/
245
   /* TIM3CLK = 18 MHz, Prescaler = 0x0, TIM3 counter clock = 18  MHz */
246
   /* CC update rate = TIM3 counter clock / (2* CCR_Val) ~= 750 Hz */
247
 
248
   /* Enable TIM3 clock */
249
   RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE );
250
   TIM_DeInit( TIM3 );
251
   TIM_TimeBaseStructInit( &TIM_TimeBaseStructure );
252
   TIM_OCStructInit( &TIM_OCInitStructure );
253
 
254
   /* Time base configuration */
255
   TIM_TimeBaseStructure.TIM_Period          = 0xFFFF;
256
   TIM_TimeBaseStructure.TIM_Prescaler       = 0x0;
257
   TIM_TimeBaseStructure.TIM_ClockDivision   = 0x0;
258
   TIM_TimeBaseStructure.TIM_CounterMode     = TIM_CounterMode_Up;
259
 
260
   TIM_TimeBaseInit( TIM3, &TIM_TimeBaseStructure );
261
 
262
   /* Output Compare Toggle Mode configuration: Channel3 */
263
   TIM_OCInitStructure.TIM_OCMode   = TIM_OCMode_Toggle;
264
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
265
   TIM_OCInitStructure.TIM_Pulse    = CCR_Val;
266
 
267
   TIM_OC3Init( TIM3, &TIM_OCInitStructure );
268
   TIM_OC3PreloadConfig( TIM3, TIM_OCPreload_Disable );
269
   BUZZER_SetFrequency( 440 );
270
 
271
   /* Enable TIM3 IT */
272
   TIM_ITConfig( TIM3, TIM_IT_CC3, ENABLE );
273
 
274
   Buzzer_Mode  = BUZZER_OFF;
275
   }
276
 
277
/*******************************************************************************
278
*
279
*                                BUZZER_Handler
280
*
281
*******************************************************************************/
282
/**
283
*
284
*  Called by the CircleOS scheduler to manage Buzzer tasks.
285
*
286
*  @attention  This function must <b>NOT</b> be called by the user.
287
*
288
**/
289
/******************************************************************************/
290
void BUZZER_Handler( void )
291
   {
292
   int fSetOFF = 0;
293
 
294
   if ( Buzzer_Mode == BUZZER_PLAYMUSIC )
295
      {
296
      if ( Buzzer_Counter == 0 )
297
         {
298
         PlayMusic();
299
         }
300
      else
301
         {
302
         Buzzer_Counter--;
303
         }
304
 
305
      return;
306
      }
307
   else if ( Buzzer_Mode == BUZZER_SHORTBEEP )
308
      {
309
      if ( Buzzer_Counter++ == (BUZZER_SHORTBEEP_DURATION) )
310
         {
311
         Buzzer_Mode  = BUZZER_OFF;
312
 
313
         return;
314
         }
315
      if ( Buzzer_Counter == (BUZZER_SHORTBEEP_DURATION/2) )
316
         {
317
         fSetOFF = 1;
318
         }
319
      }
320
   else if ( Buzzer_Mode == BUZZER_LONGBEEP )
321
      {
322
      if ( Buzzer_Counter++ == (BUZZER_LONGBEEP_DURATION) )
323
         {
324
         Buzzer_Mode  = BUZZER_OFF;
325
 
326
         return;
327
         }
328
      if ( Buzzer_Counter > (BUZZER_LONGBEEP_DURATION/2) )
329
         {
330
         fSetOFF = 1;
331
         }
332
      }
333
 
334
   if ( fSetOFF == 1 )
335
      {
336
      TIM_Cmd(TIM3, DISABLE);
337
      }
338
   }
339
 
340
/// @endcond
341
 
342
/* Public functions ----------------------------------------------------------*/
343
 
344
/*******************************************************************************
345
*
346
*                                BUZZER_GetMode
347
*
348
*******************************************************************************/
349
/**
350
*
351
*  Get the current buzzer mode.
352
*
353
*  @return  Current buzzer mode.
354
*
355
**/
356
/******************************************************************************/
357
enum BUZZER_mode BUZZER_GetMode( void )
358
   {
359
   return Buzzer_Mode;
360
   }
361
 
362
/*******************************************************************************
363
*
364
*                                BUZZER_SetMode
365
*
366
*******************************************************************************/
367
/**
368
*
369
*  Set new buzzer mode
370
*
371
*  @param[in]  mode  New buzzer mode.
372
*
373
**/
374
/******************************************************************************/
375
void BUZZER_SetMode( enum BUZZER_mode mode )
376
   {
377
   Buzzer_Mode    = mode;
378
   Buzzer_Counter = 0;
379
 
380
   switch ( mode )
381
      {
382
      case BUZZER_PLAYMUSIC   :
383
         PlayMusic(); //start melody
384
         /* no break */
385
 
386
      case BUZZER_LONGBEEP    :
387
      case BUZZER_SHORTBEEP   :
388
      case BUZZER_ON          :
389
         TIM_Cmd( TIM3, ENABLE );
390
         break;
391
 
392
      case BUZZER_OFF         :
393
         TIM_Cmd( TIM3, DISABLE );
394
         break;
395
      }
396
   }
397
 
398
/*******************************************************************************
399
*
400
*                                BUZZER_PlayMusic
401
*
402
*******************************************************************************/
403
/**
404
*
405
*  Plays the provided melody that follows the RTTTL Format.
406
*
407
*  Official Specification
408
*  @verbatim
409
<ringing-tones-text-transfer-language> :=
410
   <name> <sep> [<defaults>] <sep> <note-command>+
411
<name> := <char>+ ; maximum name length 10 characters
412
<sep> := ":"
413
<defaults> :=
414
   <def-note-duration> |
415
   <def-note-scale> |
416
   <def-beats>
417
<def-note-duration> := "d=" <duration>
418
<def-note-scale> := "o=" <scale>
419
<def-beats> := "b=" <beats-per-minute>
420
<beats-per-minute> := 25,28,...,900 ; decimal value
421
; If not specified, defaults are
422
   ;
423
   ; 4 = duration
424
   ; 6 = scale
425
   ; 63 = beats-per-minute
426
<note-command> :=
427
   [<duration>] <note> [<scale>] [<special-duration>] <delimiter>
428
   <duration> :=
429
   "1" | ; Full 1/1 note
430
   "2" | ; 1/2 note
431
   "4" | ; 1/4 note
432
   "8" | ; 1/8 note
433
   "16" | ; 1/16 note
434
   "32" | ; 1/32 note
435
<note> :=
436
   "P"  | ; pause
437
   "C"  |
438
   "C#" |
439
   "D"  |
440
   "D#" |
441
   "E"  |
442
   "F"  |
443
   "F#" |
444
   "G"  |
445
   "G#" |
446
   "A"  |
447
   "A#" |
448
   "B"
449
<scale> :=
450
   "5" | ; Note A is 440Hz
451
   "6" | ; Note A is 880Hz
452
   "7" | ; Note A is 1.76 kHz
453
   "8" ; Note A is 3.52 kHz
454
<special-duration> :=
455
   "." ; Dotted note
456
<delimiter> := ","
457
@endverbatim
458
*
459
*  @param[in]  melody New melody to play on buzzer.
460
*
461
**/
462
/******************************************************************************/
463
void BUZZER_PlayMusic (const u8 *melody )
464
   {
465
   u8    c;
466
   u8    default_id  = 0;
467
   u16   default_val = 0;
468
 
469
   DefaultOctave      = OCT_880;  // Default for the default Octave.
470
   DefaultDuration    = 4;        // Default for the default Duration.
471
   DefaultBeats       = 63;
472
   CurrentMelody      = melody;
473
   CurrentMelodySTART = melody;
474
 
475
   while( *CurrentMelody != RTTTL_SEP )
476
      {
477
      if( *CurrentMelody == 0 )
478
         {
479
         return;
480
         }
481
 
482
      // Discard the melody name.
483
      CurrentMelody++;
484
      }
485
 
486
   // Now read the defaults if any.
487
   for( ++CurrentMelody; *CurrentMelody != RTTTL_SEP; CurrentMelody++ )
488
      {
489
      if( *CurrentMelody == 0 )
490
         {
491
         return;
492
         }
493
 
494
      // Discard any blank.
495
      while ( *CurrentMelody == ' ' )
496
         {
497
         CurrentMelody++;
498
         }
499
 
500
      c = *CurrentMelody;
501
 
502
      if ( c == RTTTL_SEP )
503
         {
504
         break;
505
         }
506
 
507
      if ( (c >= 'a') && (c <= 'z') )
508
         {
509
         c+=('A'-'a');
510
         }
511
 
512
      if ( (c >= 'A') && (c <= 'Z') )
513
         {
514
         default_id = c;
515
         continue;
516
         }
517
 
518
      if ( (c >= '0') && (c <= '9') )
519
         {
520
         default_val *= 10;
521
         default_val += (c-'0');
522
         c = * (CurrentMelody + 1 );
523
 
524
         if ( (c >= '0') && (c <= '9') )
525
            {
526
            continue;
527
            }
528
 
529
         if ( default_id == 'D' )
530
            {
531
            DefaultDuration = default_val;
532
            }
533
         else if ( default_id == 'O' )
534
            {
535
            DefaultOctave = default_val - 5;
536
 
537
            if ( DefaultOctave > OCT_7040 )
538
               DefaultOctave = OCT_440;
539
            }
540
         else if ( default_id == 'B' )
541
            {
542
            DefaultBeats = default_val;
543
 
544
            if ( ( DefaultBeats == 0 ) || ( DefaultBeats > 500 ) )
545
               DefaultBeats = 63;
546
            }
547
 
548
         default_val = 0;
549
         default_id  = 0;
550
         }
551
      }
552
 
553
   BUZZER_SetMode( BUZZER_PLAYMUSIC );
554
   }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.