EmbedEd
/
mbed_theremin
xypad theremin for LPC1768
Revision 1:aa184d2eb2e3, committed 2016-03-14
- Comitter:
- exopiped
- Date:
- Mon Mar 14 23:37:58 2016 +0000
- Parent:
- 0:8ee38453bad9
- Child:
- 2:c5eeaf1c8e69
- Commit message:
- Eliminated audio glitches from touch screen
Changed in this revision
--- a/dma.cpp Sun Mar 13 01:12:40 2016 +0000 +++ b/dma.cpp Mon Mar 14 23:37:58 2016 +0000 @@ -10,6 +10,8 @@ int buffer[2][DMA_BUFSIZE]; AnalogOut sig(p18); // analog output object ( uses pin 18) +DigitalOut led2(LED1); +DigitalOut led3(LED2); MODDMA dma; MODDMA_Config *conf0, *conf1; @@ -82,43 +84,42 @@ } void dma_disable(void) -{ +{ + // Get configuration pointer. + MODDMA_Config *config = dma.getConfig(); // Finish the DMA cycle by shutting down the channel. - dma.Disable((MODDMA::CHANNELS)conf0->channelNum()); - dma.Disable((MODDMA::CHANNELS)conf1->channelNum()); + dma.Disable((MODDMA::CHANNELS)config->channelNum()); } // Configuration callback on TC void TC0_callback(void) { - - dma.Disable((MODDMA::CHANNELS)conf0->channelNum()); - + + dma_disable(); + if (note_active()) { // Notify note.cpp that it is time to refill buffer[0] note_set_bufno(0); - + // Swap to buffer1 dma.Prepare( conf1 ); + } + // Clear DMA IRQ flags. + if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); - // Clear DMA IRQ flags. - if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); - } else { - dma.Disable((MODDMA::CHANNELS)conf1->channelNum()); - } } // Configuration callback on Error void ERR0_callback(void) { + led2=1; error("Oh no! My Mbed EXPLODED!"); } // Configuration callback on TC void TC1_callback(void) { - // Finish the DMA cycle by shutting down the channel. - dma.Disable((MODDMA::CHANNELS)conf1->channelNum()); + dma_disable(); if (note_active()) { // Notify note.cpp that it is time to refill buffer[1] @@ -126,16 +127,15 @@ // Swap to buffer0 dma.Prepare( conf0 ); - - // Clear DMA IRQ flags. - if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); - } else { - dma.Disable((MODDMA::CHANNELS)conf0->channelNum()); } + // Clear DMA IRQ flags. + if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); } + // Configuration callback on Error void ERR1_callback(void) { + led3=1; error("Oh no! My Mbed EXPLODED!"); }
--- a/jswitch.cpp Sun Mar 13 01:12:40 2016 +0000 +++ b/jswitch.cpp Mon Mar 14 23:37:58 2016 +0000 @@ -51,7 +51,6 @@ js_official|=(js_now&js_old&js_older&js_oldest); if (js_official>0) { js_msec=js_timer.read_ms(); -// debug_hexbyte(js_official); } } else { js_now=0;
--- a/note.cpp Sun Mar 13 01:12:40 2016 +0000 +++ b/note.cpp Mon Mar 14 23:37:58 2016 +0000 @@ -12,7 +12,7 @@ #include "jswitch.h" #include "note.h" -DigitalOut led2(LED2); // lit during NOTE_RELEASE state +#define TURN_DMA_OFF_AFTER_EACH_NOTE 0 typedef enum {NOTE_ATTACK,NOTE_DECAY,NOTE_SUSTAIN,NOTE_RELEASE,NOTE_OFF} NOTE_STATE; @@ -60,15 +60,10 @@ wave_reset(); note_freq = touch_frequency(); note_attack_bufs=envlp_get_attack_bufs(); - debug_hexshort((short)note_attack_bufs); - debug_putch(' '); note_decay_bufs=envlp_get_decay_bufs(); note_release_delta = envlp_get_release_delta(); note_release_numerator = ENVLP_MAX - note_release_delta; note_release_denominator = ENVLP_MAX; - debug_hexshort((short)note_release_numerator); - debug_crlf(); - // fill first two buffers note_attack(); note_set_bufno(0); @@ -77,6 +72,7 @@ note_set_bufno(1); note_state_machine(); note_fill_buf(); + note_bufno=NIL; dma_enable(); } @@ -84,8 +80,7 @@ { dma_disable(); note_state=NOTE_OFF; - note_bufno=NIL; - led2 = 0; + note_bufno=NIL; } /* @@ -101,10 +96,8 @@ { // execute note state machine note_state_machine(); - - // if dma buffer sent, refill it if(note_bufno!=NIL) { - note_fill_buf(); + note_fill_buf(); } // handle presence or absence of touch @@ -167,21 +160,22 @@ void note_fill_buf(void) { int j,start_env,end_env,env_val,wave_val,buf_val,amplitude; - int *bufptr=NULL; + int *bufptr; bufptr = dma_get_bufptr(note_bufno); start_env = note_first_bufval; end_env = note_last_bufval; - amplitude = touch_amplitude(); + amplitude = touch_amplitude(); for (j=0;j<DMA_BUFSIZE;j++) { - env_val=start_env+(end_env - start_env)*j/DMA_BUFSIZE; - wave_val = wave_nextval(note_freq); - buf_val = wave_val * env_val / ENVLP_MAX; - buf_val=amplitude*buf_val/TOUCH_MAX_AMPLITUDE; - bufptr[j]= DAC_POWER_MODE | ((buf_val << 6) & 0xFFC0); + env_val=start_env+(end_env - start_env)*j/DMA_BUFSIZE; + wave_val = wave_nextval(note_freq); + buf_val = wave_val * env_val / ENVLP_MAX; + buf_val=amplitude*buf_val/TOUCH_MAX_AMPLITUDE; + bufptr[j]= DAC_POWER_MODE | ((buf_val << 6) & 0xFFC0); } - note_bufno = NIL; // buffer is filled + + note_bufno = NIL; switch (note_state) { case NOTE_ATTACK: note_attack_bufcount++; @@ -189,13 +183,15 @@ case NOTE_DECAY: note_decay_bufcount++; break; + case NOTE_SUSTAIN: + note_first_bufval = note_last_bufval; + break; case NOTE_RELEASE: note_first_bufval = note_last_bufval; note_last_bufval = note_first_bufval * note_release_numerator / note_release_denominator; break; - case NOTE_SUSTAIN: case NOTE_OFF: default: ; @@ -208,7 +204,6 @@ */ void note_release(void) { - led2 = 1; note_state = NOTE_RELEASE; } /*
--- a/touch.cpp Sun Mar 13 01:12:40 2016 +0000 +++ b/touch.cpp Mon Mar 14 23:37:58 2016 +0000 @@ -32,7 +32,7 @@ * */ -typedef enum {TOUCH_NOTOUCH,TOUCH_DEBOUNCE,TOUCH_PRESENT} TOUCH_STATE; +typedef enum {TOUCH_NOTOUCH,TOUCH_DEBOUNCE,NOTOUCH_DEBOUNCE,TOUCH_PRESENT} TOUCH_STATE; #define TSC_ADDR 0x82 // (i2c address for touchscreen)<<1 @@ -100,12 +100,13 @@ // GPIO_AF -- GPIO Alternate FunctionRegister #define GPIO_AF 0x17 - +DigitalOut led1(LED1); DigitalOut led4(LED4); i2c_t touch_ctrl; // i2c interface struct for touch screen -static bool touch_present(void); +static int touch_present(void); +static void touch_reset(void); static void touch_compute_params(void); static char tsc_reset[2]={SYS_CTRL1, SOFT_RESET}; @@ -137,10 +138,17 @@ // used by state machine that debounces touch detection TOUCH_STATE touch_state=TOUCH_NOTOUCH; -#define GOOD_TOUCH_COUNT 8 -#define NO_TOUCH_COUNT 8 +#define GOOD_TOUCH_COUNT 4 +#define NO_TOUCH_COUNT 4 + +bool touch_init(void) +{ + touch_reset(); + touch_state = TOUCH_NOTOUCH; + return true; +} -bool touch_init(void) +void touch_reset(void) { char chipid[2]; @@ -205,44 +213,55 @@ i2c_write(&touch_ctrl,TSC_ADDR,ena_intrupt,2,1); wait_ms(1); - - touch_state = TOUCH_NOTOUCH; - return true; } bool touch_debounce(void) { static int debounce_count=0; + int tret; + tret=touch_present(); switch (touch_state) { case TOUCH_NOTOUCH: - if (touch_present()) { + if (tret>0) { debounce_count=0; touch_state = TOUCH_DEBOUNCE; } break; case TOUCH_DEBOUNCE: - if (touch_present()) { + if (tret>0) { if (++debounce_count > GOOD_TOUCH_COUNT) { touch_state = TOUCH_PRESENT; + led1=1; } - } else { + } else if(tret == 0) { touch_state = TOUCH_NOTOUCH; } break; + + case NOTOUCH_DEBOUNCE: + if(tret>0) { + touch_state = TOUCH_PRESENT; + } else if(tret== 0) { + if(++debounce_count > NO_TOUCH_COUNT) { + debounce_count=0; + touch_state=TOUCH_NOTOUCH; + } + } + break; case TOUCH_PRESENT: - if (touch_present()) { + if (tret>0) { touch_compute_params(); - return true; - } else { - touch_state = TOUCH_NOTOUCH; + } else if(tret==0) { + debounce_count=0; + touch_state=NOTOUCH_DEBOUNCE; } break; } - return false; + return ((touch_state==TOUCH_PRESENT) || (touch_state==NOTOUCH_DEBOUNCE)); } int touch_frequency(void) @@ -257,33 +276,35 @@ void touch_compute_params(void) { if(0>touch_get_xy(&touch_x,&touch_y)) return; - touch_audio_freq = TOUCH_MIN_FREQUENCY + if((touch_y>0x3F) && (touch_y!=0xFFF)) { + touch_audio_freq = (TOUCH_MIN_FREQUENCY + (TOUCH_MAX_FREQUENCY - TOUCH_MIN_FREQUENCY) - * touch_y/0xFFF; - touch_audio_amplitude = TOUCH_MAX_AMPLITUDE*touch_x/0xFFF; -// debug_hexshort((short)touch_audio_freq); -// debug_putch(','); -// debug_hexshort((short)touch_audio_amplitude); -// debug_crlf(); + * touch_y)>>12; + } + if((touch_x > 0x3F) && (touch_x != 0xFFF)) { + touch_audio_amplitude = (TOUCH_MAX_AMPLITUDE*touch_x)>>12; + } } - -bool touch_present(void) +/* + * return 1 if touch present, 0 if touch absent, and -1 + * if there was an i2c error + */ +int touch_present(void) { - i2c_init(&touch_ctrl,p28,p27); // sync i2c routines - i2c_frequency(&touch_ctrl,100000); // 100kHz clock +// <<<<< i2c_init(&touch_ctrl,p28,p27); // sync i2c routines +// <<<<< i2c_frequency(&touch_ctrl,100000); // 100kHz clock i2c_write(&touch_ctrl,TSC_ADDR,&tsc_ctrl,1,0); i2c_read(&touch_ctrl,TSC_ADDR,&touch_status,1,1); - if ((touch_status & TSC_EN_MASK)==0) { // i2c error + if ((touch_status & TSC_EN_MASK)==0) { // i2c error led4=1; // disables screen - wait_ms(10); - touch_init(); // re-init fixes - return false; + touch_reset(); // re-init fixes + return -1; } else if ((touch_status & TSC_TOUCH_DET)>0) { - return true; + return 1; } - return false; + return 0; } int touch_get_xy(short *x,short *y) @@ -313,10 +334,10 @@ // 0xFFF or 0x000 is some kind of glitch if (*x==0xFFF && *y==0xFFF) return NIL; if (*x==0 && *y==0) return NIL; -// debug_hexshort(*x); -// debug_putch(','); -// debug_hexshort(*y); -// debug_crlf(); + debug_hexshort(*x); + debug_putch(','); + debug_hexshort(*y); + debug_crlf(); return 0; }
--- a/wave.cpp Sun Mar 13 01:12:40 2016 +0000 +++ b/wave.cpp Mon Mar 14 23:37:58 2016 +0000 @@ -78,7 +78,7 @@ delta_phi= 100000*freq/WAVE_SAMPLE_RATE; accum_phi = (accum_phi + delta_phi)%100000; - index = ((DMA_BUFSIZE - 1) * accum_phi)/100000; + index = (DMA_BUFSIZE * accum_phi)/100000; return waveform[wavetype][index]; }