source: avrstuff/V-USB_Dev/firmwares/CrO2/main.c@ 4af90bf

main
Last change on this file since 4af90bf was 4af90bf, checked in by Adrien Destugues <pulkomandy@…>, 12 years ago

work in progress CrO2:

  • USB configuration for a control endpoint with data payload
  • Timer setup for generating MFM stream

git-svn-id: svn://pulkomandy.tk/avrstuff@51 c6672c3c-f6b6-47f9-9001-1fd6b12fecbe

  • Property mode set to 100644
File size: 2.5 KB
Line 
1#include <avr/io.h>
2#include <avr/interrupt.h>
3#include <avr/wdt.h>
4#include <avr/pgmspace.h>
5#include <util/delay.h>
6
7#include <string.h>
8#include <stdbool.h>
9
10#include "usbdrv/usbdrv.h"
11
12static uint8_t ioblock[275]; // Max. Size of an MO5 standard block including sync header
13static uint8_t status; // status bits
14static uint16_t writePos;
15static uint16_t blksz;
16
17static uint16_t readPos;
18static uint8_t bitpos;
19static uint8_t bit; // Currently generated bit
20
21int main() {
22 // Init
23 status = 0;
24 writePos = 0;
25 blksz = 0;
26
27 wdt_enable(WDTO_2S);
28
29 // USB
30 usbInit();
31 sei();
32
33 bit = 1;
34 bitpos = 0;
35 readPos = 0;
36
37 // Setup TIMER 1 for MFM pulses generation
38 TCCR1A = (1<<COM1A0); // Enable OC1A output
39 // CTC mode with OCR1A as MAXregister
40 TCCR1B = (1<<WGM12) | (1<<CS10);
41 OCR1A = 12800; // 800us bit clock
42 OCR1B = 6400; // Half-clock for 1 bits
43 TIMSK = (1 << OCIE1B) | (1 << OCIE1A); // interrupts on both timer matches.
44
45 // TODO only start the timer when actually needed (start of block)
46 // and stop it when done.
47 DDRB |= 2; // OC1A/PB1 as output
48
49
50 while(1) {
51 wdt_reset();
52 usbPoll();
53
54 // TODO send data to tape !
55 }
56}
57
58
59uint8_t usbFunctionSetup(uint8_t data[8]) {
60 usbRequest_t *rq = (void *)data;
61
62 usbMsgPtr = ioblock;
63 switch(rq->bRequest)
64 {
65 case 0:
66 { /* CONFIGURE */
67 status = rq->wValue.bytes[0];
68 return 0;
69 }
70 case 1:
71 { /* RECEIVE/POLL DATA (TAPE > USB) */
72 return 254;
73 }
74 case 2:
75 {
76 /* SEND DATA (USB > TAPE) */
77 /* Get ready, actual data will come in usbFunctionWrite */
78 // TODO store type of MO5 block + size in ioblock
79 writePos = 0;
80 blksz = rq->wLength.word;
81 return USB_NO_MSG; // Call usbFunctionWrite to send the data
82 }
83 }
84 return 0;
85}
86
87uint8_t usbFunctionWrite(uint8_t* data, uint8_t len)
88{
89 // The data for a single request will be sent as slices of up to 8 bytes.
90 for (int i = 0; i < len; i++)
91 {
92 // TODO leave place for sync header and block type+size
93 ioblock[writePos++] = data[i];
94 }
95
96 // TODO compute checksum as we go
97
98 return writePos>= blksz ? 1:0;
99 // returns 0: "needs more data"
100 // returns 1: "done"
101 // returns FF: "error"
102}
103
104ISR (TIMER1_COMPA_vect)
105{
106 // generate next bit
107 bit = (ioblock[readPos] >> bitpos) & 1;
108 bitpos++;
109 if (bitpos > 7)
110 {
111 bitpos = 0;
112 readPos++;
113 if (readPos > 270)
114 readPos = 0; // TODO stop timer
115 }
116}
117
118ISR (TIMER1_COMPB_vect)
119{
120 TCCR1A |= (bit << FOC1A); // Force toggle of A on B compare when generating a 1 bit
121}
Note: See TracBrowser for help on using the repository browser.