/*UVOS*/ /* This file is part of UsbLedController. * * TelemetrySystem is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License (LGPL) version 3 as published by * the Free Software Foundation. * * TelemetrySystem is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with TelemetrySystem. If not, see . */ #include #include #include #include #include #include #include "writepin.h" #include "usbdrv.h" #define SOFT_PWM_DIV 1 static volatile uint16_t counter; static volatile uint16_t lastTime; static volatile uint8_t ovfCount[4] = {0xFF,0xFF,0xFF,0xFF}; static int16_t cameraOffset; static uint8_t mask; static uint8_t current; static uint16_t intvl; static uint8_t runSeq; enum { SEQ_NONE = 0, SEQ_TRIG, SEQ_PIC, }; ISR(TIM1_COMPA_vect) { PORTA = PORTA & (1 << PA4) ? PORTA & ~(1 << PA4) : PORTA | (1 << PA4); uint16_t intrTime = TCNT1; counter += lastTime <= intrTime ? (intrTime - lastTime)/SOFT_PWM_DIV : (intrTime + (UINT16_MAX-counter))/SOFT_PWM_DIV; lastTime = intrTime; uint8_t next = UINT8_MAX-counter+1; //155 if(next == 0) next = UINT8_MAX; uint8_t update = PORTA & 0xF0; for (uint8_t i = 0; i < 4; ++i) { if(counter < ovfCount[i]) { update |= 1 << i; if(next > ovfCount[i]-counter) next = ovfCount[i]-counter; } } PORTA = update; if(next < 32) next = 32; uint32_t next32 = ((uint32_t)next)*SOFT_PWM_DIV+intrTime; OCR1A = next32 < UINT16_MAX ? next32 : next32 - (UINT16_MAX-intrTime); } void poll() { usbPoll(); uint8_t update = PORTA & 0xF0; uint8_t time = TCNT0; for (uint8_t i = 0; i < 4; ++i) { if(time < ovfCount[i] || ovfCount[i] == UINT8_MAX) { update |= 1 << i; } } PORTA = update; } void pollWait(uint16_t ms) { ms *= (F_CPU/256)/1000; TCNT1 = 0; while(TCNT1 < ms) poll(); } static void triggerCamera(void) { writePin(&PORTB, PB2, true); pollWait(50); writePin(&PORTB, PB2, false); } static void takePicture(const uint8_t mask, const uint8_t current, const uint16_t interval, const int16_t cameraOffset) { if(cameraOffset > interval) return; if(cameraOffset < 0) { writePin(&PORTB, PB2, true); pollWait((uint16_t)(0 - cameraOffset)); } for(uint8_t i = 0; i < 4; ++i) { if(mask & (1 << i)) ovfCount[i] = UINT8_MAX - current; } if(cameraOffset > 0) { pollWait((uint16_t)cameraOffset); writePin(&PORTB, PB2, true); pollWait(interval - cameraOffset); } else { pollWait(interval); } for(uint8_t i = 0; i < 4; ++i) { if(mask & (1 << i)) ovfCount[i] = 255; } writePin(&PORTB, PB2, false); } usbMsgLen_t usbFunctionSetup(uchar data[8]) { usbRequest_t *rq = (usbRequest_t *)data; static uchar dataBuffer[8]; if(rq->bRequest == 0) { writePin(&PORTA, PA5, false); return 0; } if(rq->bRequest == 1) { writePin(&PORTA, PA5, true); return 0; } if(rq->bRequest == 2) { for (uint8_t i = 0; i < 4; ++i) { if(rq->wValue.bytes[0] & (1 << i)) ovfCount[i] = UINT8_MAX - rq->wValue.bytes[1]; } return 0; } if(rq->bRequest == 3) { triggerCamera(); return 0; } if(rq->bRequest == 4) { mask = rq->wValue.bytes[0]; current = rq->wValue.bytes[1]; intvl = rq->wIndex.word; return 0; } if(rq->bRequest == 5) { cameraOffset = rq->wValue.word; return 0; } if(rq->bRequest == 128) { dataBuffer[0] = 55; dataBuffer[1] = 55; dataBuffer[2] = 55; dataBuffer[3] = 55; usbMsgPtr = (short unsigned int)dataBuffer; return 4; } return 0; } static void timer1InterruptEnable(const bool enable) { TIMSK1 = enable ? TIMSK1 | (1 << OCIE1A) : TIMSK1 & ~(1 << OCIE1A); } int main(void) { PORTA = (1 << PA0) | (1 << PA1) | (1 << PA2) | (1 << PA3) | (1 << PA4) | (1 << PA5); DDRA = (1 << PA0) | (1 << PA1) | (1 << PA2) | (1 << PA3) | (1 << PA4) | (1 << PA5); DDRB = (1 << PB2); PORTB = (1 << PB2); TCCR1B = (1<