2 * Copyright (C) 2009 Ubixum, Inc.
3 * Copyright (C) 2015 Jochen Hoenicke
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <fx2macros.h>
22 #include <autovector.h>
33 volatile WORD ledcounter = 0;
36 volatile __bit dosud=FALSE;
37 volatile __bit dosuspend=FALSE;
40 extern void main_loop();
41 extern void main_init();
45 SETCPUFREQ(CLK_12M); // save energy
62 RCAP2H = (-500 >> 8) & 0xff;
67 // iic files (c2 load) don't need to renumerate/delay
92 printf ( "I'm going to Suspend.\n" );
93 WAKEUPCS |= bmWU|bmWU2; // make sure ext wakeups are cleared
105 } while ( !remote_wakeup_allowed && REMOTE_WAKEUP());
106 printf ( "I'm going to wake up.\n");
110 if ( REMOTE_WAKEUP() ) {
112 USBCS |= bmSIGRESUME;
114 USBCS &= ~bmSIGRESUME;
123 void resume_isr() __interrupt RESUME_ISR {
127 void sudav_isr() __interrupt SUDAV_ISR {
131 void usbreset_isr() __interrupt USBRESET_ISR {
132 handle_hispeed(FALSE);
135 void hispeed_isr() __interrupt HISPEED_ISR {
136 handle_hispeed(TRUE);
140 void suspend_isr() __interrupt SUSPEND_ISR {
145 void timer2_isr() __interrupt TF2_ISR {
148 if (--ledcounter == 0) {
157 * Copyright (C) 2009 Ubixum, Inc.
158 * Copyright (C) 2015 Jochen Hoenicke
160 * This library is free software; you can redistribute it and/or
161 * modify it under the terms of the GNU Lesser General Public
162 * License as published by the Free Software Foundation; either
163 * version 2.1 of the License, or (at your option) any later version.
165 * This library is distributed in the hope that it will be useful,
166 * but WITHOUT ANY WARRANTY; without even the implied warranty of
167 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
168 * Lesser General Public License for more details.
170 * You should have received a copy of the GNU Lesser General Public
171 * License along with this library; if not, write to the Free Software
172 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
175 #include <fx2macros.h>
178 #ifdef DEBUG_FIRMWARE
184 // change to support as many interfaces as you need
185 BYTE altiface = 0; // alt interface
186 extern volatile WORD ledcounter;
190 /* This sets three bits for each channel, one channel at a time.
191 * For channel 0 we want to set bits 5, 6 & 7
192 * For channel 1 we want to set bits 2, 3 & 4
194 * We convert the input values that are strange due to original firmware code into the value of the three bits as follows:
201 * The third bit is always zero since there are only four outputs connected in the serial selector chip.
203 * The multiplication of the converted value by 0x24 sets the relevant bits in
204 * both channels and then we mask it out to only affect the channel currently
207 BOOL set_voltage(BYTE channel, BYTE val)
227 mask = channel ? 0xe0 : 0x1c;
228 IOC = (IOC & ~mask) | (bits & mask);
232 BOOL set_numchannels(BYTE numchannels)
234 if (numchannels == 1 || numchannels == 2) {
235 BYTE fifocfg = 7 + numchannels;
236 EP2FIFOCFG = fifocfg;
237 EP6FIFOCFG = fifocfg;
267 void start_sampling()
272 for (i = 0; i < 1000; i++);
273 while (!(GPIFTRIG & 0x80)) {
292 extern __code BYTE highspd_dscr;
293 extern __code BYTE fullspd_dscr;
294 void select_interface(BYTE alt)
296 const BYTE *pPacketSize = (USBCS & bmHSM ? &highspd_dscr : &fullspd_dscr)
297 + (9 + 16*alt + 9 + 4);
305 EP6AUTOINLENL = pPacketSize[0];
306 EP6AUTOINLENH = pPacketSize[1];
313 EP2AUTOINLENL = pPacketSize[0];
314 EP2AUTOINLENH = pPacketSize[1] & 0x7;
315 EP2ISOINPKTS = (pPacketSize[1] >> 3) + 1;
319 const struct samplerate_info {
328 { 48,0x80, 0, 3, 0, 0x00, 0xea },
329 { 30,0x80, 0, 3, 0, 0x00, 0xaa },
330 { 24, 1, 0, 2, 1, 0x40, 0xca },
331 { 16, 1, 1, 2, 0, 0x40, 0xca },
332 { 12, 2, 1, 2, 0, 0x40, 0xca },
333 { 8, 3, 2, 2, 0, 0x40, 0xca },
334 { 4, 6, 5, 2, 0, 0x40, 0xca },
335 { 2, 12, 11, 2, 0, 0x40, 0xca },
336 { 1, 24, 23, 2, 0, 0x40, 0xca },
337 { 50, 48, 47, 2, 0, 0x40, 0xca },
338 { 20, 120, 119, 2, 0, 0x40, 0xca },
339 { 10, 240, 239, 2, 0, 0x40, 0xca }
342 BOOL set_samplerate(BYTE rate)
345 while (samplerates[i].rate != rate) {
347 if (i == sizeof(samplerates)/sizeof(samplerates[0]))
351 IFCONFIG = samplerates[i].ifcfg;
357 /* The program for low-speed, e.g. 1 MHz, is
358 * wait 24, CTL2=0, FIFO
362 * The program for 24 MHz is
363 * wait 1, CTL2=0, FIFO
366 * The program for 30/48 MHz is:
367 * jump 0, CTL2=Z, FIFO, LOOP
370 EXTAUTODAT2 = samplerates[i].wait0;
371 EXTAUTODAT2 = samplerates[i].wait1;
379 EXTAUTODAT2 = samplerates[i].opc0;
380 EXTAUTODAT2 = samplerates[i].opc1;
388 EXTAUTODAT2 = samplerates[i].out0;
406 for (i = 0; i < 96; i++)
411 BOOL handle_get_descriptor() {
415 //************************** Configuration Handlers *****************************
417 // set *alt_ifc to the current alt interface for ifc
418 BOOL handle_get_interface(BYTE ifc, BYTE* alt_ifc) {
419 (void) ifc; // ignore unused parameter
423 // return TRUE if you set the interface requested
424 // NOTE this function should reconfigure and reset the endpoints
425 // according to the interface descriptors you provided.
426 BOOL handle_set_interface(BYTE ifc,BYTE alt_ifc) {
427 printf ( "Set Interface.\n" );
429 select_interface(alt_ifc);
434 // handle getting and setting the configuration
435 // 1 is the default. We don't support multiple configurations.
436 BYTE handle_get_configuration() {
440 BOOL handle_set_configuration(BYTE cfg) {
441 (void) cfg; // ignore unused parameter
446 //******************* VENDOR COMMAND HANDLERS **************************
448 BOOL handle_vendorcommand(BYTE cmd) {
459 while (EP0CS & bmEPBUSY);
460 set_voltage(cmd - 0xe0, EP0BUF[0]);
465 while (EP0CS & bmEPBUSY);
466 set_samplerate(EP0BUF[0]);
471 while (EP0CS & bmEPBUSY);
478 while (EP0CS & bmEPBUSY);
479 set_numchannels(EP0BUF[0]);
482 return FALSE; // not handled by handlers
485 //******************** INIT ***********************
491 // in idle mode tristate all outputs
495 GPIFREADYSTAT = 0x00;
504 printf ( "Initialization Done.\n" );