This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

USART Handler getting overrun by TIM6_DAC handler?

We are making our DAC output a sinusoid of variable frequency depending on a button we press. The DAC does work when we hard code which button WE press but not with UART. With the UART handler (used for receiving the  "button" we press and incrementing it in software), the DAC handler is always running and never lets the UART handler start "pressing" the button so it never activates the DAC. We think that the handler is getting overrun by the TIM6_DAC because when we disable TIM6, the UART handler is initiated (but then there is not DAC conversion). We overcame the relatively slow speed of the ADC in the channel reads and the button presses are represented by the arrays and KEY#'s.

STM32F051R8T6

EDIT: DAC is set to trigger every 10us and the uart is set to interrupt whenever the receiver has a bit recieved

/*#include "stm32f0xx.h"
#include "stm32f0_discovery.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define RATE 100000
#define N 1000
#define PB_CH 0
#define ATTACK_CH 10
#define DECAY_CH 11
#define SUSTAIN_CH 12
#define RELEASE_CH 13
#define IDLE 0xFE
#define KEY1 0x34
#define KEY2 0x35
#define KEY3 0x36
#define KEY4 0x37
#define KEY5 0x38
#define KEY6 0x39
#define KEY7 0x3A
#define KEY8 0x3B
#define KEY9 0x3C
#define KEY10 0x3D
#define KEY11 0x3E
#define KEY12 0x3F
#define KEY13 0x40
#define KEY14 0x41
#define KEY15 0x42
#define KEY16 0x43
#define KEY17 0x44
#define KEY18 0x45
#define KEY19 0x46
#define KEY20 0x47
#define KEY21 0x48
#define KEY22 0x49
#define KEY23 0x4A
#define KEY24 0x4B
#define KEY25 0x4C

extern const short int wavetable[N];

int ADSR[25] = {0};
int counter[25] = {0};
int keys[25] = {KEY1,KEY2,KEY3,KEY4,KEY5,KEY6,KEY7,KEY8,KEY9,KEY10,KEY11,KEY12,KEY13,KEY14,KEY15,KEY16,KEY17,KEY18,KEY19,KEY20,KEY21,KEY22,KEY23,KEY24,KEY25};
int pressed[25] = {0};
int offset[25] = {0};
int step[25] = { (261.626 * 2.191) * N / RATE * (1<<16), //C4
                 (277.183 * 2.191) * N / RATE * (1<<16), //C#4
                 (293.665 * 2.191) * N / RATE * (1<<16), //D4
                 (311.127 * 2.191) * N / RATE * (1<<16), //D#4
                 (329.628 * 2.191) * N / RATE * (1<<16), //E4
                 (349.228 * 2.191) * N / RATE * (1<<16), //F4
                 (369.994 * 2.191) * N / RATE * (1<<16), //F#4
                 (391.995 * 2.191) * N / RATE * (1<<16), //G4
                 (415.305 * 2.191) * N / RATE * (1<<16), //G#4
                 (440.000 * 2.191) * N / RATE * (1<<16), //A4
                 (466.164 * 2.191) * N / RATE * (1<<16), //A#4
                 (493.883 * 2.191) * N / RATE * (1<<16), //B4
                 (523.251 * 2.191) * N / RATE * (1<<16), //C5
                 (554.365 * 2.191) * N / RATE * (1<<16), //C#5
                 (587.330 * 2.191) * N / RATE * (1<<16), //D5
                 (622.254 * 2.191) * N / RATE * (1<<16), //D#5
                 (659.255 * 2.191) * N / RATE * (1<<16), //E5
                 (698.456 * 2.191) * N / RATE * (1<<16), //F5
                 (739.989 * 2.191) * N / RATE * (1<<16), //F#5
                 (783.991 * 2.191) * N / RATE * (1<<16), //G5
                 (830.609 * 2.191) * N / RATE * (1<<16), //G#5
                 (880.000 * 2.191) * N / RATE * (1<<16), //A5
                 (932.328 * 2.191) * N / RATE * (1<<16), //A#5
                 (987.767 * 2.191) * N / RATE * (1<<16), //B5
                 (1046.502 * 2.191) * N / RATE * (1<<16), //C6
                 };
int attack_var = 0;
int decay_var = 0;
int sustain_var = 0;
int release_var = 0;
int PB = 0;
uint32_t note = 0;
uint32_t midiData = 0;

void setup_gpio() {
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
    RCC->AHBENR |= RCC_AHBENR_GPIOCEN;
    GPIOA->MODER |= 0x3;
    GPIOC->MODER |= 0xFF;
}

void setup_dac() {
    RCC->APB1ENR |= RCC_APB1ENR_DACEN;
    DAC->CR &= ~DAC_CR_EN1;
    DAC->CR &= ~DAC_CR_BOFF1;
    DAC->CR |= DAC_CR_TSEL1;
    DAC->CR |= DAC_CR_TEN1;
    DAC->CR |= DAC_CR_EN1;
}

void uart_init(void){
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
    GPIOA->MODER &= ~GPIO_MODER_MODER9 | GPIO_MODER_MODER10;
    GPIOA->MODER |= GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1;
    GPIOA->AFR[1] &= ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2);
    GPIOA->AFR[1] |= 1<<8 | 1<<4;

    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
    USART1->CR1 &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE);
    USART1->CR1 &= ~(1<<28);
    USART1->CR1 &= ~(1<<12);
    USART1->CR2 &= ~USART_CR2_STOP;
    USART1->CR1 &= ~USART_CR1_PCE;
    USART1->CR1 &= ~USART_CR1_OVER8;
    USART1->BRR |= 0x600;       //Baud 31250
    USART1->CR1 |= USART_CR1_RXNEIE;
    NVIC->ISER[0] = 1 <<(USART1_IRQn);

//    NVIC_SetPriority(USART1_IRQn, 0);


    USART1->CR1 |= USART_CR1_UE | USART_CR1_RE |USART_CR1_TE;
    while(!USART1->ISR && (USART_ISR_REACK | USART_ISR_TEACK));

}

void setup_timer6() {
    RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
    TIM6->ARR = 48-1;
    TIM6->PSC = 10-1;
    TIM6->DIER |= TIM_DIER_UIE;
    TIM6->CR1 |= TIM_CR1_CEN;
    NVIC->ISER[0] |= 1 << TIM6_DAC_IRQn;


}

void setup_timer3() {
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
    TIM3->ARR = 9600-1;
    TIM3->PSC = 10-1;
    TIM3->DIER |= TIM_DIER_UIE;
    TIM3->CR1 |= TIM_CR1_CEN;
    NVIC->ISER[0] |= 1 << TIM3_IRQn;
}

void setup_adc() {
    RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
    RCC->CR2 |= RCC_CR2_HSI14ON;
    while(!(RCC->CR2 & RCC_CR2_HSI14RDY));
    ADC1->CR |= ADC_CR_ADEN;
    while(!(ADC1->ISR & ADC_ISR_ADRDY));
    while((ADC1->CR & ADC_CR_ADSTART));
}

int read_adc_channel(unsigned int channel) {
    ADC1->CHSELR = 0;
    ADC1->CHSELR = 1 << channel;
    while(!(ADC1->ISR & ADC_ISR_ADRDY));
    ADC1->CR |= ADC_CR_ADSTART;
    while(!(ADC1->ISR & ADC_ISR_EOC));
    int val = ADC1->DR;
    return val;
}

void USART1_IRQHandler() {
    int u;
    midiData = USART1->RDR;
    if (midiData == 0xFE) {
        return;
    }
    if (midiData != 0xFE) {
        while(!(USART1->ISR & USART_ISR_RXNE));
        note = USART1->RDR;
        USART1->TDR = note;
        for (u = 0; u < 25; u++) {
            if (note == keys[u]) {
                if (pressed[u] == 0 || pressed[u] == 2){
                    pressed[u] = 1;
                    counter[u] = 0;
                }
                else {
                    pressed[u] = 2;
                    counter[u] = 0;
                }
            }
        }
    }
    note = 0;
    return;
}

void TIM6_DAC_IRQHandler() {                    //handles dac conversion
//void DMA1_Channel2_3_IRQHandler() {
//    DMA1->IFCR |= DMA_IFCR_CTCIF3;
    int x;
    int sample = 0;
    TIM6->SR &= ~TIM_SR_UIF;
    //DAC->SWTRIGR |= DAC_SWTRIGR_SWTRIG1;

    pressed[6] = 1;
    for(x=0; x<25; x++) {

        if (pressed[x]>0) {
            int i = x;//; + PB;
            if (i < 0)
                i = 0;
            if (i > 24)
                i = 24;
            offset[x] += step[i];
            if (offset[x] >= N<<16)
                offset[x] -= N<<16;

            counter[x]++;
            sample += wavetable[offset[x]>>16];

            /*
            if (pressed[x] == 2){        //release  //on release pressed[x] = 2, counter[x] = 0
                ADSR[x] = sustain_var - (sustain_var * counter[x]/(release_var * 25));
                if (counter[x] <= release_var * 25){
                    ADSR[x] = 0;
                    pressed[x] = 0;
                }
            }
            else if (counter[x] < attack_var * 25)       //attack
                ADSR[x] = ((4095 * counter[x]) / (attack_var * 25));
            else if (counter[x] >= attack_var * 25 && counter[x] < (decay_var * 25 + attack_var * 25))  //decay
                ADSR[x] = 4095 - (4095-sustain_var)*(counter[x]-attack_var * 25)/(decay_var * 25);
            else if (counter[x] >= (decay_var * 25 + attack_var * 25))     //sustain
                ADSR[x] = (sustain_var * 1);


            sample += ADSR[x] * wavetable[offset[x]>>16];

        }
    }
    sample = sample / 32 + 2048;
    if (sample > 4095) sample = 4095;
    else if (sample < 0) sample = 0;
    DAC->DHR12R1 = sample;
    DAC->SWTRIGR |= DAC_SWTRIGR_SWTRIG1;
    return;
}

void TIM3_IRQHandler() {
    attack_var = read_adc_channel(ATTACK_CH);
    decay_var = read_adc_channel(DECAY_CH);
    sustain_var = read_adc_channel(SUSTAIN_CH);
    release_var = read_adc_channel(RELEASE_CH);

    PB = read_adc_channel(PB_CH);
    if (PB < 2303 && PB > 1793)
            PB = 0;
    else if (PB <= 1793)
        PB = (2048-PB) * -1;
    else
        PB = PB - 1793;
    PB = PB/512;



    TIM3->SR &= ~TIM_SR_UIF;
    return;
}

void setup_dma() {
    RCC->AHBENR |= RCC_AHBENR_DMA1EN;
    DMA1_Channel3->CCR &= ~DMA_CCR_EN;
    DMA1_Channel3->CMAR = (uint32_t *) wavetable;
    DMA1_Channel3->CPAR = DAC->DHR12R1;
    DMA1_Channel3->CNDTR = sizeof(wavetable)/sizeof(wavetable[0]);
    DMA1_Channel3->CCR |= DMA_CCR_DIR;
    DMA1_Channel3->CCR |= DMA_CCR_TCIE;
    DMA1_Channel3->CCR &= ~DMA_CCR_HTIE;
    DMA1_Channel3->CCR &= ~DMA_CCR_MSIZE;            //8 BITS
    DMA1_Channel3->CCR &= ~DMA_CCR_PSIZE;            //8 BITS
    DMA1_Channel3->CCR |= DMA_CCR_CIRC;
    DMA1_Channel3->CCR |= DMA_CCR_MINC;

    DMA1_Channel3->CCR |= DMA_CCR_PL;
    DMA1_Channel3->CCR &= ~DMA_CCR_MEM2MEM;
    NVIC->ISER[0] = 1 << DMA1_Channel1_IRQn;
    DMA1_Channel3->CCR |= DMA_CCR_EN;

}

int main(void)
{
    init_wavetable();
    setup_gpio();
    setup_dac();
//    setup_adc();
//    setup_dma();
//    setup_timer3();
    setup_timer6();
//    uart_init();
    for(;;) {
    }

    while(1) asm("wfi");

}
*/

