Tons of edits...
rearranged some of the .h files, created dictionary file to list all dictionaries of opcodes.
moved error codes to shared file so host can interpret firmware error codes.
created firmware usb.c/h to handle usb operations (didn't move as git seems to think..)
cleaned up fw main function and file.
host usb_operations, created USBrequest struct type to more easily handle all transfer info.
Currently able to send pinport commands and read back return values from retro prog.
Just need to start writting functions to send opcodes and start actually preforming some cartridge operations.
This commit is contained in:
parent
53578116f1
commit
dae63f73b0
|
|
@ -1,3 +1,5 @@
|
|||
#ifndef _logic_h
|
||||
#define _logic_h
|
||||
|
||||
#define LO 0x00
|
||||
#define HI 0xFF
|
||||
|
|
@ -6,10 +8,4 @@
|
|||
#define IP 0x00
|
||||
#define OP 0xFF
|
||||
|
||||
#define SUCCESS 0x00
|
||||
#define ERR_UNKN_PP_OPCODE_ONLY 1
|
||||
#define ERR_UNKN_PP_OPCODE_8BOP 2
|
||||
#define ERR_UNKN_PP_OPCODE_16BOP 3
|
||||
#define ERR_UNKN_PP_OPCODE_24BOP 4
|
||||
#define ERR_UNKN_PP_OPCODE_8BRV 5
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,127 +1,40 @@
|
|||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "usbdrv.h"
|
||||
#include "io.h"
|
||||
#include "shared_usb_commands.h"
|
||||
#include "pinport.h"
|
||||
|
||||
|
||||
//USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]);
|
||||
/* This function is called when the driver receives a SETUP transaction from
|
||||
* the host which is not answered by the driver itself (in practice: class and
|
||||
* vendor requests). All control transfers start with a SETUP transaction where
|
||||
* the host communicates the parameters of the following (optional) data
|
||||
* transfer. The SETUP data is available in the 'data' parameter which can
|
||||
* (and should) be casted to 'usbRequest_t *' for a more user-friendly access
|
||||
* to parameters.
|
||||
*
|
||||
* If the SETUP indicates a control-in transfer, you should provide the
|
||||
* requested data to the driver. There are two ways to transfer this data:
|
||||
* (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data
|
||||
* block and return the length of the data in 'usbFunctionSetup()'. The driver
|
||||
* will handle the rest. Or (2) return USB_NO_MSG in 'usbFunctionSetup()'. The
|
||||
* driver will then call 'usbFunctionRead()' when data is needed. See the
|
||||
* documentation for usbFunctionRead() for details.
|
||||
*
|
||||
* If the SETUP indicates a control-out transfer, the only way to receive the
|
||||
* data from the host is through the 'usbFunctionWrite()' call. If you
|
||||
* implement this function, you must return USB_NO_MSG in 'usbFunctionSetup()'
|
||||
* to indicate that 'usbFunctionWrite()' should be used. See the documentation
|
||||
* of this function for more information. If you just want to ignore the data
|
||||
* sent by the host, return 0 in 'usbFunctionSetup()'.
|
||||
*
|
||||
* Note that calls to the functions usbFunctionRead() and usbFunctionWrite()
|
||||
* are only done if enabled by the configuration in usbconfig.h.
|
||||
*/
|
||||
USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||
//cast incoming data into the the usb setup packet it is
|
||||
usbRequest_t *spacket = (void *)data;
|
||||
//typedef struct usbRequest{
|
||||
// uchar bmRequestType;
|
||||
// uchar bRequest;
|
||||
// usbWord_t wValue;
|
||||
// usbWord_t wIndex;
|
||||
// usbWord_t wLength;
|
||||
//}usbRequest_t;
|
||||
|
||||
switch(spacket->bRequest) {
|
||||
case REQ_LED_ON:
|
||||
_LED_ON(); //from macros
|
||||
break;
|
||||
case REQ_LED_OFF:
|
||||
_LED_OFF();
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0; //ignore any data from the host for now
|
||||
}
|
||||
|
||||
|
||||
//USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len);
|
||||
/* This function is called by the driver to ask the application for a control
|
||||
* transfer's payload data (control-in). It is called in chunks of up to 8
|
||||
* bytes each. You should copy the data to the location given by 'data' and
|
||||
* return the actual number of bytes copied. If you return less than requested,
|
||||
* the control-in transfer is terminated. If you return 0xff, the driver aborts
|
||||
* the transfer with a STALL token.
|
||||
* In order to get usbFunctionRead() called, define USB_CFG_IMPLEMENT_FN_READ
|
||||
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup()..
|
||||
*/
|
||||
USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len) {
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
//USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len);
|
||||
/* This function is called by the driver to provide a control transfer's
|
||||
* payload data (control-out). It is called in chunks of up to 8 bytes. The
|
||||
* total count provided in the current control transfer can be obtained from
|
||||
* the 'length' property in the setup data. If an error occurred during
|
||||
* processing, return 0xff (== -1). The driver will answer the entire transfer
|
||||
* with a STALL token in this case. If you have received the entire payload
|
||||
* successfully, return 1. If you expect more data, return 0. If you don't
|
||||
* know whether the host will send more data (you should know, the total is
|
||||
* provided in the usbFunctionSetup() call!), return 1.
|
||||
* NOTE: If you return 0xff for STALL, 'usbFunctionWrite()' may still be called
|
||||
* for the remaining data. You must continue to return 0xff for STALL in these
|
||||
* calls.
|
||||
* In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE
|
||||
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup()..
|
||||
*/
|
||||
USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
|
||||
return 1; //"don't know how much data coming
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
int __attribute__((noreturn)) main(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
//enable watchdog timer with 1 second timeout
|
||||
|
||||
//set watch dog timer with 1 second timer
|
||||
wdt_enable(WDTO_1S);
|
||||
/* Even if you don't use the watchdog, turn it off here. On newer devices,
|
||||
* the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
|
||||
*/
|
||||
/* RESET status: all port bits are inputs without pull-up.
|
||||
* That's the way we need D+ and D-. Therefore we don't need any
|
||||
* additional hardware initialization.
|
||||
*/
|
||||
|
||||
//need USB pins input w/o pullup which is default at startup.
|
||||
//So further HW init is not needed/desired.
|
||||
//odDebugInit(); //intialize debuging printing via serial port
|
||||
//DBG1(0x00, 0, 0); //debug serial op: main starts
|
||||
|
||||
//initialize V-USB driver
|
||||
usbInit();
|
||||
|
||||
//enforce re-enumeration
|
||||
//interupts must be disabled!
|
||||
//initialize V-usb driver before interupts enabled and entering main loop
|
||||
usbInit();
|
||||
//disconnect from host enforce re-enumeration, interupts must be disabled during this.
|
||||
usbDeviceDisconnect();
|
||||
|
||||
i = 0;
|
||||
while (--i) {
|
||||
//fake USB disconnect for >250 ms
|
||||
//without WDT timing out
|
||||
wdt_reset();
|
||||
_delay_ms(1);
|
||||
}
|
||||
//fake USB disconnect for over 250ms
|
||||
uint8_t index = 0;
|
||||
while(--index){ //loop 256 times
|
||||
wdt_reset(); //keep wdt happy during this time
|
||||
_delay_ms(1); //delay 256msec
|
||||
}
|
||||
|
||||
//reconnect to host
|
||||
usbDeviceConnect();
|
||||
|
||||
//intialize i/o to pullup state
|
||||
|
|
@ -131,22 +44,20 @@ int main()
|
|||
_LED_OP();
|
||||
//boot with LED on to differentiate bettwen BL/RUN
|
||||
_LED_ON();
|
||||
|
||||
|
||||
//enable interrupts
|
||||
sei();
|
||||
|
||||
//=================
|
||||
//MAIN LOOP
|
||||
//=================
|
||||
while(1) {
|
||||
while (1) {
|
||||
|
||||
//reset WDT
|
||||
wdt_reset();
|
||||
//pet the watch doggie to keep him happy
|
||||
wdt_reset();
|
||||
|
||||
//V-USB driver poll
|
||||
usbPoll();
|
||||
|
||||
}//End MAIN LOOP
|
||||
|
||||
return 0;
|
||||
//must call at regular intervals no longer than 50msec
|
||||
//checks for setup packets from what I understand
|
||||
usbPoll();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
#include <avr/io.h>
|
||||
#include "logic.h"
|
||||
#include "pinport.h"
|
||||
#include "shared_pinport.h"
|
||||
|
||||
//This file was created based on pinport.h
|
||||
//the close relationship between these two files must be kept in mind when making changes.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <avr/io.h>
|
||||
#include "logic.h"
|
||||
#include "shared_errors.h"
|
||||
#include "shared_dict_pinport.h"
|
||||
|
||||
uint8_t pinport_opcode_only( uint8_t opcode );
|
||||
uint8_t pinport_opcode_8b_operand( uint8_t opcode, uint8_t operand );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,168 @@
|
|||
|
||||
#include "usb.h"
|
||||
|
||||
#include "pinport.h"
|
||||
|
||||
//USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]);
|
||||
/* This function is called when the driver receives a SETUP transaction from
|
||||
* the host which is not answered by the driver itself (in practice: class and
|
||||
* vendor requests). All control transfers start with a SETUP transaction where
|
||||
* the host communicates the parameters of the following (optional) data
|
||||
* transfer. The SETUP data is available in the 'data' parameter which can
|
||||
* (and should) be casted to 'usbRequest_t *' for a more user-friendly access
|
||||
* to parameters.
|
||||
*
|
||||
* If the SETUP indicates a control-in transfer, you should provide the
|
||||
* requested data to the driver. There are two ways to transfer this data:
|
||||
* (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data
|
||||
* block and return the length of the data in 'usbFunctionSetup()'. The driver
|
||||
* will handle the rest. Or (2) return USB_NO_MSG in 'usbFunctionSetup()'. The
|
||||
* driver will then call 'usbFunctionRead()' when data is needed. See the
|
||||
* documentation for usbFunctionRead() for details.
|
||||
*
|
||||
* If the SETUP indicates a control-out transfer, the only way to receive the
|
||||
* data from the host is through the 'usbFunctionWrite()' call. If you
|
||||
* implement this function, you must return USB_NO_MSG in 'usbFunctionSetup()'
|
||||
* to indicate that 'usbFunctionWrite()' should be used. See the documentation
|
||||
* of this function for more information. If you just want to ignore the data
|
||||
* sent by the host, return 0 in 'usbFunctionSetup()'.
|
||||
*
|
||||
* Note that calls to the functions usbFunctionRead() and usbFunctionWrite()
|
||||
* are only done if enabled by the configuration in usbconfig.h.
|
||||
*/
|
||||
|
||||
//typedef struct usbRequest{
|
||||
// uchar bmRequestType;
|
||||
// uchar bRequest;
|
||||
// usbWord_t wValue;
|
||||
// usbWord_t wIndex;
|
||||
// usbWord_t wLength;
|
||||
//}usbRequest_t;
|
||||
|
||||
#define ENDPOINT_BIT 0x80 //Bit 7 of bmRequest type determines endpoint
|
||||
#define ENDPOINT_IN 0x80 //In: device-to-host.
|
||||
#define ENDPOINT_OUT 0x00 //Out: host-to-device.
|
||||
|
||||
|
||||
typedef struct setup_packet{
|
||||
uint8_t bmRequestType; //contains endpoint
|
||||
uint8_t bRequest; //designates dictionary of opcode
|
||||
uint8_t opcode; //wValueLSB (little endian)
|
||||
uint8_t wValueMSB; //expansion byte
|
||||
uint8_t wIndexLSB; //operand LSB
|
||||
uint8_t wIndexMSB; //operand MSB
|
||||
uint16_t wLength;
|
||||
}setup_packet;
|
||||
|
||||
USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||
|
||||
//cast incoming data into the the usb setup packet it is
|
||||
setup_packet *spacket = (void *)data;
|
||||
|
||||
//8 Byte buffer to be used for returning error code and return values
|
||||
//must be static so driver can still access after function return
|
||||
static uchar rv[8];
|
||||
//rv[0] contains opcode success/error code
|
||||
//rv[1-7] available for return data, start with index 1
|
||||
|
||||
//number of bytes to return to host
|
||||
uint8_t rlen = 0;
|
||||
|
||||
//determine endpoint IN/OUT
|
||||
if ( (spacket->bmRequestType & ENDPOINT_BIT) == ENDPOINT_IN ) {
|
||||
//read from device request
|
||||
//send error code and return value
|
||||
rlen = 1; //min value of error code
|
||||
} else {
|
||||
//write to device request
|
||||
//host doesn't want to waste time with reading back error codes
|
||||
rlen = 0;
|
||||
//must also come here if opcode has payload coming in data packets to follow
|
||||
//in that case host would have to send follow up read request to get error code
|
||||
}
|
||||
|
||||
|
||||
switch(spacket->bRequest) {
|
||||
case PINPORT:
|
||||
if((spacket->opcode > PP_OPCODE_ONLY_MIN)
|
||||
& (spacket->opcode < PP_OPCODE_ONLY_MAX)) {
|
||||
rv[0] = pinport_opcode_only( spacket->opcode );
|
||||
|
||||
} else if ((spacket->opcode > PP_OPCODE_8BOP_MIN)
|
||||
& (spacket->opcode < PP_OPCODE_8BOP_MAX)) {
|
||||
rv[0] = pinport_opcode_8b_operand( spacket->opcode, spacket->wIndexLSB );
|
||||
|
||||
} else if ((spacket->opcode > PP_OPCODE_16BOP_MIN)
|
||||
& (spacket->opcode < PP_OPCODE_16BOP_MAX)) {
|
||||
rv[0] = pinport_opcode_16b_operand( spacket->opcode,
|
||||
spacket->wIndexMSB, spacket->wIndexLSB );
|
||||
|
||||
} else if ((spacket->opcode > PP_OPCODE_24BOP_MIN)
|
||||
& (spacket->opcode < PP_OPCODE_24BOP_MAX)) {
|
||||
rv[0] = pinport_opcode_24b_operand( spacket->opcode,
|
||||
spacket->wValueMSB, spacket->wIndexMSB, spacket->wIndexLSB );
|
||||
|
||||
} else if ((spacket->opcode > PP_OPCODE_8BRV_MIN)
|
||||
& (spacket->opcode < PP_OPCODE_8BRV_MAX)) {
|
||||
rv[0] = pinport_opcode_8b_return( spacket->opcode, &rv[1]);
|
||||
//return error code plus opcode return value
|
||||
rlen ++;
|
||||
}
|
||||
break; //end of PINPORT
|
||||
default:
|
||||
//request (aka dictionary) is unknown
|
||||
rv[0] = ERR_UNKN_DICTIONARY;
|
||||
}
|
||||
|
||||
/* (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data
|
||||
* block and return the length of the data in 'usbFunctionSetup()'. The driver
|
||||
* will handle the rest. Or (2) return USB_NO_MSG in 'usbFunctionSetup()'. The
|
||||
* driver will then call 'usbFunctionRead()' when data is needed. See the
|
||||
*/
|
||||
usbMsgPtr = rv;
|
||||
return rlen;
|
||||
|
||||
//return USB_NO_MSG;
|
||||
//Don't have a use for usbFunctionRead yet.. Not expecting to anytime soon
|
||||
//probably easier and perhaps faster to send cart dump commands and store rom image
|
||||
//in a buffer to be returned here.
|
||||
}
|
||||
|
||||
|
||||
//USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len);
|
||||
/* This function is called by the driver to ask the application for a control
|
||||
* transfer's payload data (control-in). It is called in chunks of up to 8
|
||||
* bytes each. You should copy the data to the location given by 'data' and
|
||||
* return the actual number of bytes copied. If you return less than requested,
|
||||
* the control-in transfer is terminated. If you return 0xff, the driver aborts
|
||||
* the transfer with a STALL token.
|
||||
* In order to get usbFunctionRead() called, define USB_CFG_IMPLEMENT_FN_READ
|
||||
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup()..
|
||||
*/
|
||||
USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len) {
|
||||
//this function should only get called if usbFunctionSetup returns USB_NO_MSG
|
||||
// data[0] = 0xAA;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
//USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len);
|
||||
/* This function is called by the driver to provide a control transfer's
|
||||
* payload data (control-out). It is called in chunks of up to 8 bytes. The
|
||||
* total count provided in the current control transfer can be obtained from
|
||||
* the 'length' property in the setup data. If an error occurred during
|
||||
* processing, return 0xff (== -1). The driver will answer the entire transfer
|
||||
* with a STALL token in this case. If you have received the entire payload
|
||||
* successfully, return 1. If you expect more data, return 0. If you don't
|
||||
* know whether the host will send more data (you should know, the total is
|
||||
* provided in the usbFunctionSetup() call!), return 1.
|
||||
* NOTE: If you return 0xff for STALL, 'usbFunctionWrite()' may still be called
|
||||
* for the remaining data. You must continue to return 0xff for STALL in these
|
||||
* calls.
|
||||
* In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE
|
||||
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup()..
|
||||
*/
|
||||
USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
|
||||
return 1; //"don't know how much data coming
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef _usb_h
|
||||
#define _usb_h
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "usbdrv.h"
|
||||
#include "logic.h"
|
||||
#include "shared_dictionaries.h"
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -14,9 +14,7 @@
|
|||
|
||||
#include "usb_operations.h"
|
||||
#include "write_operations.h"
|
||||
|
||||
//TODO remove once commands removed from main
|
||||
#include "shared_usb_commands.h"
|
||||
#include "shared_dictionaries.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
|
@ -84,35 +82,72 @@ int main(int argc, char *argv[])
|
|||
|
||||
//context set to NULL since only acting as single user of libusb
|
||||
libusb_context *context = NULL;
|
||||
//create usb device handle pointer to interact with retro-prog
|
||||
libusb_device_handle *rprog_handle = NULL;
|
||||
|
||||
rprog_handle = open_usb_device( context );
|
||||
check( rprog_handle != NULL, "Unable to open INL retro-prog usb device handle.");
|
||||
|
||||
//create USBtransfer struct to hold all transfer info
|
||||
USBtransfer *transfer = malloc( sizeof(USBtransfer));
|
||||
check_mem(transfer);
|
||||
|
||||
//create usb device handle pointer to interact with retro-prog
|
||||
//libusb_device_handle *rprog_handle = NULL;
|
||||
transfer->handle = NULL;
|
||||
|
||||
|
||||
//open INL retro prog with firmware version 2.0 or greater
|
||||
transfer->handle = open_usb_device( context );
|
||||
check( transfer->handle != NULL, "Unable to open INL retro-prog usb device handle.");
|
||||
|
||||
int xfr_cnt = 0;
|
||||
//uint8_t buffer8[8]; //8 is max payload for low speed devices' data packet
|
||||
//uint8_t buffer128[128]; //128 largest power of 2 for non-LONG_TRANSFERS with V-USB
|
||||
uint8_t buffer254[254]; //254 is max for non-LONG_TRANSFERS with V-USB
|
||||
//uint8_t buffer16k[16384]; //16384 is max for LONG_TRANSFERS with V-USB
|
||||
uint8_t rbuf[8];
|
||||
|
||||
if (o_flag) { //ON send REQ_LED_ON
|
||||
xfr_cnt = usb_write_to_device( rprog_handle,
|
||||
REQ_LED_ON, (unsigned char *)buffer254, sizeof(buffer254) );
|
||||
printf("total bytes xfrd: %d \n", xfr_cnt);
|
||||
int i;
|
||||
printf("before return buffer: ");
|
||||
for (i = 0; i < 8; i++) {
|
||||
rbuf[i] = 7;
|
||||
printf("%x ", rbuf[i]);
|
||||
}
|
||||
if (f_flag) { //OFF send REQ_LED_OFF
|
||||
xfr_cnt = usb_write_to_device( rprog_handle,
|
||||
REQ_LED_OFF, (unsigned char *)buffer254, sizeof(buffer254) );
|
||||
printf("total bytes xfrd: %d \n", xfr_cnt);
|
||||
}
|
||||
if (w_value) { //OFF send REQ_LED_OFF
|
||||
check( write_file( rprog_handle, w_value, i_value, b_value) == SUCCESS,
|
||||
"Failed to write file: %s", w_value);
|
||||
printf("\n");
|
||||
|
||||
//handle simple LED ON/OFF within main for now
|
||||
if (o_flag | f_flag) {
|
||||
transfer->endpoint = USB_IN;
|
||||
transfer->request = PINPORT;
|
||||
if (o_flag) transfer->wValueLSB = LED_ON;
|
||||
if (f_flag) transfer->wValueLSB = LED_OFF;
|
||||
transfer->data = rbuf;
|
||||
transfer->wLength = 1;
|
||||
|
||||
//send command
|
||||
xfr_cnt = usb_transfer( transfer );
|
||||
}
|
||||
|
||||
printf("total bytes xfrd: %d \n", xfr_cnt);
|
||||
printf("after buffer: ");
|
||||
for (i = 0; i < 8; i++) {
|
||||
printf("%x ", rbuf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
close_usb( context, rprog_handle);
|
||||
|
||||
//if (o_flag) { //ON send REQ_LED_ON
|
||||
// xfr_cnt = usb_transfer( transfer.handle,
|
||||
// REQ_LED_ON,
|
||||
// (unsigned char *)buffer254, sizeof(buffer254) );
|
||||
// printf("total bytes xfrd: %d \n", xfr_cnt);
|
||||
//}
|
||||
//if (f_flag) { //OFF send REQ_LED_OFF
|
||||
// xfr_cnt = usb_write_to_device( transfer.handle,
|
||||
// REQ_LED_OFF, (unsigned char *)buffer254, sizeof(buffer254) );
|
||||
// printf("total bytes xfrd: %d \n", xfr_cnt);
|
||||
//}
|
||||
|
||||
//if (w_value) { //OFF send REQ_LED_OFF
|
||||
// check( write_file( transfer.handle, w_value, i_value, b_value) == SUCCESS,
|
||||
// "Failed to write file: %s", w_value);
|
||||
//}
|
||||
|
||||
|
||||
close_usb( context, transfer->handle);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -205,61 +205,77 @@ void close_usb(libusb_context *context, libusb_device_handle *handle)
|
|||
return;
|
||||
}
|
||||
|
||||
//int libusb_control_transfer (libusb_device_handle *dev_handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout)
|
||||
//
|
||||
//SETUP PACKET FIELDS:
|
||||
//bmRequestType: ORing of req type (STD/VENDOR), recipient (think we only care about DEVICE), endpoint direction IN-dev->host OUT-host->dev
|
||||
//bRequest: single byte that can signify any 'command' or 'request' we setup.
|
||||
//The wValue and wIndex fields allow parameters to be passed with the request. Think we can do whatever we want with these
|
||||
//wLength is used the specify the number of bytes to be transferred should there be a data phase.
|
||||
//wLength the length field for the setup packet. The data buffer should be at least this size.
|
||||
// USB 1.1 low speed standard limits to 8 bytes
|
||||
// V-USB seems to break this limit with max of 254 bytes (255 designates "USB_NO_MSG"
|
||||
// V-USB allows "LONG TRANSFERS" utilizing full 16bit wLength for upto 16384 bytes = exactly 16KBytes
|
||||
// although considering sram on AVR doesn't explode with long transfers and read/write functions are in 8byte chunks,
|
||||
// I think it really is limited to 8bytes
|
||||
// One idea to squeeze more data is have a request type defined that utilizes wValue and wIndex to gain 4bytes + 8buffer = 12bytes 50% gain
|
||||
// Not sure how to gain access to wValue/wIndex with vusb drivers...
|
||||
// answer: usbFunctionSetup will get called for every setup packet and pass all 8 bytes of setup packet
|
||||
// Can ultimately answer this question by counting how many startup packets are recieved by usbFunciton setup for transfers >8 bytes
|
||||
// If when sending >8 byte control transfers, a setup packet only comes once, then there is nothing to abuse
|
||||
// however if the same setup packet gets sent for every 8 bytes, it would be better to only perform 8byte transfers and stuff
|
||||
// 4 more bytes in wValue and wIndex fields to increase throughput by ~50%!!!
|
||||
// Testing shows that usbFunctionSetup only gets called once for transfers of 254 bytes
|
||||
// So there is only one setup packet for multiple data packets of 8bytes each
|
||||
//
|
||||
//Still not sure increasing transfer length doesn't simply break up into bunch of small 8byte transfers although it doesn't sound like it.
|
||||
//245byte limit is kind of a pain.. but wValue/wIndex fields could be abused to send 256 bytes
|
||||
//Long transfers apparently max out speed @ 24KBps with 300 bytes: https://forums.obdev.at/viewtopic.php?t=3059
|
||||
//
|
||||
//PAYLOAD:
|
||||
//data: a suitably-sized data buffer for either input or output (depending on direction bits within bmRequestType)
|
||||
//
|
||||
//TIMEOUT:
|
||||
//timeout: (in millseconds) that this function should wait before giving up due to no response being received.
|
||||
// For an unlimited timeout, use value 0
|
||||
// USB nutshell: A compliant host requires control transfer response within 5sec
|
||||
//
|
||||
//RETURN:
|
||||
// Returns on success, the number of bytes actually transferred
|
||||
// LIBUSB_ERROR_TIMEOUT if the transfer timed out
|
||||
// LIBUSB_ERROR_PIPE if the control request was not supported by the device
|
||||
// LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
|
||||
// another LIBUSB_ERROR code on other failures
|
||||
int usb_write_to_device( libusb_device_handle *handle, int command, unsigned char *data, uint16_t len )
|
||||
|
||||
/* USB transfer
|
||||
*Desc: primary means of sending and recieving commands and data to retro programmer
|
||||
* makes calls to libusb drivers to send/recieve control transfer setup, data, and status packets
|
||||
* See USBtransfer struct explaination in usb_operations.h for more details
|
||||
*Pre: libusb must be initialized
|
||||
* USBtransfer struct must be initialized as follows:
|
||||
* -handle must point to open usb device
|
||||
* -endpoint "direction" must be defined
|
||||
* -request must be a valid and defined in a command dictionary
|
||||
* -wValue and wIndex must be valid as defined by request dictionary
|
||||
* -WLength must equal number of bytes to be transferred with max of 254
|
||||
* -data points to buffer of raw data to send for reads or dump into for reads
|
||||
* if wLength is zero, data can be NULL
|
||||
*Post: USB control transfer complete (setup, data, and status packets)
|
||||
* data buffer pointed by USBtransfer struct filled with read data for USB_IN requests.
|
||||
* USBtransfer struct is unmodified can be reused for identical transfers with different payload
|
||||
* libusb is still initialized and open
|
||||
*Rtn: Number of bytes transferred on success (positive)
|
||||
* ERROR if unable to transfer USBtransfer's wLength number of bytes
|
||||
* prints libusb_error if there was usb problem
|
||||
*/
|
||||
int usb_transfer( USBtransfer *transfer )
|
||||
{
|
||||
//TODO translate command into request, value, index, etc
|
||||
uint8_t request = command;
|
||||
uint16_t wValue = 0; //setup packet wValue field
|
||||
uint16_t wIndex = 0; //setup packet wIndex field
|
||||
check( transfer->wLength <= MAX_VUSB, "Can't transfer more than %d bytes!", MAX_VUSB);
|
||||
|
||||
int xfr_cnt = libusb_control_transfer( handle,
|
||||
if ( transfer->wLength != 0) {
|
||||
check( transfer->data != NULL, "data buffer isn't initialized it's: %s", transfer->data);
|
||||
} else {
|
||||
debug("USB transfer with no data payload.");
|
||||
}
|
||||
//TODO create a check to verify dictionary is defined, and opcode/operands are valid
|
||||
//TODO also check to ensure opcode supports endpoint direction
|
||||
//many operations could be performed with IN/OUT and no data packet
|
||||
//but all avr operations should have a return value success/error code
|
||||
//one way to control whether those retrun values are read back is endpoint direction
|
||||
|
||||
uint16_t wValue = transfer->wValueMSB;
|
||||
wValue = wValue << 8;
|
||||
wValue |= transfer->wValueLSB;
|
||||
|
||||
uint16_t wIndex = transfer->wIndexMSB;
|
||||
wIndex = wIndex << 8;
|
||||
wIndex |= transfer->wIndexLSB;
|
||||
|
||||
debug("request h: %x d: %d", transfer->request, transfer->request);
|
||||
debug("wValueMSB h: %x d: %d", transfer->wValueMSB, transfer->wValueMSB);
|
||||
debug("wValueLSB h: %x d: %d", transfer->wValueLSB, transfer->wValueLSB);
|
||||
debug("wValue h: %x", wValue);
|
||||
debug("wValue d: %d", wValue);
|
||||
debug("wIndexMSB h: %x d: %d", transfer->wIndexMSB, transfer->wIndexMSB);
|
||||
debug("wIndexLSB h: %x d: %d", transfer->wIndexLSB, transfer->wIndexLSB);
|
||||
debug("wIndex h: %x", wIndex);
|
||||
debug("wIndex d: %d", wIndex);
|
||||
|
||||
int xfr_cnt = libusb_control_transfer(
|
||||
transfer->handle,
|
||||
//Request type: vendor (as we define), recip: device, out: host->device
|
||||
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
|
||||
request, wValue, wIndex, data, len, SEC_5);
|
||||
//LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
|
||||
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | transfer->endpoint,
|
||||
//request, wValue, wIndex, data, len, SEC_5);
|
||||
transfer->request,
|
||||
wValue, wIndex,
|
||||
transfer->data,
|
||||
transfer->wLength,
|
||||
TIMEOUT_1_SEC);
|
||||
|
||||
debug("%d bytes transfered", xfr_cnt);
|
||||
check( xfr_cnt >=0, "Write xfr failed with libusb error: %s", libusb_strerror(xfr_cnt));
|
||||
check( xfr_cnt == len, "Write transfer failed only %dB sent when expecting %dB", xfr_cnt, len);
|
||||
check( xfr_cnt == transfer->wLength, "Write transfer failed only %d Bytes sent expected %dBytes",
|
||||
xfr_cnt, transfer->wLength);
|
||||
|
||||
return xfr_cnt;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,13 +8,14 @@
|
|||
#include <errno.h>
|
||||
#include <libusb.h>
|
||||
|
||||
//list of included dictionaries for defining request, wValue, and wIndex fields
|
||||
#include "shared_dictionaries.h"
|
||||
|
||||
//uncomment to DEBUG this file alone
|
||||
//#define DEBUG
|
||||
#define DEBUG
|
||||
//"make debug" to get DEBUG msgs on entire program
|
||||
#include "dbg.h"
|
||||
|
||||
#include "shared_usb_commands.h"
|
||||
|
||||
//control transfer request types
|
||||
//uint8_t libusb_control_setup::bmRequestType
|
||||
//Request type.
|
||||
|
|
@ -32,16 +33,115 @@
|
|||
//LIBUSB_RECIPIENT_ENDPOINT Endpoint.
|
||||
//LIBUSB_RECIPIENT_OTHER Other.
|
||||
//
|
||||
//LIBUSB_ENDPOINT_IN In: device-to-host.
|
||||
//LIBUSB_ENDPOINT_OUT Out: host-to-device.
|
||||
//LIBUSB_ENDPOINT_IN 0x80 In: device-to-host.
|
||||
//LIBUSB_ENDPOINT_OUT 0x00 Out: host-to-device.
|
||||
#define USB_IN LIBUSB_ENDPOINT_IN
|
||||
#define USB_OUT LIBUSB_ENDPOINT_OUT
|
||||
|
||||
//USB timeout
|
||||
#define SEC_5 5000
|
||||
#define TIMEOUT_1_SEC 1000
|
||||
#define TIMEOUT_5_SEC 5000
|
||||
|
||||
//Max transfer length
|
||||
#define MAX_VUSB 245 //Max VUSB transfers without long transfers enabled
|
||||
#define USB_NO_MSG 255 //designates transfer with no message
|
||||
#define MAX_VUSB_LONGXFR 16384 //16KByte biggest value 16bit wLength can hold
|
||||
|
||||
//typedef struct USBtransfer {
|
||||
//This is the primary USB request struct used by host app used for all application USB communications.
|
||||
//handle is retrieved from open_usb_device gives us a means to point to the opened USB device.
|
||||
//The remaining elements are all directly fed to the outgoing USB setup & data packets to/from the device.
|
||||
// Every USB transfer starts with host sending one of these setup packets to the device.
|
||||
// the setup packets are unidirectinal always coming from the bus master (host).
|
||||
// The data packet(s) for the transfer then follow and are bidirectional.
|
||||
// The drivers handle final NACK/ACK/STALL packet for the most part..
|
||||
// Note V-USB mcu driver doesn't have time to check CRC so it sends ACK assuming no corruption.
|
||||
//endpoint basically this is the direction of the data packet to follow.
|
||||
// the usb device has a OUT and IN endpoint buffer and this defines which is being accessed.
|
||||
// OUT "out of host" is for writting data to the usb device.
|
||||
// IN "in to host" is for reading data from the usb device.
|
||||
// endpoint is the only portion of setup packet's requestType field that isn't hardcoded.
|
||||
// Vendor request types used exclusively as they meet the our intent and 'hard coded' into this struct.
|
||||
// The recipient of this setup packet is also 'hard coded' to the usb device.
|
||||
//request is more like request type in this scope and designates the 'dictionary' containing the command.
|
||||
// pinport is the first dictionary of commands, more to come as things develop.
|
||||
// these requests/dictionaries define how the wValue and wIndex fields are utilized.
|
||||
// anything can be placed in the 4 bytes of wValue/wIndex as defined by the dictionary.
|
||||
//wValueMSB:wValueLSB
|
||||
// This is where the app places the 'command' being given to the retro programmer.
|
||||
// LSB is big enough for now and contains the actual opcode.
|
||||
// MSB is used as an overflow for operands/data if wIndex is not large enough.
|
||||
// future dicts with more than 256 opcodes could define some/all of MSB to contain the opcode as well.
|
||||
//wIndexMSB:wIndexLSB
|
||||
// This typically contains the operand/data for the opcode but could be used for anything
|
||||
// as defined by the opcode. Raw buffer data could even be placed here to cheat the 254 Byte transfer
|
||||
// limit of V-USB (w/o long xfrs), the two bytes of wIndex bring to full page of 256 Bytes.
|
||||
// Planning for this to contain the page index (aka memory addr) of the transmitted data buffer.
|
||||
//wLength must be set to the size of the data transfer to follow this setup packet in Bytes.
|
||||
// if wLength is >8, drivers split data into 8byte packets and final packet of < 8Bytes if needed.
|
||||
// with 16bit wLength 16KB transfers are largest possible, requires using long xfrs on device driver.
|
||||
// The max length without long xfrs is 254Bytes, value 255 is reserved for USB_NO_MSG.
|
||||
// This means wLength's MSByte is under utilized but prob shouldn't concern ourselves with that.
|
||||
//data is a pointer to the data buffer being sent for writes (OUT transfers).
|
||||
// read (IN transfers) utilize data pointer to pass location of where to dump read data.
|
||||
|
||||
typedef struct USBtransfer {
|
||||
libusb_device_handle *handle;
|
||||
uint8_t endpoint;
|
||||
uint8_t request;
|
||||
uint8_t wValueMSB;
|
||||
uint8_t wValueLSB;
|
||||
uint8_t wIndexMSB;
|
||||
uint8_t wIndexLSB;
|
||||
uint16_t wLength;
|
||||
unsigned char *data;
|
||||
} USBtransfer;
|
||||
|
||||
libusb_device_handle * open_usb_device( libusb_context *context );
|
||||
|
||||
void close_usb(libusb_context *context, libusb_device_handle *handle);
|
||||
|
||||
int usb_write_to_device( libusb_device_handle *handle, int command, unsigned char *data, uint16_t len );
|
||||
//int libusb_control_transfer (libusb_device_handle *dev_handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout)
|
||||
//
|
||||
//SETUP PACKET FIELDS:
|
||||
//bmRequestType: ORing of req type (STD/VENDOR), recipient (think we only care about DEVICE), endpoint direction IN-dev->host OUT-host->dev
|
||||
//bRequest: single byte that can signify any 'command' or 'request' we setup.
|
||||
//The wValue and wIndex fields allow parameters to be passed with the request. Think we can do whatever we want with these
|
||||
//wLength is used the specify the number of bytes to be transferred should there be a data phase.
|
||||
//wLength the length field for the setup packet. The data buffer should be at least this size.
|
||||
// USB 1.1 low speed standard limits to 8 bytes
|
||||
// V-USB seems to break this limit with max of 254 bytes (255 designates "USB_NO_MSG"
|
||||
// V-USB allows "LONG TRANSFERS" utilizing full 16bit wLength for upto 16384 bytes = exactly 16KBytes
|
||||
// although considering sram on AVR doesn't explode with long transfers and read/write functions are in 8byte chunks,
|
||||
// I think it really is limited to 8bytes
|
||||
// One idea to squeeze more data is have a request type defined that utilizes wValue and wIndex to gain 4bytes + 8buffer = 12bytes 50% gain
|
||||
// Not sure how to gain access to wValue/wIndex with vusb drivers...
|
||||
// answer: usbFunctionSetup will get called for every setup packet and pass all 8 bytes of setup packet
|
||||
// Can ultimately answer this question by counting how many startup packets are recieved by usbFunciton setup for transfers >8 bytes
|
||||
// If when sending >8 byte control transfers, a setup packet only comes once, then there is nothing to abuse
|
||||
// however if the same setup packet gets sent for every 8 bytes, it would be better to only perform 8byte transfers and stuff
|
||||
// 4 more bytes in wValue and wIndex fields to increase throughput by ~50%!!!
|
||||
// Testing shows that usbFunctionSetup only gets called once for transfers of 254 bytes
|
||||
// So there is only one setup packet for multiple data packets of 8bytes each
|
||||
//
|
||||
//Still not sure increasing transfer length doesn't simply break up into bunch of small 8byte transfers although it doesn't sound like it.
|
||||
//245byte limit is kind of a pain.. but wValue/wIndex fields could be abused to send 256 bytes
|
||||
//Long transfers apparently max out speed @ 24KBps with 300 bytes: https://forums.obdev.at/viewtopic.php?t=3059
|
||||
//
|
||||
//PAYLOAD:
|
||||
//data: a suitably-sized data buffer for either input or output (depending on direction bits within bmRequestType)
|
||||
//
|
||||
//TIMEOUT:
|
||||
//timeout: (in millseconds) that this function should wait before giving up due to no response being received.
|
||||
// For an unlimited timeout, use value 0
|
||||
// USB nutshell: A compliant host requires control transfer response within 5sec
|
||||
//
|
||||
//RETURN:
|
||||
// Returns on success, the number of bytes actually transferred
|
||||
// LIBUSB_ERROR_TIMEOUT if the transfer timed out
|
||||
// LIBUSB_ERROR_PIPE if the control request was not supported by the device
|
||||
// LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
|
||||
// another LIBUSB_ERROR code on other failures
|
||||
int usb_transfer( USBtransfer *transfer );
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ int write_file( libusb_device_handle *usbhandle, char *filename, char *ines_mapp
|
|||
int rv = 0;
|
||||
int index = 0;
|
||||
FILE *fileptr = NULL;
|
||||
uint8_t data[128];
|
||||
//warn uint8_t data[128];
|
||||
|
||||
//first open file
|
||||
fileptr = fopen( filename, "rb");
|
||||
|
|
@ -35,11 +35,11 @@ int write_file( libusb_device_handle *usbhandle, char *filename, char *ines_mapp
|
|||
//9: Flags 9
|
||||
//10: Flags 10 (unofficial)
|
||||
//11-15: Zero filled
|
||||
uint8_t num_prg_banks = header[4];
|
||||
uint8_t num_chr_banks = header[5];
|
||||
|
||||
int prg_size = num_prg_banks * SIZE_PRG_BANK;
|
||||
int chr_size = num_chr_banks * SIZE_CHR_BANK;
|
||||
//warn uint8_t num_prg_banks = header[4];
|
||||
//warn uint8_t num_chr_banks = header[5];
|
||||
//warn
|
||||
//warn int prg_size = num_prg_banks * SIZE_PRG_BANK;
|
||||
//warn int chr_size = num_chr_banks * SIZE_CHR_BANK;
|
||||
|
||||
//next check board inserted
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include <libusb.h>
|
||||
|
||||
#include "usb_operations.h"
|
||||
#include "shared_usb_commands.h"
|
||||
|
||||
//uncomment to DEBUG this file alone
|
||||
#define DEBUG
|
||||
|
|
|
|||
|
|
@ -1,5 +1,17 @@
|
|||
#ifndef _shared_pinport_h
|
||||
#define _shared_pinport_h
|
||||
#ifndef _shared_dict_pinport_h
|
||||
#define _shared_dict_pinport_h
|
||||
|
||||
//define dictionary's reference number in the shared_dictionaries.h file
|
||||
//then include this dictionary file in shared_dictionaries.h
|
||||
//The dictionary number is literally used as usb transfer request field
|
||||
//the opcodes and operands in this dictionary are fed directly into usb setup packet's wValue wIndex fields
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
// PINPORT DICTIONARY
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
|
||||
//This file was created based on firmware version of pinport.h and pinport.c
|
||||
//the close relationship between these two files must be kept in mind when making changes.
|
||||
|
|
@ -11,6 +23,7 @@
|
|||
|
||||
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
// OPCODES with no operand and no return value besides SUCCESS/ERROR_CODE
|
||||
//=============================================================================================
|
||||
|
|
@ -22,6 +35,10 @@
|
|||
// Current limit for these types of opcodes is 0-127
|
||||
// This allows for the MSB to be used for decoding pinport opcode to this type
|
||||
//
|
||||
// Detect this opcode/operand setup with opcode between the following defines:
|
||||
#define PP_OPCODE_ONLY_MIN 0x00
|
||||
#define PP_OPCODE_ONLY_MAX 0x7F
|
||||
//
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
|
||||
|
|
@ -230,14 +247,22 @@
|
|||
//=============================================================================================
|
||||
// OPCODES WITH OPERAND and no return value besides SUCCESS/ERROR_CODE
|
||||
//=============================================================================================
|
||||
//
|
||||
#define PP_OPCODE_8BOP_MIN 0x80
|
||||
#define PP_OPCODE_8BOP_MAX 0x9F
|
||||
// 0x80-0x9F: opcodes with 8bit operand
|
||||
// 0x80-8A are only ones currently in use
|
||||
//
|
||||
#define PP_OPCODE_16BOP_MIN 0xA0
|
||||
#define PP_OPCODE_16BOP_MAX 0xAF
|
||||
// 0xA0-0xAF: opcodes with 16bit operand
|
||||
// 0xA0-A2 are only ones currently in use
|
||||
//
|
||||
#define PP_OPCODE_24BOP_MIN 0xB0
|
||||
#define PP_OPCODE_24BOP_MAX 0xBF
|
||||
// 0xB0-0xBF: opcodes with 24bit operand
|
||||
// 0xA0 is currently only one in use
|
||||
//
|
||||
//
|
||||
// Current limit for these types of opcodes is 128-191 (0x80-0xBF)
|
||||
// This allows for the MSBs' to be used for decoding pinport opcode to this type
|
||||
//
|
||||
|
|
@ -287,9 +312,6 @@
|
|||
#define ctl_port_set 0x89
|
||||
#define aux_port_set 0x8A
|
||||
|
||||
//TODO consider listing AVR internal registers here..?
|
||||
//could be useful when utilizing SPI/I2C communications etc
|
||||
|
||||
|
||||
|
||||
//=================================
|
||||
|
|
@ -340,6 +362,9 @@
|
|||
//=============================================================================================
|
||||
// OPCODES with NO OPERAND but have RETURN VALUE plus SUCCESS/ERROR_CODE
|
||||
//=============================================================================================
|
||||
//
|
||||
#define PP_OPCODE_8BRV_MIN 0xC0
|
||||
#define PP_OPCODE_8BRV_MAX 0xFF
|
||||
// 0xC0-0xFF: opcodes with 8bit return value (plus SuCCESS/ERROR)
|
||||
// 0xC0-CB are only ones currently in use
|
||||
//
|
||||
|
|
@ -348,6 +373,9 @@
|
|||
//
|
||||
// Current limit for these types of opcodes is 192-255 (0xC0-0xFF)
|
||||
// This allows for the MSBs' to be used for decoding pinport opcode to this type
|
||||
// Detect this opcode/operand setup with opcode between the following defines:
|
||||
//
|
||||
// Detect this opcode/operand setup with opcode between the following defines:
|
||||
//
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
|
|
@ -395,11 +423,6 @@
|
|||
|
||||
|
||||
|
||||
//TODO consider listing AVR internal registers here..?
|
||||
//could be useful when utilizing SPI/I2C communications etc
|
||||
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
// OPCODES with OPERAND and RETURN VALUE plus SUCCESS/ERROR_CODE
|
||||
//=============================================================================================
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef _shared_dictionaries_h
|
||||
#define _shared_dictionaries_h
|
||||
|
||||
//list of dictionary reference numbers
|
||||
//these numbers literally sent in usb control transfer in request field
|
||||
//the included dictionaries define opcodes and operands contained in transfer wValue wIndex fields
|
||||
//they also define expected data buffer sizes and contents.
|
||||
|
||||
|
||||
#define PINPORT 1
|
||||
#include "shared_dict_pinport.h"
|
||||
//pinport dictionary has various commands giving low and mid level access to retro prog's i/o pins.
|
||||
//It also contains internal avr registers associated with the avr's io.
|
||||
//Access to other internal avr registers should be placed in other associated dictionaries.
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef _error_codes_h
|
||||
#define _error_codes_h
|
||||
|
||||
#define SUCCESS 0
|
||||
|
||||
//greater than 128 are possible avr return codes
|
||||
#define ERR_UNKN_DICTIONARY 128
|
||||
|
||||
#define ERR_UNKN_PP_OPCODE_ONLY 129
|
||||
#define ERR_UNKN_PP_OPCODE_8BOP 130
|
||||
#define ERR_UNKN_PP_OPCODE_16BOP 131
|
||||
#define ERR_UNKN_PP_OPCODE_24BOP 132
|
||||
#define ERR_UNKN_PP_OPCODE_8BRV 133
|
||||
|
||||
#endif
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef _shared_usb_commands_h
|
||||
#define _shared_usb_commands_h
|
||||
|
||||
#define REQ_LED_ON 1
|
||||
#define REQ_LED_OFF 2
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue