source: avrstuff/V-USB_Dev/firmwares/herePic/main.c@ 8659a17

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

Progress on the host driver. Still untested.

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

  • Property mode set to 100644
File size: 3.2 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
30// TODO is it wise to use a timer or two for bit patterns generation ? (see
31// CrO2 architecture)
32//
33// As usual the SPI, TWI and USART are not useable, because we need 6 and 16 bit
34// communcations in the ICSP protocol. So we are bit banging bhe ICSP protocol.
35// Timers may make it easier to do that in parallel with the USB handling, since
36// timings are in the nanosecond range.
37
38
39uint8_t command;
40uint16_t ICSP_data;
41
42
43int main() {
44 // Init
45 wdt_enable(WDTO_2S);
46
47 // USB
48 usbInit();
49 sei();
50
51 // Enter Low Voltage ICSP mode on the PIC
52 PORTB &= ~(VPP|PGM|PGD|PGC); // Start with all pin low
53 DDRB |= VPP|PGM|PGD|PGC; // set them as outputs
54 _delay_us(4); // Wait for some time
55 PORTB |= PGM; // Enable low voltage programming
56 PORTB |= VPP; // Enter programming mode
57
58 while(1) {
59 wdt_reset();
60 usbPoll();
61 }
62}
63
64
65void ICSP_command(uint8_t cmd)
66{
67 for(int i = 6; --i>= 0;)
68 {
69 PORTB |= PGC;
70 if(cmd & 1)
71 PORTB |= PGD;
72 else
73 PORTB &= ~PGD;
74 PORTB &= ~PGC;
75
76 cmd >>= 1;
77 }
78
79 _delay_us(1);
80}
81
82
83void ICSP_write(uint8_t cmd, uint16_t data)
84{
85 ICSP_command(cmd);
86
87 // send data
88 for(int i = 16; --i>= 0;)
89 {
90 PORTB |= PGC;
91 if(data & 1)
92 PORTB |= PGD;
93 else
94 PORTB &= ~PGD;
95 PORTB &= ~PGC;
96
97 data >>= 1;
98 }
99 _delay_us(1);
100}
101
102
103void ICSP_read(uint8_t cmd, uint16_t *const data)
104{
105 ICSP_command(cmd);
106
107 // get data
108 for(int i = 16; --i>= 0;)
109 {
110 PORTB |= PGC;
111 *data |= (PORTB & PGD) / PGD;
112 PORTB &= ~PGC;
113
114 *data <<= 1;
115 }
116 _delay_us(1);
117}
118
119
120uint8_t usbFunctionSetup(uint8_t data[8]) {
121 usbRequest_t *rq = (void *)data;
122
123 switch(rq->bRequest)
124 {
125 /* HOST to DEVICE data transfers requests */
126 case LoadConfigWord:
127 case LoadCodeWord:
128 case LoadDataWord:
129 {
130 // TODO check there is only and exactly 16 bits of data
131
132 /* Read the 16-bit data */
133 ICSP_data = (rq->wValue.bytes[0] << 8) | rq->wValue.bytes[0];
134 command = rq->bRequest;
135
136 // send the command and data
137 ICSP_write(command, ICSP_data);
138
139 // Return the number of bytes we wrote (none here)
140 return 0;
141 }
142
143 /* CONFIGURATION commands (no data is transferred) */
144 case NextAddress:
145 case BeginEraseProgram:
146 case BeginProgramOnly:
147 case BulkEraseCode:
148 case BulkEraseData:
149 case BulkEraseConfig1:
150 case BulkEraseConfig2:
151 {
152 command = rq->bRequest;
153
154 // send the command
155 ICSP_command(command);
156
157 return 0;
158 }
159
160 /* DEVICE to HOST data transfers requests */
161 case ReadCodeWord:
162 case ReadDataWord:
163 {
164 command = rq->bRequest;
165 // TODO send the command and get the result
166 ICSP_read(command, &ICSP_data);
167 usbMsgPtr = (uint8_t*)&ICSP_data;
168
169 return 2; // We send 2 bytes back
170 }
171 }
172 return 0;
173}
174
Note: See TracBrowser for help on using the repository browser.