Functions

xpal_noise.h File Reference

Go to the source code of this file.

Functions

void xpal_noise_init (void)
 init noise generator
void xpal_output_noise (uint16_t duration, uint8_t value, volatile uint8_t *pdone)
 output some noise
void xpal_output_noise_ms (uint16_t duration, uint8_t value, volatile uint8_t *pdone)

Detailed Description


Function Documentation

void xpal_noise_init ( void   ) 

init noise generator

initialize the noise generator (Timer0 in PWM mode)

{
  DDRG |= _BV(DDG5);

  /* fast PWM, normal output mode on OC0B */
  TCCR0A = (TCCR0A & ~(_BV(COM0B1)|_BV(COM0B0)|_BV(WGM01)|_BV(WGM00)))
    | (_BV(COM0B1)|(0*_BV(COM0B0))|_BV(WGM01)|_BV(WGM00));
}

void xpal_output_noise ( uint16_t  duration,
uint8_t  value,
volatile uint8_t *  pdone 
)

output some noise

output some noise for ${duration*256}\over{F\_CPU}$ seconds.

Parameters:
duration time after the noise should stop
value 0 - stop noise, otherwise play
pdone pointer to a uint8_t which gets set to !=0 when playing this part has finished. Pass NULL when not wanted.

values: 1 - 3600 Hz sine wave 2 - 7200 Hz sine wave

{
  if (value) {
    const struct sample_s *s;
    uint8_t sz;
    noise_part_t * p = NULL;
    uint8_t * v = NULL;

    /* bounds check */
    if (value >= sizeof(samples)/sizeof(samples[0])) value = 1;

    /* prepare new part for queue */
    s = &samples[value];
    sz = pgm_read_byte (&s->sz);
    
    while (1) {
      if (!v) v = malloc (sz);
      if (!p) p = malloc(sizeof(noise_part_t));
      if (v && p) break;
      /* malloc() failed - try GC if useful */
      if (!noises_done) {
        /* GC won't help (yet?) - free() malloced spaces and ignore sample */
        free (v);
        free (p);
        if (pdone) *pdone = -1;
        return;
      }
      xpal_noise_gc ();
    }
    p->values = v;
    p->num_values = sz/sizeof(uint8_t);
    p->flags.malloced_struct = p->flags.malloced_values = 1;
    memcpy_P (v, (const uint8_t*)pgm_read_word (&s->v), sz);
    p->duration = duration;
    p->next = NULL;
    p->pdone = pdone;

    /* Link newly-prepared part at end of queue.
     * Block is necessary to prevent a race condition with the ISR
     * modifying noise_playing or *noise_playing.
     */
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
      if (!noise_playing) {
        noise_playing = p;
        xpal_noise_init ();
        xpal_noise_enable ();
      } else {
        noise_last->next = p;
      }
      noise_last = p;
    }
  } else {
    xpal_noise_disable ();
  }
  xpal_noise_gc ();
}