#include "main.h"#define USB_CON_SENSE_PIN PIN_D4#include <pic18_usb.h>#include "usbconfig.h"#include <usb.h>#include <usb.c>/* commands from USB, must e.g. match command ids in kernel driver */#define CMD_ECHO 0#define CMD_GET_FUNC 1#define CMD_SET_DELAY 2#define CMD_GET_STATUS 3#define CMD_I2C_IO 4#define CMD_I2C_BEGIN 1 // flag fo I2C_IO#define CMD_I2C_END 2 // flag fo I2C_IO/* linux kernel flags */#define I2C_M_TEN 0x10 /* we have a ten bit chip address */#define I2C_M_RD 0x01#define I2C_M_NOSTART 0x4000#define I2C_M_REV_DIR_ADDR 0x2000#define I2C_M_IGNORE_NAK 0x1000#define I2C_M_NO_RD_ACK 0x0800/* To determine what functionality is present */#define I2C_FUNC_I2C 0x00000001#define I2C_FUNC_10BIT_ADDR 0x00000002#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */#define I2C_FUNC_SMBUS_QUICK 0x00010000#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */#define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \I2C_FUNC_SMBUS_WRITE_BYTE#define I2C_FUNC_SMBUS_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA | \I2C_FUNC_SMBUS_WRITE_BYTE_DATA#define I2C_FUNC_SMBUS_WORD_DATA I2C_FUNC_SMBUS_READ_WORD_DATA | \I2C_FUNC_SMBUS_WRITE_WORD_DATA#define I2C_FUNC_SMBUS_BLOCK_DATA I2C_FUNC_SMBUS_READ_BLOCK_DATA | \I2C_FUNC_SMBUS_WRITE_BLOCK_DATA#define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \I2C_FUNC_SMBUS_WRITE_I2C_BLOCK#define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \I2C_FUNC_SMBUS_BYTE | \I2C_FUNC_SMBUS_BYTE_DATA | \I2C_FUNC_SMBUS_WORD_DATA | \I2C_FUNC_SMBUS_PROC_CALL | \I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \I2C_FUNC_SMBUS_I2C_BLOCK/* ------------------------------------------------------------------------- */#define DEFAULT_DELAY 10 // default 10us (100khz)static unsigned clock_delay = DEFAULT_DELAY;static unsigned clock_delay2 = DEFAULT_DELAY/2;static unsigned short expected;static unsigned char saved_cmd;unsigned int8 control_data[8];struct i2c_cmd {unsigned char type;unsigned char cmd;unsigned short flags;unsigned short addr;unsigned short len;};#define STATUS_IDLE 0#define STATUS_ADDRESS_ACK 1#define STATUS_ADDRESS_NAK 2unsigned int8 status = STATUS_IDLE;void main(){unsigned int8 data[64];unsigned int8 replyBuf[4];unsigned int8 i=0;setup_adc_ports(NO_ANALOGS|VSS_VDD);setup_adc(ADC_CLOCK_DIV_2);setup_psp(PSP_DISABLED);setup_wdt(WDT_OFF);setup_timer_0(RTCC_INTERNAL);setup_timer_1(T1_DISABLED);setup_timer_2(T2_DISABLED,0,1);setup_timer_3(T3_DISABLED|T3_DIV_BY_1);setup_ccp1(CCP_OFF);setup_comparator(NC_NC_NC_NC);setup_vref(FALSE);printf("MLAB I2C to USB adapter started \n\r ");output_high(PIN_B4);usb_init();usb_wait_for_enumeration();printf("device enumerated \n\r ");if(usb_tbe(0)) printf(" endpoint 0 ready \n\r ");else printf(" endpoint 0 disabled \n\r ");if(usb_tbe(1)) printf(" endpoint 1 ready \n\r ");else printf(" endpoint 1 disabled \n\r ");if(usb_tbe(2)) printf(" endpoint 2 ready \n\r ");else printf(" endpoint 2 disabled \n\r ");if(usb_puts(0,data,64,1000)) printf(" endpoint 0 inicialized \n\r ");else printf("cannot write to endpoint 0 \n\r ");while (TRUE) {if (usb_enumerated()){output_low(PIN_B4);/* if(usb_kbhit(0)){printf("control data received... \n\r");usb_gets(0,control_data,8,100);switch(control_data[1]){case CMD_ECHO: // echo (for transfer reliability testing)replyBuf[0] = control_data[2];replyBuf[1] = control_data[3];usb_puts(0,replyBuf,2,50);break;case CMD_GET_FUNC:usb_puts(0,(I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL),32,50);break;case CMD_SET_DELAY:clock_delay = *(unsigned short*)(control_data+2);if(!clock_delay) clock_delay = 1;clock_delay2 = clock_delay/2;if(!clock_delay2) clock_delay2 = 1;break;case CMD_I2C_IO:case CMD_I2C_IO + CMD_I2C_BEGIN:case CMD_I2C_IO + CMD_I2C_END:case CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END:// these are only allowed as class transfersreturn i2c_do((struct i2c_cmd*)data);break;case CMD_GET_STATUS:replyBuf[0] = status;usb_puts(0,replyBuf,1,50);break;default:// must not happen ...break;}}*/if(usb_kbhit(i)){printf(" data received at endpoint %d \n\r ", i);usb_gets(i,data,64,1000);}delay_ms(10);output_high(PIN_B4);if( i==1 )i=0;else i=1;}}}