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

main
Last change on this file since e07597b was e07597b, checked in by Adrien Destugues <pulkomandy@…>, 12 years ago
  • Remove binary file for now
  • Make sure the output stays high when not generating pulses, and also stop the timer to get no interrupt storm.

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

  • Property mode set to 100644
File size: 3.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 // Generate sync header (this never changes)
38 int i;
39 for (i = 0; i< 16; i++)
40 {
41 ioblock[i] = 1;
42 }
43 ioblock[i++] = 0x3C;
44 ioblock[i++] = 0x5A;
45
46 // HEAD block
47 ioblock[i++] = 0x0;
48 ioblock[i++] = 0x10;
49
50 int j = i;
51 ioblock[i++] = 'C';
52 ioblock[i++] = 'r';
53 ioblock[i++] = 'O';
54 ioblock[i++] = '2';
55 ioblock[i++] = ' ';
56 ioblock[i++] = ' ';
57 ioblock[i++] = ' ';
58 ioblock[i++] = ' ';
59 ioblock[i++] = 'B';
60 ioblock[i++] = 'A';
61 ioblock[i++] = 'S';
62 ioblock[i++] = 0;
63 ioblock[i++] = 0;
64 ioblock[i++] = 0;
65 uint8_t s = 0;
66 for (;j<i;j++) s -= ioblock[j];
67 ioblock[i++] = s;
68
69
70 // Setup TIMER 1 for MFM pulses generation
71 TCCR1A = (1<<COM1A0); // Enable OC1A output
72 TCCR1A |= (1<<COM1A1); // Compare match will always SET OC1A instead of toggling it. Thus the output is always high.
73 // CTC mode with OCR1A as MAXregister
74 TCCR1B = (1<<WGM12);
75 OCR1A = 12800; // 800us bit clock
76 OCR1B = 6400; // Half-clock for 1 bits
77 TIMSK = (1 << OCIE1B) | (1 << OCIE1A); // interrupts on both timer matches.
78 TCCR1A |= (bit << FOC1A); // Force toggle of A (make sure output is a logic 1 to allow MO5 to detect tapedrive)
79
80 DDRB |= 2; // OC1A/PB1 as output
81
82
83 while(1) {
84 wdt_reset();
85 usbPoll();
86 // TODO watch for motor on/off
87 }
88}
89
90
91uint8_t usbFunctionSetup(uint8_t data[8]) {
92 usbRequest_t *rq = (void *)data;
93
94 usbMsgPtr = ioblock;
95 switch(rq->bRequest)
96 {
97 case 0:
98 { /* CONFIGURE */
99 status = rq->wValue.bytes[0];
100 return 0;
101 }
102 case 1:
103 { /* RECEIVE/POLL DATA (TAPE > USB) */
104 return 254;
105 }
106 case 2:
107 {
108 /* SEND DATA (USB > TAPE) */
109 /* Get ready, actual data will come in usbFunctionWrite */
110 // TODO store type of MO5 block + size in ioblock
111 writePos = 0;
112 blksz = rq->wLength.word;
113 return USB_NO_MSG; // Call usbFunctionWrite to send the data
114 }
115 }
116 return 0;
117}
118
119uint8_t usbFunctionWrite(uint8_t* data, uint8_t len)
120{
121 // The data for a single request will be sent as slices of up to 8 bytes.
122 for (int i = 0; i < len; i++)
123 {
124 // TODO leave place for sync header and block type+size
125// ioblock[writePos] = data[i];
126 writePos++;
127 }
128
129 // TODO compute checksum as we go
130
131 if (writePos >= blksz)
132 {
133 // start generating
134 TCCR1A &= ~(1<<COM1A1);
135 TCCR1B |= (1<<CS10);
136 return 1;
137 } else {
138 return 0;
139 }
140 // returns 0: "needs more data"
141 // returns 1: "done"
142 // returns FF: "error"
143}
144
145ISR (TIMER1_COMPA_vect, ISR_NOBLOCK)
146{
147 // generate next bit
148 bit = (ioblock[readPos] >> bitpos) & 1;
149 bitpos++;
150 if (bitpos > 7)
151 {
152 bitpos = 0;
153 readPos++;
154 if (readPos > blksz)
155 {
156 // Make sure output is high
157 TCCR1A |= (1<<COM1A1);
158 // Stop generating (and interrupts)
159 TCCR1B &= ~(1<<CS10);
160 readPos = 0;
161 TCCR1A |= (1 << FOC1A);
162 }
163 }
164}
165
166ISR (TIMER1_COMPB_vect, ISR_NOBLOCK)
167{
168 TCCR1A |= (bit << FOC1A); // Force toggle of A on B compare when generating a 1 bit
169}
Note: See TracBrowser for help on using the repository browser.