Files
TrainDecoder/main.cpp
2020-02-03 23:19:58 +01:00

125 lines
3.0 KiB
C++

#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#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<<CS02); // run timer0 with /256 scaler
timer0InterruptEnable(true);
usbInit();
usbDeviceDisconnect(); // enforce re-enumeration, do this while interrupts are disabled!
_delay_ms(250);
usbDeviceConnect();
sei();
while(true)
{
usbPoll();
}
}