First functioning version
This commit is contained in:
172
main.cpp
172
main.cpp
@ -3,122 +3,96 @@
|
||||
#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"
|
||||
#include "decoder.h"
|
||||
|
||||
static constexpr uint8_t T0_A = PB0;
|
||||
static constexpr uint8_t T0_B = PB1;
|
||||
static constexpr uint8_t T1_A = PB3;
|
||||
static constexpr uint8_t T1_B = PB4;
|
||||
|
||||
static volatile bool turnout0Flag = false;
|
||||
static volatile bool turnout1Flag = false;
|
||||
|
||||
void handler(uint16_t data, void *user_data)
|
||||
{
|
||||
(void)user_data;
|
||||
|
||||
if(((bool)(data & (1 << 9))) != ((bool)(data & (1 << 8))) ||
|
||||
((bool)(data & (1 << 7))) != ((bool)(data & (1 << 6))) ||
|
||||
((bool)(data & (1 << 5))) != ((bool)(data & (1 << 4))))
|
||||
return;
|
||||
bool set = data & (1 << 9);
|
||||
if(data & (1 << 7))
|
||||
turnout0Flag = set;
|
||||
if(data & (1 << 5))
|
||||
turnout1Flag = set;
|
||||
}
|
||||
|
||||
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)
|
||||
static void setTurnout0(bool in)
|
||||
{
|
||||
adc.aquire();
|
||||
writePin(&PORTB, T0_A, in);
|
||||
writePin(&PORTB, T0_B, !in);
|
||||
_delay_ms(50);
|
||||
|
||||
writePin(&PORTB, T0_A, false);
|
||||
writePin(&PORTB, T0_B, false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
extern "C" usbMsgLen_t usbFunctionSetup(uchar data[8])
|
||||
static void setTurnout1(bool in)
|
||||
{
|
||||
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;
|
||||
writePin(&PORTB, T1_A, in);
|
||||
writePin(&PORTB, T1_B, !in);
|
||||
_delay_ms(50);
|
||||
|
||||
writePin(&PORTB, T1_A, false);
|
||||
writePin(&PORTB, T1_B, false);
|
||||
}
|
||||
|
||||
void adcConversionCallback(uint16_t sample, void* userData)
|
||||
Decoder decoder(&PINB, PB2, &TCNT1, &handler);
|
||||
|
||||
ISR(TIMER1_OVF_vect)
|
||||
{
|
||||
buffer.write(sample);
|
||||
sampleId++;
|
||||
decoder.overflowInterrupt();
|
||||
}
|
||||
|
||||
void timer0InterruptEnable(const bool enable)
|
||||
ISR(INT0_vect)
|
||||
{
|
||||
if(enable) TIMSK = TIMSK | (1 << TOIE0);
|
||||
else TIMSK = TIMSK & ~(1 << TOIE0);
|
||||
decoder.interrupt();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
DDRB = (1 << PB0) | (1 << PB1) | (1 << PB3) | (1 << PB4);
|
||||
|
||||
bool turnout0 = false;
|
||||
bool turnout1 = false;
|
||||
_delay_ms(100);
|
||||
setTurnout0(true);
|
||||
setTurnout1(true);
|
||||
_delay_ms(500);
|
||||
setTurnout0(false);
|
||||
setTurnout1(false);
|
||||
|
||||
MCUCR = (1 << ISC00); //enable rising and falling irq on INT0
|
||||
GIMSK = (1 << INT0); //unmask INT0
|
||||
TIMSK = (1 << TOIE1); //enable timer 1 overflow irq
|
||||
TCCR1 = (1 << CS12) | (1 << CS10); //enable timer 1 with /16 timer
|
||||
|
||||
sei();
|
||||
while(true)
|
||||
{
|
||||
if(turnout0 != turnout0Flag)
|
||||
{
|
||||
turnout0 = turnout0Flag;
|
||||
setTurnout0(turnout0);
|
||||
}
|
||||
if(turnout1 != turnout1Flag)
|
||||
{
|
||||
turnout1 = turnout1Flag;
|
||||
setTurnout1(turnout1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user