#include "stm32f0xx.h"
#include "stm32f0_discovery.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define RATE 100000
#define N 1000
#define PB_CH 0
#define ATTACK_CH 10
#define DECAY_CH 11
#define SUSTAIN_CH 12
#define RELEASE_CH 13
#define IDLE 0xFE
#define KEY1 0x34
#define KEY2 0x35
#define KEY3 0x36
#define KEY4 0x37
#define KEY5 0x38
#define KEY6 0x39
#define KEY7 0x3A
#define KEY8 0x3B
#define KEY9 0x3C
#define KEY10 0x3D
#define KEY11 0x3E
#define KEY12 0x3F
#define KEY13 0x40
#define KEY14 0x41
#define KEY15 0x42
#define KEY16 0x43
#define KEY17 0x44
#define KEY18 0x45
#define KEY19 0x46
#define KEY20 0x47
#define KEY21 0x48
#define KEY22 0x49
#define KEY23 0x4A
#define KEY24 0x4B
#define KEY25 0x4C

extern const short int wavetable[N];

int ADSR[25] = {0};
int counter[25] = {0};
int keys[25] = {KEY1,KEY2,KEY3,KEY4,KEY5,KEY6,KEY7,KEY8,KEY9,KEY10,KEY11,KEY12,KEY13,KEY14,KEY15,KEY16,KEY17,KEY18,KEY19,KEY20,KEY21,KEY22,KEY23,KEY24,KEY25};
int pressed[25] = {1,0};
int offset[25] = {0};
int step[25] = { (261.626 * 2.191) * N / RATE * (1<<16), //C4
                 (277.183 * 2.191) * N / RATE * (1<<16), //C#4
                 (293.665 * 2.191) * N / RATE * (1<<16), //D4
                 (311.127 * 2.191) * N / RATE * (1<<16), //D#4
                 (329.628 * 2.191) * N / RATE * (1<<16), //E4
                 (349.228 * 2.191) * N / RATE * (1<<16), //F4
                 (369.994 * 2.191) * N / RATE * (1<<16), //F#4
                 (391.995 * 2.191) * N / RATE * (1<<16), //G4
                 (415.305 * 2.191) * N / RATE * (1<<16), //G#4
                 (440.000 * 2.191) * N / RATE * (1<<16), //A4
                 (466.164 * 2.191) * N / RATE * (1<<16), //A#4
                 (493.883 * 2.191) * N / RATE * (1<<16), //B4
                 (523.251 * 2.191) * N / RATE * (1<<16), //C5
                 (554.365 * 2.191) * N / RATE * (1<<16), //C#5
                 (587.330 * 2.191) * N / RATE * (1<<16), //D5
                 (622.254 * 2.191) * N / RATE * (1<<16), //D#5
                 (659.255 * 2.191) * N / RATE * (1<<16), //E5
                 (698.456 * 2.191) * N / RATE * (1<<16), //F5
                 (739.989 * 2.191) * N / RATE * (1<<16), //F#5
                 (783.991 * 2.191) * N / RATE * (1<<16), //G5
                 (830.609 * 2.191) * N / RATE * (1<<16), //G#5
                 (880.000 * 2.191) * N / RATE * (1<<16), //A5
                 (932.328 * 2.191) * N / RATE * (1<<16), //A#5
                 (987.767 * 2.191) * N / RATE * (1<<16), //B5
                 (1046.502 * 2.191) * N / RATE * (1<<16), //C6
                 };
