multithreading example

Dependencies:   FastAnalogIn

main.cpp

Committer:
candre97
Date:
2019-12-02
Revision:
111:f6bf8ca71128
Parent:
110:037667235b6d
Child:
112:a0fd359ec3a6

File content as of revision 111:f6bf8ca71128:

/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"
#include "platform/mbed_thread.h"
#include "stats_report.h"
#include <AnalogIn.h>
#include <AnalogOut.h>
#include "circ_buff.hpp"


AnalogOut v_src(GPIO0);
AnalogIn therm(GPIO2);

#define SLEEP_TIME                  500 // (msec)
#define PRINT_AFTER_N_LOOPS         20

//define defaults for mfcc
#define DEF_NUMCEPSTRA      12
#define DEF_NUMFILTERS      40
#define DEF_SAMPLINGRATE    16000
#define DEF_WINLENGTH       25
#define DEF_FRAMESHIFT      10
#define DEF_LOWFREQ         50
#define DEF_HIGHFREQ        DEF_SAMPLINGRATE/2
#define WINDOW_SIZE         DEF_WINLENGTH - DEF_FRAMESHIFT
#define ARRAY_SIZE          800
 
#define BUFFSIZE                    1760 // size of buffer = sampling_time * sampling_rate * size(float)
//DigitalOut led1(LED1);
//DigitalOut led2(LED2);
Thread thread_adc;
Thread thread_mfcc;

// PIN DEFINITIONS
DigitalOut vcc(GPIO0);
AnalogIn mic(PB_0);
CircularBuff<uint16_t> buff(BUFFSIZE);


int num_readings = 0;
int z = 0;
uint16_t raw_adc = 0; 
uint16_t* pop_val;

void adc_thread() {
    while (true) {
        for (;;) {                            /* Loop forever                       */
            if (ADC1->SR & (1 << 1)) {          /* If conversion has finished         */
              raw_adc = ADC1->DR & 0x0FFF;       /* Read AD converted value            */
              ADC1->CR2 |= 1 << 22;             /* Start new conversion               */ 
            }
            buff.push(raw_adc);
            num_readings++;
        }
        
    }
}

//To sleep, 'wait' should be replaced by 'ThisThread::sleep_for' (C++) or 'thread_sleep_for' (C). If you wish to wait (without sleeping), call 'wait_us'. 'wait_us' is safe to call from ISR context. [since mbed-os-5.14] [-Wdeprecated-declarations] in "main.cpp", Line: 59, Col: 9

/* 
    this thread is in charge of converting 
*/
void mfcc_thread() {
    while (true) {
        //printf("Top of MFCC thread");
        thread_sleep_for(2000);
        printf("Readings / second: %i\n\n", num_readings/2);
        num_readings = 0;
        pop_val = buff.pop();
        printf("last reading: %u\n", *pop_val);
        buff.clear();
    }
}

/* 
The following sequence should be followed to configure a DMA channelx (where x is the
channel number).
1. Set the peripheral register address in the DMA_CPARx register. The data will be
moved from/ to this address to/ from the memory after the peripheral event.
2. Set the memory address in the DMA_CMARx register. The data will be written to or
read from this memory after the peripheral event.
3. Configure the total number of data to be transferred in the DMA_CNDTRx register.
After each peripheral event, this value will be decremented.
4. Configure the channel priority using the PL[1:0] bits in the DMA_CCRx register
5. Configure data transfer direction, circular mode, peripheral & memory incremented
mode, peripheral & memory data size, and interrupt after half and/or full transfer in the
DMA_CCRx register
6. Activate the channel by setting the ENABLE bit in the DMA_CCRx register
*/

void config_dma() {
    /* 
    1. Set the peripheral register address in the DMA_CPARx register. The data will be
    moved from/ to this address to/ from the memory after the peripheral event.
    */
    //RCC->DMA_CPAR1 &= 0x00000000;
}







int main() {
    config_dma();
    printf("configuring DMA\n");
    
    printf("Creating buff of size %d\n", BUFFSIZE);
    /* clear the buffer */
    buff.clear();
    printf("library read val: %u\n", mic.read_u16());
    
    /* Setup and initialize ADC converter                                       */
    RCC->APB2RSTR |=  1 <<  9;             /* Enable ADC1 clock                  */
    GPIOA->CRL   &= 0xFFF0FFFF;           /* Configure PC4 as ADC.14 input      */
    ADC1->SQR1    = 0x00000000;           /* Regular channel 1 conversion       */
    ADC1->SQR2    = 0x00000000;           /* Clear register                     */
    ADC1->SQR3    = 14 <<  0;             /* SQ1 = channel 14                   */
    ADC1->SMPR1   =  5 << 12;             /* Channel 14 sample time is 55.5 cyc */
    ADC1->SMPR2   = 0x00000000;           /* Clear register                     */
    ADC1->CR1     =  1 <<  8;             /* Scan mode on                       */
    ADC1->CR2     = (1 << 20) |           /* Enable external trigger            */
                  (7 << 17) |           /* EXTSEL = SWSTART                   */
                  (1 <<  1) |           /* Continuous conversion              */
                  (1 <<  0) ;           /* ADC enable                         */
    ADC1->CR2    |=  1 <<  3;             /* Initialize calibration registers   */
    while (ADC1->CR2 & (1 << 3));         /* Wait for initialization to finish  */
    ADC1->CR2    |=  1 <<  2;             /* Start calibration                  */
    while (ADC1->CR2 & (1 << 2));         /* Wait for calibration to finish     */
    ADC1->CR2    |=  1 << 22;             /* Start first conversion  */
    
    for (;;) {                            /* Loop forever                       */
        if (ADC1->SR & (1 << 1)) {          /* If conversion has finished         */
          raw_adc = ADC1->DR & 0x0FFF;       /* Read AD converted value            */
          ADC1->CR2 |= 1 << 22;             /* Start new conversion               */ 
        }
        printf("register read val: %u\n", raw_adc);
        thread_sleep_for(2000);
    }
    
    
    
    while(1);
    thread_adc.start(adc_thread);
    thread_mfcc.start(mfcc_thread);
}