commit 0584796a6759469aee3490d0b54e252cb640b054 Author: Carl Klemm Date: Mon Feb 3 23:19:58 2020 +0100 Inital commit Version 1.0 diff --git a/adc.cpp b/adc.cpp new file mode 100644 index 0000000..9b23ebc --- /dev/null +++ b/adc.cpp @@ -0,0 +1,40 @@ +#include "adc.h" + +#include +#include + +ISR(ADC_vect) +{ + uint16_t sample = ADCL; + sample |= ADCH << 8; + if(Adc::sampleCallback_) Adc::sampleCallback_(sample, Adc::userData_); +} + +Adc::Adc(void (*sampleCallback)(uint16_t sample, void* userData), void* userData, uint8_t input, uint8_t referance) +{ + userData_ = userData; + sampleCallback_ = sampleCallback; + ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); + setInput(input); + setReferance(referance); +} + +Adc::~Adc() +{ + ADCSRA = 0; +} + +void Adc::setInput(const uint8_t input) +{ + ADMUX = (ADMUX & 0b11110000) | (input & 0b00001111); +} + +void Adc::setReferance(const uint8_t input) +{ + ADMUX = (ADMUX & 0b00101111) | ((input & 0b00000100) << 2) | ((input & 0b00000011) << 6); +} + +void Adc::aquire() +{ + ADCSRA |= 1 << ADSC; +} diff --git a/adc.h b/adc.h new file mode 100644 index 0000000..3f1c760 --- /dev/null +++ b/adc.h @@ -0,0 +1,28 @@ +#pragma once +#include + +class Adc +{ +public: + + inline static void* userData_ = nullptr; + inline static void (*sampleCallback_)(uint16_t sample, void* userData) = nullptr; + + static constexpr uint8_t VREF_VCC = 0b0000; + static constexpr uint8_t VREF_1_1 = 0b0010; + static constexpr uint8_t VREF_2_56 = 0b0110; + static constexpr uint8_t VREF_EXT = 0b0001; + + static constexpr uint8_t IN_ADC0 = 0b0000; + static constexpr uint8_t IN_ADC1 = 0b0001; + static constexpr uint8_t IN_ADC2 = 0b0010; + static constexpr uint8_t IN_ADC3 = 0b0011; + static constexpr uint8_t IN_ADC4 = 0b1111; + + Adc(void (*sampleCallback)(uint16_t sample, void* userData), void* userData = nullptr, uint8_t input = IN_ADC0, uint8_t referance = VREF_2_56); + ~Adc(); + + void setInput(const uint8_t input); + void setReferance(const uint8_t referance); + void aquire(); +}; diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..ba726a0 --- /dev/null +++ b/main.cpp @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include "adc.h" +#include "writepin.h" +#include "ringbuffer.h" +extern "C" +{ + #include "usbdrv.h" + +} + +volatile uint16_t sampleId = 0; + +void adcConversionCallback(uint16_t sample, void* userData); + +Adc adc(&adcConversionCallback, nullptr, Adc::IN_ADC1, Adc::VREF_VCC); + +RingBuffer<32, uint16_t> buffer; + +ISR(TIMER0_OVF_vect) +{ + adc.aquire(); +} + + +extern "C" usbMsgLen_t usbFunctionSetup(uchar data[8]) +{ + usbRequest_t *rq = (usbRequest_t *)data; + static uchar dataBuffer[8]; + + if(rq->bRequest == 0) + { + if(!buffer.isEmpty() && !buffer.isEmpty() && rq->wLength.word >= 4 ) + { + usbMsgLen_t length = buffer.remaining()+2; + if(length > 8) length = 8; + if(length > rq->wLength.word) length = rq->wLength.word; + dataBuffer[0] = sampleId-buffer.remaining() >> 8; + dataBuffer[1] = sampleId-buffer.remaining() & 0x00FF; + for(usbMsgLen_t i = 2; i+1 < length; i+=2) + { + uint16_t sample = buffer.read(); + dataBuffer[i] = sample >> 8; + dataBuffer[i+1] = sample & 0x00FF; + } + usbMsgPtr = (short unsigned int)dataBuffer; + return length; + } + } + if(rq->bRequest == 1) + { + if(rq->wValue.word == 0) adc.setInput(Adc::IN_ADC1); + else adc.setInput(Adc::IN_ADC0); + buffer.flush(); + return 0; + } + if(rq->bRequest == 2) + { + if(rq->wValue.word == 0) adc.setReferance(Adc::VREF_VCC); + else if(rq->wValue.word == 1) adc.setReferance(Adc::VREF_1_1); + else adc.setReferance(Adc::VREF_2_56); + buffer.flush(); + return 0; + } + else if(rq->bRequest == 128) + { + dataBuffer[0] = 55; + dataBuffer[1] = 55; + dataBuffer[2] = 55; + dataBuffer[3] = 55; + usbMsgPtr = (short unsigned int)dataBuffer; + return 4; + } + else if(rq->bRequest == 129) + { + dataBuffer[0] = ADCSRA; + dataBuffer[1] = ADMUX; + usbMsgPtr = (short unsigned int)dataBuffer; + return 2; + } + if(rq->bRequest == 130) + { + constexpr uint16_t freq = 30518; + dataBuffer[0] = freq >> 8; + dataBuffer[1] = freq & 0x00FF; + usbMsgPtr = (short unsigned int)dataBuffer; + return 2; + } + return 0; +} + +void adcConversionCallback(uint16_t sample, void* userData) +{ + buffer.write(sample); + sampleId++; +} + +void timer0InterruptEnable(const bool enable) +{ + if(enable) TIMSK = TIMSK | (1 << TOIE0); + else TIMSK = TIMSK & ~(1 << TOIE0); +} + +int main() +{ + DIDR0 |= (1 << PB2); + TCCR0B = (1<. +*/ +#pragma once + +#include + +template < int BUFFER_SIZE, typename T = uint8_t > +class RingBuffer +{ +private: + + volatile uint_fast16_t _headIndex = 0; + volatile uint_fast16_t _tailIndex = 0; + volatile bool _overrun = false; + volatile T _buffer[BUFFER_SIZE]; + +public: + + RingBuffer() + { + flush(); + } + + uint_fast16_t remaining() const volatile + { + return (_headIndex-_tailIndex); + } + + uint_fast16_t remainingCapacity() const volatile + { + return BUFFER_SIZE - (_headIndex-_tailIndex); + } + + bool isOverun() volatile + { + bool returnVal = _overrun; + _overrun = false; + return returnVal; + } + + bool isEmpty() const volatile + { + return _tailIndex >= _headIndex; + } + + T read() volatile + { + if(!isEmpty()) + { + _tailIndex++; + return _buffer[(_tailIndex - 1) % BUFFER_SIZE]; + } + else return '\0'; + } + + unsigned int read( T* buffer, unsigned int length ) volatile + { + unsigned int i = 0; + for(; i < length && !isEmpty(); i++) + { + buffer[i] = read(); + } + return i; + } + + void write( T in ) volatile + { + if (_headIndex - BUFFER_SIZE > 0 && _tailIndex - BUFFER_SIZE > 0) + { + _headIndex -= BUFFER_SIZE; + _tailIndex -= BUFFER_SIZE; + } + _buffer[_headIndex % BUFFER_SIZE] = in; + _headIndex++; + if(remaining() > BUFFER_SIZE) + { + _overrun = true; + _tailIndex = _headIndex - BUFFER_SIZE; + } + } + + void write( T* buffer, const unsigned int length ) volatile + { + for(unsigned int i = 0; i < length; i++) write(buffer[i]); + } + + void flush(T flushCharacter = ' ') volatile + { + _headIndex = 0; + _tailIndex = 0; + for(int i = 0; i < BUFFER_SIZE; i++) _buffer[i] = flushCharacter; + _overrun = false; + } + + unsigned int getString(T terminator, T* buffer, const unsigned int bufferLength) volatile + { + unsigned int i = 0; + for(; i <= remaining() && i <= BUFFER_SIZE && _buffer[(_tailIndex+i) % BUFFER_SIZE] != terminator; i++); + + if( i < remaining() && i > 0) + { + if(i > bufferLength-1) i = bufferLength-1; + read(buffer, i); + buffer[i]='\0'; + _tailIndex++; + } + else if(i == 0) _tailIndex++; + else i = 0; + + return i; + } +}; diff --git a/writepin.cpp b/writepin.cpp new file mode 100644 index 0000000..cbeee20 --- /dev/null +++ b/writepin.cpp @@ -0,0 +1,21 @@ +#include "writepin.h" + +void writePin(volatile unsigned char * const port, const unsigned char pin, const bool state) +{ + *port = (*port & ~(1 << pin)) | (1 << pin)*state; +} + +void setBit( volatile unsigned char * const reg, const unsigned char bit, const bool value ) +{ + writePin(reg, bit, value); +} + +void setDirection( volatile unsigned char * const portDirReg, const unsigned char pin, const bool makeOutput ) +{ + writePin(portDirReg, pin, makeOutput); +} + +bool readPin( volatile const unsigned char * const inPort, const unsigned char pin) +{ + return (bool) (*inPort & (1 << pin)); +} diff --git a/writepin.h b/writepin.h new file mode 100644 index 0000000..0cf8943 --- /dev/null +++ b/writepin.h @@ -0,0 +1,13 @@ +#ifndef WRITEPIN_H +#define WRITEPIN_H +#include + +void writePin(volatile unsigned char * const port, const unsigned char pin, const bool state); + +void setBit( volatile unsigned char * const reg, const unsigned char bit, const bool value ); + +void setDirection( volatile unsigned char * const portDirReg, const unsigned char pin, const bool makeOutput ); + +bool readPin( volatile const unsigned char * const inPort, const unsigned char pin); + +#endif