int attack_var = 0;
int decay_var = 0;
int sustain_var = 0;
int release_var = 0;
int PB = 0;
uint32_t note = 0;
uint32_t midiData = 0;

void setup_gpio() {
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
    RCC->AHBENR |= RCC_AHBENR_GPIOCEN;
    GPIOA->MODER |= 0x3;
    GPIOC->MODER |= 0xFF;
}

void setup_dac() {
    RCC->APB1ENR |= RCC_APB1ENR_DACEN;
    DAC->CR &= ~DAC_CR_EN1;
    DAC->CR &= ~DAC_CR_BOFF1;
    DAC->CR |= DAC_CR_TEN1;
    DAC->CR |= DAC_CR_TSEL1;
    DAC->CR |= DAC_CR_DMAEN1;
    DAC->CR |= DAC_CR_EN1;
}

void uart_init(void){
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
    GPIOA->MODER &= ~GPIO_MODER_MODER9 | GPIO_MODER_MODER10;
    GPIOA->MODER |= GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1;
    GPIOA->AFR[1] &= ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2);
    GPIOA->AFR[1] |= 1<<8 | 1<<4;

    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
    USART1->CR1 &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE);
    USART1->CR1 &= ~(1<<28);
    USART1->CR1 &= ~(1<<12);
    USART1->CR2 &= ~USART_CR2_STOP;
    USART1->CR1 &= ~USART_CR1_PCE;
    USART1->CR1 &= ~USART_CR1_OVER8;
    USART1->BRR |= 0x600;       //Baud 31250
    USART1->CR1 |= USART_CR1_RXNEIE;
    NVIC->ISER[0] = 1 <<(USART1_IRQn);

    NVIC_SetPriority(USART1_IRQn, 0);


    USART1->CR1 |= USART_CR1_UE | USART_CR1_RE |USART_CR1_TE;
    while(!USART1->ISR && (USART_ISR_REACK | USART_ISR_TEACK));

}

