Skip to content

Instantly share code, notes, and snippets.

@dagon666
Created July 20, 2014 21:20
Show Gist options
  • Save dagon666/4d7b8291f9fa58dc0bd0 to your computer and use it in GitHub Desktop.
Save dagon666/4d7b8291f9fa58dc0bd0 to your computer and use it in GitHub Desktop.
arduino uscope experiment
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include "pca.h"
#include "main.h"
// global samples buffer
volatile struct samples g_samples;
void adc_setup() {
// enable global ints
sei();
adc_init(E_AT_FREERUN);
adc_reference_set(E_ADC_REF_INTERNAL_11);
ADMUX |= _BV(ADLAR); // result left adjusted
// setup prescaler = 64
// f = 250 kHz
adc_prescaler_set(0x6);
adc_channel_set(0);
adc_di_disable(0);
adc_di_disable(1);
adc_di_disable(2);
adc_di_disable(3);
// disable interrupts for now
adc_interrupt_disable();
// start the thing up
adc_conversion_trigger();
}
void comparator_setup() {
ADCSRB &= ~_BV(ACME);
DIDR1 = 0x03;
// int on rising output edge
ACSR = _BV(ACIS1) | _BV(ACIS0);
}
void adc_start() {
adc_interrupt_enable();
}
void samples_init() {
memset((void *)&g_samples, 0x00, sizeof(struct samples));
}
void samples_collect() {
// make sure that the head equals the tail
g_samples.s.r.tail = g_samples.s.r.head;
adc_start();
}
ISR(ADC_vect) {
volatile uint8_t data = ADCH;
g_samples.next = SAMPLES_NEXT_HEAD(g_samples);
// if there is no space in the buff
if (g_samples.next != g_samples.s.r.tail) {
g_samples.s.r.ring[g_samples.s.r.head] = data;
g_samples.s.r.head = g_samples.next;
}
else {
// disable ADC interrupt
adc_interrupt_disable();
} // if
}
ISR(ANALOG_COMP_vect, ISR_BLOCK) {
// disable comparator interrupt
ACSR &= ~_BV(ACIE);
g_samples.s.r.tail = g_samples.s.r.head;
samples_collect();
}
int main(int argc, char *argv[]) {
struct dev_pcd8544_ctx lcd;
struct bus_t spi_bus;
spi_bus = spi_hw_poll_bus_get();
lcd.bus = &spi_bus;
lcd.sce.port = &PORTB;
lcd.sce.pin = PORTB0;
lcd.dc.port = &PORTB;
lcd.dc.pin = PORTB1;
lcd.res.port = &PORTB;
lcd.res.pin = PORTB2;
spi_hw_poll_init(E_SPI_MODE_MASTER, E_SPI_SPEED_F2);
pcd8544_init(&lcd);
pcd8544_clrscr(&lcd);
pcd8544_install_stdout(&lcd);
samples_init();
adc_setup();
comparator_setup();
uint8_t x,y,b;
uint8_t result = 0;
uint8_t yp[86] = {0x00};
while (1) {
/* samples_collect(); */
ACSR |= _BV(ACIE);
while (SAMPLES_NOT_FULL(g_samples)) {
// wait for data
}
x = 0;
while (g_samples.s.r.tail != g_samples.s.r.head) {
result = g_samples.s.r.ring[g_samples.s.r.tail];
g_samples.s.r.tail = SAMPLES_NEXT_TAIL(g_samples);
y = (uint8_t)(((float)result/256) * 48);
b = (1 << (y % 8));
y = y >> 3;
pcd8544_putblock(&lcd, x, yp[x], 0x00);
pcd8544_putblock(&lcd, x, y, b);
yp[x] = y;
x++;
}
}
return 0;
}
#ifndef __MAIN_H__
#define __MAIN_H__
#define SAMPLES_BUFF_SIZE 86
/**
* @brief determine next head position
*/
#define SAMPLES_NEXT_HEAD(__buff) \
((__buff.s.r.head + 1) % SAMPLES_BUFF_SIZE)
#define SAMPLES_NEXT_TAIL(__buff) \
((__buff.s.r.tail + 1) % SAMPLES_BUFF_SIZE)
#define SAMPLES_FULL(__buff) \
(__buff.next == __buff.s.r.tail)
#define SAMPLES_NOT_FULL(__buff) \
(__buff.next != __buff.s.r.tail)
/**
* @brief samples buffer
*/
struct samples {
union {
volatile uint8_t raw[SAMPLES_BUFF_SIZE + RING_SIZE];
volatile ring_buffer r;
} s;
volatile uint8_t next;
};
#endif /* __MAIN_H__ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment