source: avrstuff/V-USB_Dev/firmwares/herePic/main.c@ 0262b6e

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

Move PIC init earlier in boot sequence since we don't control VCC line !
The pic starts at the same time as the AVR and we have to enter it in reset state as fast as possible.

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

  • Property mode set to 100644
File size: 3.6 KB
Line 
1
2/* This project is targetted at the VUSBDev hacking board. */
3
4#include <avr/io.h>
5#include <avr/interrupt.h>
6#include <avr/wdt.h>
7#include <avr/pgmspace.h>
8#include <util/delay.h>
9
10#include <string.h>
11#include <stdbool.h>
12
13#include "usbdrv/usbdrv.h"
14#include "shared.h"
15
16// IO pins:
17// PIC <> AVR
18// PGC PB3
19// PGD PB2
20// PGM PB1
21// VPP PB0
22// VDD VCC
23// VSS GND
24#define PGC 8
25#define PGD 4
26#define PGM 2
27#define VPP 1
28
29// VUSB leds (PD6 and PD7)
30#define RED 64
31#define GREEN 128
32
33// TODO is it wise to use a timer or two for bit patterns generation ? (see
34// CrO2 architecture)
35//
36// As usual the SPI, TWI and USART are not useable, because we need 6 and 16 bit
37// communcations in the ICSP protocol. So we are bit banging bhe ICSP protocol.
38// Timers may make it easier to do that in parallel with the USB handling, since
39// timings are in the nanosecond range.
40
41
42uint8_t command;
43uint16_t ICSP_data;
44
45
46int main() {
47 // Enter Low Voltage ICSP mode on the PIC
48 PORTB &= ~(VPP|PGM|PGD|PGC); // Start with all pins low
49 DDRB |= VPP|PGM|PGD|PGC; // set them as outputs
50 _delay_us(5); // Wait for some time
51 PORTB |= PGM | VPP; // Enter low voltage programming mode
52
53 // Init
54 wdt_enable(WDTO_2S);
55
56 // USB
57 usbInit();
58 sei();
59
60 // Configure leds
61 DDRD |= RED | GREEN;
62 PORTD |= RED | GREEN;
63
64 int k = 0;
65
66 while(1) {
67 if (k-- < 0)
68 {
69 k = 20000;
70 PORTD ^= RED;
71 }
72 wdt_reset();
73 usbPoll();
74 }
75}
76
77
78void ICSP_command(uint8_t cmd)
79{
80 for(int i = 6; --i>= 0;)
81 {
82 if(cmd & 1)
83 PORTB |= PGD;
84 else
85 PORTB &= ~PGD;
86 PORTB |= PGC;
87 PORTB &= ~PGC;
88
89 cmd >>= 1;
90 }
91
92 _delay_us(1);
93}
94
95
96void ICSP_write(uint8_t cmd, uint16_t data)
97{
98 ICSP_command(cmd);
99
100 // send data
101 for(int i = 16; --i>= 0;)
102 {
103 if(data & 1)
104 PORTB |= PGD;
105 else
106 PORTB &= ~PGD;
107 PORTB |= PGC;
108 PORTB &= ~PGC;
109
110 data >>= 1;
111 }
112 _delay_us(1);
113}
114
115
116void ICSP_read(uint8_t cmd, uint16_t *const data)
117{
118 ICSP_command(cmd);
119
120 // PGD as input
121 DDRB &= ~PGD;
122 PORTB |= PGD; //pull up
123
124 // get data
125 for(int i = 16; --i>= 0;)
126 {
127 PORTB |= PGC;
128 *data |= (PINB & PGD) / PGD;
129 PORTB &= ~PGC;
130
131 *data <<= 1;
132 }
133 _delay_us(1);
134
135 // PGD as output
136 PORTB &= ~PGD;
137 DDRB |= PGD;
138}
139
140
141uint8_t usbFunctionSetup(uint8_t data[8]) {
142 usbRequest_t *rq = (void *)data;
143
144 PORTD &= ~GREEN;
145
146 if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_VENDOR)
147 switch(rq->bRequest)
148 {
149 /* HOST to DEVICE data transfers requests */
150 case LoadConfigWord:
151 case LoadCodeWord:
152 case LoadDataWord:
153 {
154 // TODO check there is only and exactly 16 bits of data
155
156 /* Read the 16-bit data */
157 ICSP_data = (rq->wValue.bytes[0] << 8) | rq->wValue.bytes[0];
158 command = rq->bRequest;
159
160 // send the command and data
161 ICSP_write(command, ICSP_data);
162
163 // Return the number of bytes we wrote (none here)
164 PORTD |= GREEN;
165 return 0;
166 }
167
168 /* CONFIGURATION commands (no data is transferred) */
169 case NextAddress:
170 case BeginEraseProgram:
171 case BeginProgramOnly:
172 case BulkEraseCode:
173 case BulkEraseData:
174 case BulkEraseConfig1:
175 case BulkEraseConfig2:
176 {
177 command = rq->bRequest;
178
179 // send the command
180 ICSP_write(command, 0);
181
182 PORTD |= GREEN;
183 return 0;
184 }
185
186 /* DEVICE to HOST data transfers requests */
187 case ReadCodeWord:
188 case ReadDataWord:
189 {
190 command = rq->bRequest;
191 // TODO send the command and get the result
192 ICSP_read(command, &ICSP_data);
193 usbMsgPtr = (uint8_t*)&ICSP_data;
194
195 PORTD |= GREEN;
196 return 2; // We send 2 bytes back
197 }
198 }
199
200 // Unhandled commands leave the green led on.
201 return 0;
202}
203
Note: See TracBrowser for help on using the repository browser.