void setup_timer6() {
    RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
    TIM6->ARR = 48-1;
    TIM6->PSC = 10-1;
    TIM6->DIER |= TIM_DIER_UIE;
    TIM6->CR1 |= TIM_CR1_CEN;
    NVIC->ISER[0] |= 1 << TIM6_DAC_IRQn;

    NVIC_SetPriority(TIM6_DAC_IRQn, 1);


}

void setup_timer3() {
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
    TIM3->ARR = 9600-1;
    TIM3->PSC = 10-1;
    TIM3->DIER |= TIM_DIER_UIE;
    TIM3->CR1 |= TIM_CR1_CEN;
    NVIC->ISER[0] |= 1 << TIM3_IRQn;
}

void setup_adc() {
    RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
    RCC->CR2 |= RCC_CR2_HSI14ON;
    while(!(RCC->CR2 & RCC_CR2_HSI14RDY));
    ADC1->CR |= ADC_CR_ADEN;
    while(!(ADC1->ISR & ADC_ISR_ADRDY));
    while((ADC1->CR & ADC_CR_ADSTART));
}

int read_adc_channel(unsigned int channel) {
    ADC1->CHSELR = 0;
    ADC1->CHSELR = 1 << channel;
    while(!(ADC1->ISR & ADC_ISR_ADRDY));
    ADC1->CR |= ADC_CR_ADSTART;
    while(!(ADC1->ISR & ADC_ISR_EOC));
    int val = ADC1->DR;
    return val;
}

