diff --git a/oscilloscope.c b/oscilloscope.c index daafa662dea329e6d874be04b28b93551d5e39ac..4f54617f7428665c5144ce782608dd58c111e477 100644 --- a/oscilloscope.c +++ b/oscilloscope.c @@ -12,12 +12,17 @@ int16_t *raw_buffer_a; int16_t *raw_buffer_b; bool active_buffer; // 0 for a, 1 for b unsigned int dma_channel; -unsigned int dma_irq; samples_ready_handler_t samples_ready_handler; volatile int samples_read; -int16_t sample_buffer[256]; +int16_t sample_buffer[SAMPLE_BUFFER_SIZE]; +/* + Lots of this code is derived from + https://github.com/raspberrypi/pico-examples/tree/master/adc/dma_capture + and + https://github.com/ArmDeveloperEcosystem/microphone-library-for-pico + */ int main() { @@ -37,7 +42,7 @@ int main() unsigned int num_samples = 0; - // with the arducam text UPSIDE DOWN, + // with the arducam text upside down, // x is left-to-right on the narrow (max x is on the right) // y is top-to-bottom on the long (max y is at the bottom) @@ -45,10 +50,10 @@ int main() { while (samples_read == 0) tight_loop_contents(); - for (size_t i = 0; i < 128; i++) - { - int16_t sample_value = sample_buffer[i*2]; - ST7735_DrawPixel((sample_value) / 20, i, ST7735_COLOR565(i, 128, 128)); + for (size_t i = 0; i < 160; i++) + { + int16_t sample_value = sample_buffer[(256*i)/160]; + ST7735_DrawPixel((sample_value) / 12, i, ST7735_COLOR565(i, 128, 128)); } sleep_ms(50); @@ -77,7 +82,6 @@ void setup_adc() void setup_dma() { - raw_buffer_a = malloc(SAMPLE_BUFFER_SIZE * sizeof(uint16_t)); raw_buffer_b = malloc(SAMPLE_BUFFER_SIZE * sizeof(uint16_t)); if (raw_buffer_a == NULL || raw_buffer_b == NULL) gpio_put(PICO_DEFAULT_LED_PIN, 1); // bad! @@ -93,8 +97,6 @@ void setup_dma() channel_config_set_write_increment(&config, true); channel_config_set_dreq(&config, DREQ_ADC); - dma_irq = DMA_IRQ_0; - dma_channel_configure( dma_channel, &config, @@ -103,13 +105,12 @@ void setup_dma() SAMPLE_BUFFER_SIZE, false ); - } void start_listening() { - irq_set_enabled(dma_irq, true); - irq_set_exclusive_handler(dma_irq, dma_handler); + irq_set_enabled(DMA_IRQ_0, true); + irq_set_exclusive_handler(DMA_IRQ_0, dma_handler); dma_channel_set_irq0_enabled(dma_channel, true); diff --git a/oscilloscope_incomplete.c b/oscilloscope_incomplete.c new file mode 100644 index 0000000000000000000000000000000000000000..ab14e4a64f6e17e96a4499daa9cfe5fdb5dfdabb --- /dev/null +++ b/oscilloscope_incomplete.c @@ -0,0 +1,140 @@ +#include "oscilloscope.h" + +#define ADC_PIN 26 + +#define BIAS_VOLTAGE 1.25 +#define SAMPLE_RATE 8000 +#define SAMPLE_BUFFER_SIZE 256 + +const int16_t bias = (BIAS_VOLTAGE * 4095) / 3.3; + +int16_t *raw_buffer_a; +int16_t *raw_buffer_b; +bool active_buffer; // 0 for a, 1 for b +unsigned int dma_channel; +unsigned int dma_irq; + +samples_ready_handler_t samples_ready_handler; +volatile int samples_read; +int16_t sample_buffer[SAMPLE_BUFFER_SIZE]; + +/* + Lots of this code is derived from + https://github.com/raspberrypi/pico-examples/tree/master/adc/dma_capture + and + https://github.com/ArmDeveloperEcosystem/microphone-library-for-pico + */ + +int main() +{ + stdio_init_all(); + setvbuf(stdout, NULL, _IONBF, 0); + sleep_ms(1000); + + // screen init + ST7735_Init(); + ST7735_FillScreen(ST7735_BLACK); + + // microphone setup + setup_adc(); + setup_dma(); + set_samples_ready_handler(on_samples_ready); + start_listening(); + + unsigned int num_samples = 0; + + // with the arducam text upside down, + // x is left-to-right on the narrow (max x is on the right) + // y is top-to-bottom on the long (max y is at the bottom) + + while (true) + { + // TODO: draw the output (from sample_buffer) + } +} + +void start_listening() +{ + // TODO: somehow call dma_handler when the samples are ready + // also set the adc running +} + +void dma_handler() +{ + // TODO: get the samples from DMA into main() + // hint: call samples_ready_handler at the end +} + +void setup_adc() +{ + adc_gpio_init(ADC_PIN); + + adc_init(); + adc_select_input(0); + adc_fifo_setup( + true, + true, + 1, + false, + false + ); + + float clkdiv = (clock_get_hz(clk_adc) / SAMPLE_RATE) - 1; + adc_set_clkdiv(clkdiv); +} + +void setup_dma() +{ + raw_buffer_a = malloc(SAMPLE_BUFFER_SIZE * sizeof(uint16_t)); + raw_buffer_b = malloc(SAMPLE_BUFFER_SIZE * sizeof(uint16_t)); + if (raw_buffer_a == NULL || raw_buffer_b == NULL) gpio_put(PICO_DEFAULT_LED_PIN, 1); // bad! + + active_buffer = 0; + + dma_channel = dma_claim_unused_channel(true); + if (dma_channel < 0) gpio_put(PICO_DEFAULT_LED_PIN, 1); // bad, also! + + dma_channel_config config = dma_channel_get_default_config(dma_channel); + channel_config_set_transfer_data_size(&config, DMA_SIZE_16); + channel_config_set_read_increment(&config, false); + channel_config_set_write_increment(&config, true); + channel_config_set_dreq(&config, DREQ_ADC); + + + dma_channel_configure( + dma_channel, + &config, + raw_buffer_a, // start with buffer a + &adc_hw->fifo, + SAMPLE_BUFFER_SIZE, + false + ); + +} + +void set_samples_ready_handler(samples_ready_handler_t handler) +{ + samples_ready_handler = handler; +} + +int read_samples(int16_t* buffer, size_t samples) +{ + uint16_t* in = active_buffer ? raw_buffer_a : raw_buffer_b; + int16_t* out = buffer; + + for (size_t i = 0; i < samples; i++) + { + *out++ = *in++ - bias; + } + + return samples; +} + +void on_samples_ready() +{ + samples_read = read_samples(sample_buffer, SAMPLE_BUFFER_SIZE); +} + +void debug_write_to_screen(char debug_string[]) { + ST7735_WriteString(80, 80, debug_string, Font_16x26, ST7735_RED, ST7735_BLACK); +}