Charles Andre
/
multithread
multithreading example
main.cpp@112:a0fd359ec3a6, 2019-12-02 (annotated)
- Committer:
- candre97
- Date:
- Mon Dec 02 06:12:17 2019 +0000
- Revision:
- 112:a0fd359ec3a6
- Parent:
- 111:f6bf8ca71128
- Child:
- 113:233a2fac1911
added link
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mbed_official | 82:abf1b1785bd7 | 1 | /* mbed Microcontroller Library |
mbed_official | 82:abf1b1785bd7 | 2 | * Copyright (c) 2018 ARM Limited |
mbed_official | 82:abf1b1785bd7 | 3 | * SPDX-License-Identifier: Apache-2.0 |
mbed_official | 82:abf1b1785bd7 | 4 | */ |
mbed_official | 82:abf1b1785bd7 | 5 | |
Jonathan Austin |
0:2757d7abb7d9 | 6 | #include "mbed.h" |
mbed_official | 100:ec006d6f3cb6 | 7 | #include "platform/mbed_thread.h" |
mbed_official | 82:abf1b1785bd7 | 8 | #include "stats_report.h" |
candre97 | 102:14fd65f261a2 | 9 | #include <AnalogIn.h> |
candre97 | 102:14fd65f261a2 | 10 | #include <AnalogOut.h> |
candre97 | 109:1d95a4596fb5 | 11 | #include "circ_buff.hpp" |
Jonathan Austin |
0:2757d7abb7d9 | 12 | |
candre97 | 111:f6bf8ca71128 | 13 | |
candre97 | 102:14fd65f261a2 | 14 | AnalogOut v_src(GPIO0); |
candre97 | 102:14fd65f261a2 | 15 | AnalogIn therm(GPIO2); |
Jonathan Austin |
0:2757d7abb7d9 | 16 | |
mbed_official | 88:bea4f2daa48c | 17 | #define SLEEP_TIME 500 // (msec) |
mbed_official | 88:bea4f2daa48c | 18 | #define PRINT_AFTER_N_LOOPS 20 |
mbed_official | 88:bea4f2daa48c | 19 | |
candre97 | 110:037667235b6d | 20 | //define defaults for mfcc |
candre97 | 110:037667235b6d | 21 | #define DEF_NUMCEPSTRA 12 |
candre97 | 110:037667235b6d | 22 | #define DEF_NUMFILTERS 40 |
candre97 | 110:037667235b6d | 23 | #define DEF_SAMPLINGRATE 16000 |
candre97 | 110:037667235b6d | 24 | #define DEF_WINLENGTH 25 |
candre97 | 110:037667235b6d | 25 | #define DEF_FRAMESHIFT 10 |
candre97 | 110:037667235b6d | 26 | #define DEF_LOWFREQ 50 |
candre97 | 110:037667235b6d | 27 | #define DEF_HIGHFREQ DEF_SAMPLINGRATE/2 |
candre97 | 110:037667235b6d | 28 | #define WINDOW_SIZE DEF_WINLENGTH - DEF_FRAMESHIFT |
candre97 | 110:037667235b6d | 29 | #define ARRAY_SIZE 800 |
candre97 | 102:14fd65f261a2 | 30 | |
candre97 | 111:f6bf8ca71128 | 31 | #define BUFFSIZE 1760 // size of buffer = sampling_time * sampling_rate * size(float) |
candre97 | 109:1d95a4596fb5 | 32 | //DigitalOut led1(LED1); |
candre97 | 109:1d95a4596fb5 | 33 | //DigitalOut led2(LED2); |
candre97 | 109:1d95a4596fb5 | 34 | Thread thread_adc; |
candre97 | 110:037667235b6d | 35 | Thread thread_mfcc; |
candre97 | 109:1d95a4596fb5 | 36 | |
candre97 | 110:037667235b6d | 37 | // PIN DEFINITIONS |
candre97 | 110:037667235b6d | 38 | DigitalOut vcc(GPIO0); |
candre97 | 110:037667235b6d | 39 | AnalogIn mic(PB_0); |
candre97 | 110:037667235b6d | 40 | CircularBuff<uint16_t> buff(BUFFSIZE); |
candre97 | 110:037667235b6d | 41 | |
candre97 | 111:f6bf8ca71128 | 42 | |
candre97 | 110:037667235b6d | 43 | int num_readings = 0; |
candre97 | 111:f6bf8ca71128 | 44 | int z = 0; |
candre97 | 111:f6bf8ca71128 | 45 | uint16_t raw_adc = 0; |
candre97 | 111:f6bf8ca71128 | 46 | uint16_t* pop_val; |
candre97 | 111:f6bf8ca71128 | 47 | |
candre97 | 109:1d95a4596fb5 | 48 | void adc_thread() { |
Jonathan Austin |
0:2757d7abb7d9 | 49 | while (true) { |
candre97 | 111:f6bf8ca71128 | 50 | for (;;) { /* Loop forever */ |
candre97 | 111:f6bf8ca71128 | 51 | if (ADC1->SR & (1 << 1)) { /* If conversion has finished */ |
candre97 | 111:f6bf8ca71128 | 52 | raw_adc = ADC1->DR & 0x0FFF; /* Read AD converted value */ |
candre97 | 111:f6bf8ca71128 | 53 | ADC1->CR2 |= 1 << 22; /* Start new conversion */ |
candre97 | 111:f6bf8ca71128 | 54 | } |
candre97 | 111:f6bf8ca71128 | 55 | buff.push(raw_adc); |
candre97 | 111:f6bf8ca71128 | 56 | num_readings++; |
candre97 | 111:f6bf8ca71128 | 57 | } |
candre97 | 111:f6bf8ca71128 | 58 | |
Jonathan Austin |
0:2757d7abb7d9 | 59 | } |
Jonathan Austin |
0:2757d7abb7d9 | 60 | } |
candre97 | 103:2da5fc276330 | 61 | |
candre97 | 111:f6bf8ca71128 | 62 | //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 |
candre97 | 111:f6bf8ca71128 | 63 | |
candre97 | 109:1d95a4596fb5 | 64 | /* |
candre97 | 109:1d95a4596fb5 | 65 | this thread is in charge of converting |
candre97 | 109:1d95a4596fb5 | 66 | */ |
candre97 | 109:1d95a4596fb5 | 67 | void mfcc_thread() { |
candre97 | 102:14fd65f261a2 | 68 | while (true) { |
candre97 | 110:037667235b6d | 69 | //printf("Top of MFCC thread"); |
candre97 | 111:f6bf8ca71128 | 70 | thread_sleep_for(2000); |
candre97 | 111:f6bf8ca71128 | 71 | printf("Readings / second: %i\n\n", num_readings/2); |
candre97 | 110:037667235b6d | 72 | num_readings = 0; |
candre97 | 111:f6bf8ca71128 | 73 | pop_val = buff.pop(); |
candre97 | 111:f6bf8ca71128 | 74 | printf("last reading: %u\n", *pop_val); |
candre97 | 111:f6bf8ca71128 | 75 | buff.clear(); |
candre97 | 102:14fd65f261a2 | 76 | } |
candre97 | 102:14fd65f261a2 | 77 | } |
candre97 | 102:14fd65f261a2 | 78 | |
candre97 | 111:f6bf8ca71128 | 79 | /* |
candre97 | 111:f6bf8ca71128 | 80 | The following sequence should be followed to configure a DMA channelx (where x is the |
candre97 | 111:f6bf8ca71128 | 81 | channel number). |
candre97 | 111:f6bf8ca71128 | 82 | 1. Set the peripheral register address in the DMA_CPARx register. The data will be |
candre97 | 111:f6bf8ca71128 | 83 | moved from/ to this address to/ from the memory after the peripheral event. |
candre97 | 111:f6bf8ca71128 | 84 | 2. Set the memory address in the DMA_CMARx register. The data will be written to or |
candre97 | 111:f6bf8ca71128 | 85 | read from this memory after the peripheral event. |
candre97 | 111:f6bf8ca71128 | 86 | 3. Configure the total number of data to be transferred in the DMA_CNDTRx register. |
candre97 | 111:f6bf8ca71128 | 87 | After each peripheral event, this value will be decremented. |
candre97 | 111:f6bf8ca71128 | 88 | 4. Configure the channel priority using the PL[1:0] bits in the DMA_CCRx register |
candre97 | 111:f6bf8ca71128 | 89 | 5. Configure data transfer direction, circular mode, peripheral & memory incremented |
candre97 | 111:f6bf8ca71128 | 90 | mode, peripheral & memory data size, and interrupt after half and/or full transfer in the |
candre97 | 111:f6bf8ca71128 | 91 | DMA_CCRx register |
candre97 | 111:f6bf8ca71128 | 92 | 6. Activate the channel by setting the ENABLE bit in the DMA_CCRx register |
candre97 | 111:f6bf8ca71128 | 93 | */ |
candre97 | 111:f6bf8ca71128 | 94 | |
candre97 | 111:f6bf8ca71128 | 95 | void config_dma() { |
candre97 | 111:f6bf8ca71128 | 96 | /* |
candre97 | 111:f6bf8ca71128 | 97 | 1. Set the peripheral register address in the DMA_CPARx register. The data will be |
candre97 | 111:f6bf8ca71128 | 98 | moved from/ to this address to/ from the memory after the peripheral event. |
candre97 | 111:f6bf8ca71128 | 99 | */ |
candre97 | 111:f6bf8ca71128 | 100 | //RCC->DMA_CPAR1 &= 0x00000000; |
candre97 | 111:f6bf8ca71128 | 101 | } |
candre97 | 111:f6bf8ca71128 | 102 | |
candre97 | 111:f6bf8ca71128 | 103 | |
candre97 | 111:f6bf8ca71128 | 104 | |
candre97 | 111:f6bf8ca71128 | 105 | |
candre97 | 111:f6bf8ca71128 | 106 | |
candre97 | 111:f6bf8ca71128 | 107 | |
candre97 | 111:f6bf8ca71128 | 108 | |
candre97 | 102:14fd65f261a2 | 109 | int main() { |
candre97 | 111:f6bf8ca71128 | 110 | config_dma(); |
candre97 | 111:f6bf8ca71128 | 111 | printf("configuring DMA\n"); |
candre97 | 111:f6bf8ca71128 | 112 | |
candre97 | 110:037667235b6d | 113 | printf("Creating buff of size %d\n", BUFFSIZE); |
candre97 | 110:037667235b6d | 114 | /* clear the buffer */ |
candre97 | 110:037667235b6d | 115 | buff.clear(); |
candre97 | 111:f6bf8ca71128 | 116 | printf("library read val: %u\n", mic.read_u16()); |
candre97 | 110:037667235b6d | 117 | |
candre97 | 112:a0fd359ec3a6 | 118 | /* Setup and initialize ADC converter https://www.davidkebo.com/microcontroller-interfacing */ |
candre97 | 111:f6bf8ca71128 | 119 | RCC->APB2RSTR |= 1 << 9; /* Enable ADC1 clock */ |
candre97 | 111:f6bf8ca71128 | 120 | GPIOA->CRL &= 0xFFF0FFFF; /* Configure PC4 as ADC.14 input */ |
candre97 | 111:f6bf8ca71128 | 121 | ADC1->SQR1 = 0x00000000; /* Regular channel 1 conversion */ |
candre97 | 111:f6bf8ca71128 | 122 | ADC1->SQR2 = 0x00000000; /* Clear register */ |
candre97 | 111:f6bf8ca71128 | 123 | ADC1->SQR3 = 14 << 0; /* SQ1 = channel 14 */ |
candre97 | 111:f6bf8ca71128 | 124 | ADC1->SMPR1 = 5 << 12; /* Channel 14 sample time is 55.5 cyc */ |
candre97 | 111:f6bf8ca71128 | 125 | ADC1->SMPR2 = 0x00000000; /* Clear register */ |
candre97 | 111:f6bf8ca71128 | 126 | ADC1->CR1 = 1 << 8; /* Scan mode on */ |
candre97 | 111:f6bf8ca71128 | 127 | ADC1->CR2 = (1 << 20) | /* Enable external trigger */ |
candre97 | 111:f6bf8ca71128 | 128 | (7 << 17) | /* EXTSEL = SWSTART */ |
candre97 | 111:f6bf8ca71128 | 129 | (1 << 1) | /* Continuous conversion */ |
candre97 | 111:f6bf8ca71128 | 130 | (1 << 0) ; /* ADC enable */ |
candre97 | 111:f6bf8ca71128 | 131 | ADC1->CR2 |= 1 << 3; /* Initialize calibration registers */ |
candre97 | 111:f6bf8ca71128 | 132 | while (ADC1->CR2 & (1 << 3)); /* Wait for initialization to finish */ |
candre97 | 111:f6bf8ca71128 | 133 | ADC1->CR2 |= 1 << 2; /* Start calibration */ |
candre97 | 111:f6bf8ca71128 | 134 | while (ADC1->CR2 & (1 << 2)); /* Wait for calibration to finish */ |
candre97 | 111:f6bf8ca71128 | 135 | ADC1->CR2 |= 1 << 22; /* Start first conversion */ |
candre97 | 111:f6bf8ca71128 | 136 | |
candre97 | 111:f6bf8ca71128 | 137 | for (;;) { /* Loop forever */ |
candre97 | 111:f6bf8ca71128 | 138 | if (ADC1->SR & (1 << 1)) { /* If conversion has finished */ |
candre97 | 111:f6bf8ca71128 | 139 | raw_adc = ADC1->DR & 0x0FFF; /* Read AD converted value */ |
candre97 | 111:f6bf8ca71128 | 140 | ADC1->CR2 |= 1 << 22; /* Start new conversion */ |
candre97 | 111:f6bf8ca71128 | 141 | } |
candre97 | 111:f6bf8ca71128 | 142 | printf("register read val: %u\n", raw_adc); |
candre97 | 111:f6bf8ca71128 | 143 | thread_sleep_for(2000); |
candre97 | 111:f6bf8ca71128 | 144 | } |
candre97 | 111:f6bf8ca71128 | 145 | |
candre97 | 111:f6bf8ca71128 | 146 | |
candre97 | 111:f6bf8ca71128 | 147 | |
candre97 | 111:f6bf8ca71128 | 148 | while(1); |
candre97 | 109:1d95a4596fb5 | 149 | thread_adc.start(adc_thread); |
candre97 | 109:1d95a4596fb5 | 150 | thread_mfcc.start(mfcc_thread); |
candre97 | 102:14fd65f261a2 | 151 | } |