void USART1_IRQHandler() {
    //USART1->TDR = 0xAA;
    
    int u;
    midiData = USART1->RDR;
    if (midiData == 0x90 || midiData == 0x80) {
        while(!(USART1->ISR & USART_ISR_RXNE));
        note = USART1->RDR;
        USART1->TDR = note;
        for (u = 0; u < 25; u++) {
            if (note == keys[u]) {
                if (pressed[u] == 0 || pressed[u] == 2){
                    pressed[u] = 1;
                    counter[u] = 0;
                }
                else {
                    pressed[u] = 2;
                    counter[u] = 0;
                }
            }
        }
    }
    note = 0;
    midiData = 0;*/
    return;
}

void TIM6_DAC_IRQHandler() {                    //handles dac conversion
    int x;
    int sample = 0;
    DAC->SWTRIGR |= DAC_SWTRIGR_SWTRIG1;
    TIM6->SR &= ~TIM_SR_UIF;

    int u;
    midiData = USART1->RDR;
    if (midiData == 0x90 || midiData == 0x80) {
        while(!(USART1->ISR & USART_ISR_RXNE));
        note = USART1->RDR;
        USART1->TDR = note;
        for (u = 0; u < 25; u++) {
            if (note == keys[u]) {
                if (pressed[u] == 0 || pressed[u] == 2){
                    pressed[u] = 1;
                    counter[u] = 0;
                }
                else {
                    pressed[u] = 2;
                    counter[u] = 0;
                }
            }
        }
    }
    note = 0;
    midiData = 0;


    //pressed[24] = 1;
    for(x=0; x<25; x++) {

        if (pressed[x]>0) {
            int i = x + PB;
            if (i < 0)
                i = 0;
            if (i > 24)
                i = 24;
            offset[x] += step[i];
            if (offset[x] >= N<<16)
                offset[x] -= N<<16;

            counter[x]++;
            if (pressed[x] == 2){        //release  //on release pressed[x] = 2, counter[x] = 0
                ADSR[x] = sustain_var - (sustain_var * counter[x]/(release_var * 25));
                if (counter[x] <= release_var * 25){
                    ADSR[x] = 0;
                    pressed[x] = 0;
                }
            }
            else if (counter[x] < attack_var * 25)       //attack
                ADSR[x] = ((4095 * counter[x]) / (attack_var * 25));
            else if (counter[x] >= attack_var * 25 && counter[x] < (decay_var * 25 + attack_var * 25))  //decay
                ADSR[x] = 4095 - (4095-sustain_var)*(counter[x]-attack_var * 25)/(decay_var * 25);
            else if (counter[x] >= (decay_var * 25 + attack_var * 25))     //sustain
                ADSR[x] = (sustain_var * 1);


            sample += ADSR[x] * wavetable[offset[x]>>16];

        }
    }
    sample = sample / 32 + 2048;
    if (sample > 4095) sample = 4095;
    else if (sample < 0) sample = 0;
    DAC->DHR12R1 = sample;
    return;
}

void TIM3_IRQHandler() {
    attack_var = read_adc_channel(ATTACK_CH);
    decay_var = read_adc_channel(DECAY_CH);
    sustain_var = read_adc_channel(SUSTAIN_CH);
    release_var = read_adc_channel(RELEASE_CH);

    PB = read_adc_channel(PB_CH);
    if (PB < 2303 && PB > 1793)
            PB = 0;
    else if (PB <= 1793)
        PB = (2048-PB) * -1;
    else
        PB = PB - 1793;
    PB = PB/512;

    TIM3->SR &= ~TIM_SR_UIF;
    return;
}


int main(void)
{
    init_wavetable();
    setup_gpio();
    setup_dac();
    setup_adc();
    uart_init();
    setup_timer3();
    setup_timer6();
    for(;;) {
    }

    while(1) asm("wfi");

}