source: avrstuff/V-USB_Dev/firmwares/herePic/driver/herepic.cpp@ 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: 4.2 KB
Line 
1/* HEREPIC - AVR based ICSP programmer for 16F6xx and 16F8xx chips
2 * Copyright 2012, Adrien Destugues <pulkomandy@gmail.com>
3 *
4 * This file is distributed under the terms of the MIT licence
5 */
6
7// C++
8#include <iostream>
9
10// POSIX
11#include <semaphore.h>
12#include <unistd.h>
13
14// Haiku
15#include <USBKit.h>
16
17#include "../shared.h"
18#include "icsp.h"
19
20
21// We need a subclass of USBRoster to enumerate devices.
22class MyUSBRoster: public BUSBRoster {
23 public:
24 MyUSBRoster(BUSBDevice*& device, sem_t& deviceLock)
25 : fDevice(device)
26 , fDeviceLock(deviceLock)
27 {
28 Start();
29 }
30
31 ~MyUSBRoster()
32 {
33 sem_destroy(&fDeviceLock);
34 Stop();
35 }
36
37 /* The DeviceAdded hook will be called for all plugged devices.
38 If we don't find the correct one, the method will also be called later,
39 as devices are plugged. So we can wait for the right device to come in!
40 */
41 status_t DeviceAdded(BUSBDevice* device)
42 {
43 if(device->VendorID() == 0x16c0 && device->ProductID() == 0x05DC
44 && strcmp(device->ManufacturerString(), "pulkomandy.tk") == 0
45 && strcmp(device->ProductString(), "HerePic") == 0)
46 {
47 fDevice = device;
48 // Notify main thread it's ok to continue
49 sem_post(&fDeviceLock);
50 }
51 return B_OK;
52 }
53
54 void DeviceRemoved(BUSBDevice* device)
55 {
56 // TODO send message to main app to tell there's a problem !
57 // or we may even commit suicide at this point...
58 }
59 private:
60 BUSBDevice*& fDevice;
61 sem_t& fDeviceLock;
62};
63
64
65void usage(const char* progname)
66{
67 // print usage
68 std::cout << progname << " - AVR based ICSP programmer for "
69 "PIC16F62x and PIC16F87x" << std::endl <<
70 "Written by Adrien Destugues <pulkomandy@gmail.com>"
71 << std::endl << std::endl <<
72 "Usage:" << std::endl <<
73 " -w file.hex Write file to device" << std::endl <<
74 " -r file.hex Read device to file" << std::endl <<
75 " -e Erase device" << std::endl <<
76 " -h Display this help message" << std::endl;
77}
78
79
80int main(int argc, char** argv)
81{
82 // parse CLI args
83 static const char* optstring = ":w:r:eh";
84
85 int nextopt;
86 signed char action = 0;
87 const char* filename;
88
89 do {
90 nextopt = getopt(argc,argv, optstring);
91
92 switch(nextopt)
93 {
94 case 'w':
95 case 'r':
96 case 'h':
97 case 'e':
98 // We get the filename in all cases, for h and e it will give
99 // meaningless results but we won't be using it anyway
100 filename = optarg;
101 // store the action, but make sure we do it only once
102 if (action > 0)
103 {
104 std::cerr << "multiple actions specified (only one of w,r,e is allowed)" << std::endl;
105 action = -1;
106 } else {
107 action = nextopt;
108 }
109 break;
110 case ':':
111 std::cout << "option -" << (char)optopt << " needs an argument" << std::endl;
112 break;
113 case '?':
114 std::cerr << "Unknown option: -" << (char)optopt << std::endl;
115 break;
116 case -1:
117 // end of options
118 break;
119 default:
120 std::cerr << "Command-line format error at argument " << optind
121 << std::endl;
122 break;
123 }
124 } while(nextopt != -1);
125
126 // If we found no valid action request, print usage and exit
127 if (action <= 0 || action == 'h')
128 {
129 usage(argv[0]);
130 // Exit code is EXIT_SUCCESS if we reach this by -h option. Otherwise
131 // the arguments are incorrect
132 exit(action < 0 ? action : 0);
133 }
134
135 // TODO handle the boring usb stuff... (might be nice to abstract it so we
136 // can use both libusb and haiku usb kit)
137
138 BUSBDevice* theDevice = NULL;
139 sem_t deviceLock;
140
141 sem_init(&deviceLock, false, 0);
142
143 MyUSBRoster usbRoster(theDevice, deviceLock);
144 usbRoster.Start();
145
146 int deviceAvailable;
147 // TODO we rely on the initial device scan being done when we get here. Is
148 // that always true ? If not, we may print this message in cases where it
149 // is not needed.
150 sem_getvalue(&deviceLock, &deviceAvailable);
151 if(deviceAvailable == 0)
152 {
153 std::cout << "Programmer hardware not detected. Please connect it now..." << std::endl;
154 }
155
156 // Wait for the device
157 sem_wait(&deviceLock);
158
159 ICSP icsp(*theDevice);
160
161 // take action depending on command request in CLI
162 switch(action)
163 {
164 case 'r':
165 // read the chip
166 icsp.Read(filename);
167 break;
168 case 'w':
169 icsp.Write(filename);
170 // Here, perform the programming cycle !
171 break;
172 case 'e':
173 icsp.Erase();
174 // erase the chip
175 break;
176 }
177
178 exit(0);
179}
Note: See TracBrowser for help on using the repository browser.