From 2eeedf6c55e6bf37b3647b01a905e8775b7e6a0e Mon Sep 17 00:00:00 2001 From: bsongis Date: Fri, 4 May 2012 10:20:59 +0000 Subject: [PATCH] Some more refactoring in audio / haptic --- src/Makefile | 3 +- src/board_ersky9x.cpp | 1 + src/board_ersky9x.h | 4 +- src/ersky9x/audio.cpp | 11 +- src/ersky9x/haptic_driver.cpp | 55 ++++++ src/ersky9x/haptic_driver.h | 35 ++++ src/ersky9x/sdcard_driver.cpp | 39 ++++ src/ersky9x/sdcard_driver.h | 35 ++++ src/ersky9x/{sound.cpp => sound_driver.cpp} | 190 ++++---------------- src/ersky9x/{sound.h => sound_driver.h} | 30 ++-- src/haptic.cpp | 5 +- 11 files changed, 229 insertions(+), 179 deletions(-) create mode 100644 src/ersky9x/haptic_driver.cpp create mode 100644 src/ersky9x/haptic_driver.h create mode 100644 src/ersky9x/sdcard_driver.cpp create mode 100644 src/ersky9x/sdcard_driver.h rename src/ersky9x/{sound.cpp => sound_driver.cpp} (61%) rename src/ersky9x/{sound.h => sound_driver.h} (83%) diff --git a/src/Makefile b/src/Makefile index 76c5967ad..9586775e5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -292,7 +292,8 @@ ifeq ($(PCB), ARM) # ersky9x/ff.c ersky9x/diskio_sam3s.c ersky9x/Media.c ersky9x/ccsbcs.c ersky9x/sdcard.c ersky9x/MEDSdcard.c EEPROMSRC = eeprom_arm.cpp PULSESSRC = pulses_arm.cpp - CPPSRC += ersky9x/audio.cpp ersky9x/sound.cpp haptic.cpp + CPPSRC += ersky9x/audio.cpp haptic.cpp + CPPSRC += ersky9x/sound_driver.cpp ersky9x/haptic_driver.cpp ersky9x/sdcard_driver.cpp endif ifeq ($(PCB), V4) diff --git a/src/board_ersky9x.cpp b/src/board_ersky9x.cpp index c995f4b49..04a816088 100644 --- a/src/board_ersky9x.cpp +++ b/src/board_ersky9x.cpp @@ -720,6 +720,7 @@ void board_init() start_timer0() ; init_adc() ; init_pwm() ; + init_SDcard() ; __enable_irq() ; diff --git a/src/board_ersky9x.h b/src/board_ersky9x.h index c2bb0003d..5585511e6 100644 --- a/src/board_ersky9x.h +++ b/src/board_ersky9x.h @@ -40,7 +40,9 @@ #include "ersky9x/AT91SAM3S4.h" #endif -#include "ersky9x/sound.h" +#include "ersky9x/sound_driver.h" +#include "ersky9x/haptic_driver.h" +#include "ersky9x/sdcard_driver.h" #define PIN_ENABLE 0x001 #define PIN_PERIPHERAL 0x000 diff --git a/src/ersky9x/audio.cpp b/src/ersky9x/audio.cpp index fae06dc95..2e6bd79b2 100644 --- a/src/ersky9x/audio.cpp +++ b/src/ersky9x/audio.cpp @@ -54,19 +54,18 @@ void audioQueue::heartbeat() if (toneTimeLeft > 0) { if (toneChanged) { toneChanged = 0; - set_frequency(toneFreq); + set_frequency(toneFreq * 61 / 2); tone_start(0); } else if (toneFreqIncr && (toneTimeLeft&1) == 0) { toneFreq += toneFreqIncr; - set_frequency(toneFreq); + set_frequency(toneFreq * 61 / 2); } toneTimeLeft--; //time gets counted down } else { if (tonePause > 0) { - DACC->DACC_IDR = DACC_IDR_ENDTX ; // Disable interrupt - // SPEAKER_OFF; + tone_stop(); tonePause--; //time gets counted down } else if (t_queueRidx != t_queueWidx) { @@ -83,13 +82,13 @@ void audioQueue::heartbeat() if (tone2TimeLeft > 0) { if (tone2Changed) { tone2Changed = 0; - set_frequency(toneFreq); + set_frequency(toneFreq * 61 / 2); tone_start(0); } tone2TimeLeft--; //time gets counted down } else { - DACC->DACC_IDR = DACC_IDR_ENDTX ; // Disable interrupt + tone_stop(); if (tone2Pause > 0) { tone2Pause--; //time gets counted down } diff --git a/src/ersky9x/haptic_driver.cpp b/src/ersky9x/haptic_driver.cpp new file mode 100644 index 000000000..baa03f9ba --- /dev/null +++ b/src/ersky9x/haptic_driver.cpp @@ -0,0 +1,55 @@ +/* + * Authors (alphabetical order) + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +void hapticOff() +{ + PWM->PWM_DIS = PWM_DIS_CHID2 ; // Disable channel 2 + PWM->PWM_OOV &= ~0x00040000 ; // Force low + PWM->PWM_OSS |= 0x00040000 ; // Force low +} + +// pwmPercent 0-100 +void hapticOn( uint32_t pwmPercent ) +{ + register Pwm *pwmptr ; + + pwmptr = PWM ; + + if ( pwmPercent > 100 ) + { + pwmPercent = 100 ; + } + pwmptr->PWM_CH_NUM[2].PWM_CDTYUPD = pwmPercent ; // Duty + pwmptr->PWM_ENA = PWM_ENA_CHID2 ; // Enable channel 2 + pwmptr->PWM_OSC = 0x00040000 ; // Enable output +} diff --git a/src/ersky9x/haptic_driver.h b/src/ersky9x/haptic_driver.h new file mode 100644 index 000000000..032b9f622 --- /dev/null +++ b/src/ersky9x/haptic_driver.h @@ -0,0 +1,35 @@ +/* + * Authors (alphabetical order) + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +extern void hapticOff(void) ; +extern void hapticOn( uint32_t pwmPercent ) ; diff --git a/src/ersky9x/sdcard_driver.cpp b/src/ersky9x/sdcard_driver.cpp new file mode 100644 index 000000000..13fae5323 --- /dev/null +++ b/src/ersky9x/sdcard_driver.cpp @@ -0,0 +1,39 @@ +/* + * Authors (alphabetical order) + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +void init_SDcard() +{ + configure_pins( 0xFC000000, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_C | PIN_PORTA | PIN_NO_PULLUP ) ; + configure_pins( PIO_PB7, PIN_INPUT | PIN_PORTB | PIN_NO_PULLUP | PIN_NO_PULLDOWN ) ; +} + diff --git a/src/ersky9x/sdcard_driver.h b/src/ersky9x/sdcard_driver.h new file mode 100644 index 000000000..a7d6bd53d --- /dev/null +++ b/src/ersky9x/sdcard_driver.h @@ -0,0 +1,35 @@ +/* + * Authors (alphabetical order) + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +extern void init_SDcard( void ) ; + diff --git a/src/ersky9x/sound.cpp b/src/ersky9x/sound_driver.cpp similarity index 61% rename from src/ersky9x/sound.cpp rename to src/ersky9x/sound_driver.cpp index 0289aedac..c4fbf244c 100644 --- a/src/ersky9x/sound.cpp +++ b/src/ersky9x/sound_driver.cpp @@ -34,36 +34,7 @@ #include "../open9x.h" -void start_sound( void ) ; -void buzzer_on( void ) ; -void buzzer_off( void ) ; -void buzzer_sound( uint8_t time ) ; -void start_timer1( void ) ; -void init_dac( void ) ; -extern "C" void DAC_IRQHandler( void ) ; -void disp_mem( register uint32_t address ) ; -void end_sound( void ) ; -void tone_start( register uint32_t time ) ; -void tone_stop( void ) ; -void init_twi( void ) ; -void set_volume( register uint8_t volume ) ; -extern "C" void TWI0_IRQHandler (void) ; -void audioDefevent( uint8_t e ) ; - -extern uint32_t Master_frequency ; // TODO in a .h? volatile uint8_t Buzzer_count ; -/* -struct t_sound_globals -{ - uint32_t Next_freq ; - volatile uint32_t Sound_time ; - uint32_t Frequency ; - volatile uint32_t Tone_timer ; // Modified in interrupt routine - volatile uint8_t Tone_ms_timer ; - uint32_t Frequency_increment ; - uint32_t Next_frequency_increment ; -} Sound_g ; -*/ // Must NOT be in flash, PDC needs a RAM source. uint16_t Sine_values[] = @@ -80,20 +51,6 @@ uint16_t Sine_values[] = 872, 976,1084,1196,1311,1429,1550,1673,1797,1922 } ; -// Must NOT be in flash, PDC needs a RAM source. -// We'll use these for higher frequencies -//uint16_t Sine_values64[] = -//{ -//2048,2244,2438,2628,2813,2990,3159,3316, -//3462,3594,3710,3811,3895,3961,4009,4038, -//4048,4038,4009,3961,3895,3811,3710,3594, -//3462,3316,3159,2990,2813,2628,2438,2244, -//2048,1851,1657,1467,1282,1105, 936, 779, -// 633, 501, 385, 284, 200, 134, 86, 57, -// 48, 57, 86, 134, 200, 284, 385, 501, -// 633, 779, 936,1105,1282,1467,1657,1851 -//} ; - const uint16_t PianoTones[] = { 28, 29, 31, 33, 35, 37, 39, 41, 44, 46, @@ -112,60 +69,57 @@ const uint16_t PianoTones[] = void start_sound() { - register Pio *pioptr ; - - start_timer1() ; - init_dac() ; - init_twi() ; + register Pio *pioptr ; - pioptr = PIOA ; + start_timer1() ; + init_dac() ; + init_twi() ; + + pioptr = PIOA ; #ifdef REVB - pioptr->PIO_CODR = 0x02000000L ; // Set bit A25 OFF - pioptr->PIO_PER = 0x02000000L ; // Enable bit A25 (Stock buzzer) - pioptr->PIO_OER = 0x02000000L ; // Set bit A25 as output + pioptr->PIO_CODR = 0x02000000L ; // Set bit A25 OFF + pioptr->PIO_PER = 0x02000000L ; // Enable bit A25 (Stock buzzer) + pioptr->PIO_OER = 0x02000000L ; // Set bit A25 as output #else - pioptr->PIO_CODR = 0x00010000L ; // Set bit A16 OFF - pioptr->PIO_PER = 0x00010000L ; // Enable bit A16 (Stock buzzer) - pioptr->PIO_OER = 0x00010000L ; // Set bit A16 as output + pioptr->PIO_CODR = 0x00010000L ; // Set bit A16 OFF + pioptr->PIO_PER = 0x00010000L ; // Enable bit A16 (Stock buzzer) + pioptr->PIO_OER = 0x00010000L ; // Set bit A16 as output #endif } #ifdef REVB void buzzer_on() { - PIOA->PIO_SODR = 0x02000000L ; // Set bit A25 ON + PIOA->PIO_SODR = 0x02000000L ; // Set bit A25 ON } void buzzer_off() { - PIOA->PIO_CODR = 0x02000000L ; // Set bit A25 ON + PIOA->PIO_CODR = 0x02000000L ; // Set bit A25 ON } #else void buzzer_on() { - PIOA->PIO_SODR = 0x00010000L ; // Set bit A16 ON + PIOA->PIO_SODR = 0x00010000L ; // Set bit A16 ON } void buzzer_off() { - PIOA->PIO_CODR = 0x00010000L ; // Set bit A16 ON + PIOA->PIO_CODR = 0x00010000L ; // Set bit A16 ON } #endif void buzzer_sound( uint8_t time ) { - buzzer_on() ; - Buzzer_count = time ; + buzzer_on() ; + Buzzer_count = time ; } - void set_frequency( uint32_t frequency ) { register Tc *ptc ; register uint32_t timer ; - frequency = frequency * 61 / 2; - timer = Master_frequency / (800 * frequency) ; // MCK/8 and 100 000 Hz if ( timer > 65535 ) { @@ -204,8 +158,7 @@ void start_timer1() ptc->TC_CHANNEL[1].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) // Sound_g.Frequency = 1000 ; } - - + // Configure DAC1 (or DAC0 for REVB) // Not sure why PB14 has not be allocated to the DAC, although it is an EXTRA function @@ -245,18 +198,6 @@ extern "C" void DAC_IRQHandler() DACC->DACC_TNPR = (uint32_t) Sine_values ; #endif DACC->DACC_TNCR = 50 ; // words, 100 16 bit values -/* if ( Sound_g.Tone_timer ) - { - if ( --Sound_g.Tone_timer == 0 ) - { - DACC->DACC_IDR = DACC_IDR_ENDTX ; - } - } */ -// if ( Tone_ms_timer == 0 ) -// { -// Tone_ms_timer = -1 ; -// DACC->DACC_IDR = DACC_IDR_ENDTX ; -// } } void end_sound() @@ -269,78 +210,38 @@ void end_sound() PMC->PMC_PCER0 &= ~0x40000000L ; // Disable peripheral clock to DAC } -#if 0 -// frequency in Hz, time in mS -void playTone( uint32_t frequency, uint32_t time ) -{ - Sound_g.Next_frequency_increment = 0 ; - Sound_g.Next_freq = frequency ; - Sound_g.Sound_time = time ; -// set_frequency( frequency ) ; -// Tone_ms_timer = ( time + 4 ) / 5 ; -// tone_start( 0 ) ; -} -#endif -/* -uint32_t queueTone( uint32_t frequency, uint32_t time, uint32_t frequency_increment ) -{ - if ( Sound_g.Sound_time == 0 ) - { - Sound_g.Next_freq = frequency ; - Sound_g.Next_frequency_increment = frequency_increment ; - Sound_g.Sound_time = time ; - return 1 ; - } - return 0 ; -} -*/ -// Time is in milliseconds -void tone_start( register uint32_t time ) -{ - PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC - // Sound_g.Tone_timer = Sound_g.Frequency * time / 1000 ; - DACC->DACC_IER = DACC_IER_ENDTX ; -} - -void tone_stop() -{ - DACC->DACC_IDR = DACC_IDR_ENDTX ; // Disable interrupt - // Sound_g.Tone_timer = 0 ; -} - - // Set up for volume control (TWI0) // Need PA3 and PA4 set to peripheral A void init_twi() { - register Pio *pioptr ; - register uint32_t timing ; + register Pio *pioptr ; + register uint32_t timing ; - PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 + PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 /* Configure PIO */ - pioptr = PIOA ; + pioptr = PIOA ; pioptr->PIO_ABCDSR[0] &= ~0x00000018 ; // Peripheral A pioptr->PIO_ABCDSR[1] &= ~0x00000018 ; // Peripheral A pioptr->PIO_PDR = 0x00000018 ; // Assign to peripheral - timing = Master_frequency * 5 / 1000000 ; // 5uS high and low - timing += 15 - 4 ; - timing /= 16 ; - timing |= timing << 8 ; + timing = Master_frequency * 5 / 1000000 ; // 5uS high and low + timing += 15 - 4 ; + timing /= 16 ; + timing |= timing << 8 ; - TWI0->TWI_CWGR = 0x00040000 | timing ; // TWI clock set - TWI0->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS ; // Master mode enable - TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing - NVIC_EnableIRQ(TWI0_IRQn) ; - set_volume( 2 ) ; + TWI0->TWI_CWGR = 0x00040000 | timing ; // TWI clock set + TWI0->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS ; // Master mode enable + TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing + NVIC_EnableIRQ(TWI0_IRQn) ; + set_volume( 2 ) ; } static int16_t Volume_required ; static const uint8_t Volume_scale[NUM_VOL_LEVELS] = { - 0, 2, 4, 6, 8, 10, 13, 17, 22, 27, 33, 40, - 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 + 0, 2, 4, 6, 8, 10, 13, 17, 22, 27, 33, 40, + 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 } ; void set_volume( register uint8_t volume ) @@ -382,27 +283,4 @@ extern "C" void TWI0_IRQHandler() } } -void hapticOff() -{ - PWM->PWM_DIS = PWM_DIS_CHID2 ; // Disable channel 2 - PWM->PWM_OOV &= ~0x00040000 ; // Force low - PWM->PWM_OSS |= 0x00040000 ; // Force low -} - -// pwmPercent 0-100 -void hapticOn( uint32_t pwmPercent ) -{ - register Pwm *pwmptr ; - - pwmptr = PWM ; - - if ( pwmPercent > 100 ) - { - pwmPercent = 100 ; - } - pwmptr->PWM_CH_NUM[2].PWM_CDTYUPD = pwmPercent ; // Duty - pwmptr->PWM_ENA = PWM_ENA_CHID2 ; // Enable channel 2 - pwmptr->PWM_OSC = 0x00040000 ; // Enable output -} - diff --git a/src/ersky9x/sound.h b/src/ersky9x/sound_driver.h similarity index 83% rename from src/ersky9x/sound.h rename to src/ersky9x/sound_driver.h index 2e0d8d10d..c4763c899 100644 --- a/src/ersky9x/sound.h +++ b/src/ersky9x/sound_driver.h @@ -32,12 +32,11 @@ * ****************************************************************************/ +#ifndef sound_driver_h +#define sound_driver_h #define NUM_VOL_LEVELS 24 -extern volatile uint8_t Buzzer_count ; - - extern void start_sound( void ) ; extern void buzzer_on( void ) ; extern void buzzer_off( void ) ; @@ -47,17 +46,22 @@ extern void start_timer1( void ) ; extern void init_dac( void ) ; extern "C" void DAC_IRQHandler( void ) ; extern void end_sound( void ) ; -extern void playTone( uint32_t frequency, uint32_t time ) ; -extern uint32_t queueTone( uint32_t frequency, uint32_t time, uint32_t frequency_increment ) ; -extern void tone_start( register uint32_t time ) ; -extern void tone_stop( void ) ; + +inline void tone_start( register uint32_t time ) +{ + PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC + DACC->DACC_IER = DACC_IER_ENDTX ; +} + +inline void tone_stop( void ) +{ + DACC->DACC_IDR = DACC_IDR_ENDTX ; // Disable interrupt +} + +extern volatile uint8_t Buzzer_count ; + extern void init_twi( void ) ; extern void set_volume( register uint8_t volume ) ; extern "C" void TWI0_IRQHandler (void) ; -extern void audioDefevent( uint8_t e ) ; -extern void hapticOff(void) ; -extern void hapticOn( uint32_t pwmPercent ) ; -extern void sound_5ms( void ) ; - - +#endif diff --git a/src/haptic.cpp b/src/haptic.cpp index 2ae3a0574..ce0cdaf86 100644 --- a/src/haptic.cpp +++ b/src/haptic.cpp @@ -83,7 +83,7 @@ void hapticQueue::play(uint8_t tLen, uint8_t tPause, uint8_t tFlags) { tLen = getHapticLength(tLen); - if (tFlags & PLAY_NOW || (!busy() && empty())) { + if ((tFlags & PLAY_NOW) || (!busy() && empty())) { buzzTimeLeft = tLen; buzzPause = tPause; t_queueWidx = t_queueRidx; @@ -115,8 +115,9 @@ void hapticQueue::event(uint8_t e) play(15, 3, PLAY_NOW); else if (e < AU_FRSKY_FIRST) play(15, 3, (e-AU_TIMER_10)|PLAY_NOW); - else if (e >= AU_FRSKY_LAST) + else if (e >= AU_FRSKY_LAST && empty()) { play(15, 3, e-AU_FRSKY_LAST); + } } }