| 3325 | kaklik | 1 | #include "main.h" | 
      
        |  |  | 2 |  | 
      
        |  |  | 3 | #define USB_CON_SENSE_PIN PIN_D4 | 
      
        |  |  | 4 |  | 
      
        |  |  | 5 | #include <pic18_usb.h> | 
      
        |  |  | 6 | #include "usbconfig.h" | 
      
        |  |  | 7 | #include <usb.h> | 
      
        |  |  | 8 |  | 
      
        |  |  | 9 | #include <usb.c> | 
      
        |  |  | 10 |  | 
      
        |  |  | 11 |  | 
      
        |  |  | 12 | /* commands from USB, must e.g. match command ids in kernel driver */ | 
      
        |  |  | 13 | #define CMD_ECHO       0 | 
      
        |  |  | 14 | #define CMD_GET_FUNC   1 | 
      
        |  |  | 15 | #define CMD_SET_DELAY  2 | 
      
        |  |  | 16 | #define CMD_GET_STATUS 3 | 
      
        |  |  | 17 |  | 
      
        |  |  | 18 | #define CMD_I2C_IO     4 | 
      
        |  |  | 19 | #define CMD_I2C_BEGIN  1  // flag fo I2C_IO | 
      
        |  |  | 20 | #define CMD_I2C_END    2  // flag fo I2C_IO | 
      
        |  |  | 21 |  | 
      
        |  |  | 22 | /* linux kernel flags */ | 
      
        |  |  | 23 | #define I2C_M_TEN      0x10   /* we have a ten bit chip address */ | 
      
        |  |  | 24 | #define I2C_M_RD      0x01 | 
      
        |  |  | 25 | #define I2C_M_NOSTART      0x4000 | 
      
        |  |  | 26 | #define I2C_M_REV_DIR_ADDR   0x2000 | 
      
        |  |  | 27 | #define I2C_M_IGNORE_NAK   0x1000 | 
      
        |  |  | 28 | #define I2C_M_NO_RD_ACK      0x0800 | 
      
        |  |  | 29 |  | 
      
        |  |  | 30 | /* To determine what functionality is present */ | 
      
        |  |  | 31 | #define I2C_FUNC_I2C         0x00000001 | 
      
        |  |  | 32 | #define I2C_FUNC_10BIT_ADDR      0x00000002 | 
      
        |  |  | 33 | #define I2C_FUNC_PROTOCOL_MANGLING   0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ | 
      
        |  |  | 34 | #define I2C_FUNC_SMBUS_HWPEC_CALC   0x00000008 /* SMBus 2.0 */ | 
      
        |  |  | 35 | #define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC  0x00000800 /* SMBus 2.0 */  | 
      
        |  |  | 36 | #define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */  | 
      
        |  |  | 37 | #define I2C_FUNC_SMBUS_PROC_CALL_PEC   0x00002000 /* SMBus 2.0 */ | 
      
        |  |  | 38 | #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */ | 
      
        |  |  | 39 | #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL   0x00008000 /* SMBus 2.0 */ | 
      
        |  |  | 40 | #define I2C_FUNC_SMBUS_QUICK      0x00010000  | 
      
        |  |  | 41 | #define I2C_FUNC_SMBUS_READ_BYTE   0x00020000  | 
      
        |  |  | 42 | #define I2C_FUNC_SMBUS_WRITE_BYTE   0x00040000  | 
      
        |  |  | 43 | #define I2C_FUNC_SMBUS_READ_BYTE_DATA   0x00080000  | 
      
        |  |  | 44 | #define I2C_FUNC_SMBUS_WRITE_BYTE_DATA   0x00100000  | 
      
        |  |  | 45 | #define I2C_FUNC_SMBUS_READ_WORD_DATA   0x00200000  | 
      
        |  |  | 46 | #define I2C_FUNC_SMBUS_WRITE_WORD_DATA   0x00400000  | 
      
        |  |  | 47 | #define I2C_FUNC_SMBUS_PROC_CALL   0x00800000  | 
      
        |  |  | 48 | #define I2C_FUNC_SMBUS_READ_BLOCK_DATA   0x01000000  | 
      
        |  |  | 49 | #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000  | 
      
        |  |  | 50 | #define I2C_FUNC_SMBUS_READ_I2C_BLOCK   0x04000000 /* I2C-like block xfer  */ | 
      
        |  |  | 51 | #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK   0x08000000 /* w/ 1-byte reg. addr. */ | 
      
        |  |  | 52 | #define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2    0x10000000 /* I2C-like block xfer  */ | 
      
        |  |  | 53 | #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */ | 
      
        |  |  | 54 | #define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC  0x40000000 /* SMBus 2.0 */ | 
      
        |  |  | 55 | #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */ | 
      
        |  |  | 56 |  | 
      
        |  |  | 57 | #define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \ | 
      
        |  |  | 58 |                             I2C_FUNC_SMBUS_WRITE_BYTE | 
      
        |  |  | 59 | #define I2C_FUNC_SMBUS_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA | \ | 
      
        |  |  | 60 |                                  I2C_FUNC_SMBUS_WRITE_BYTE_DATA | 
      
        |  |  | 61 | #define I2C_FUNC_SMBUS_WORD_DATA I2C_FUNC_SMBUS_READ_WORD_DATA | \ | 
      
        |  |  | 62 |                                  I2C_FUNC_SMBUS_WRITE_WORD_DATA | 
      
        |  |  | 63 | #define I2C_FUNC_SMBUS_BLOCK_DATA I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ | 
      
        |  |  | 64 |                                   I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | 
      
        |  |  | 65 | #define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ | 
      
        |  |  | 66 |                                   I2C_FUNC_SMBUS_WRITE_I2C_BLOCK | 
      
        |  |  | 67 |  | 
      
        |  |  | 68 | #define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \ | 
      
        |  |  | 69 |                             I2C_FUNC_SMBUS_BYTE | \ | 
      
        |  |  | 70 |                             I2C_FUNC_SMBUS_BYTE_DATA | \ | 
      
        |  |  | 71 |                             I2C_FUNC_SMBUS_WORD_DATA | \ | 
      
        |  |  | 72 |                             I2C_FUNC_SMBUS_PROC_CALL | \ | 
      
        |  |  | 73 |                             I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ | 
      
        |  |  | 74 |                             I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ | 
      
        |  |  | 75 |                             I2C_FUNC_SMBUS_I2C_BLOCK | 
      
        |  |  | 76 |  | 
      
        |  |  | 77 | /* ------------------------------------------------------------------------- */ | 
      
        |  |  | 78 | #define DEFAULT_DELAY 10  // default 10us (100khz) | 
      
        |  |  | 79 | static unsigned clock_delay  = DEFAULT_DELAY; | 
      
        |  |  | 80 | static unsigned clock_delay2 = DEFAULT_DELAY/2; | 
      
        |  |  | 81 |  | 
      
        |  |  | 82 | static unsigned short expected; | 
      
        |  |  | 83 | static unsigned char saved_cmd; | 
      
        |  |  | 84 |  | 
      
        |  |  | 85 | unsigned int8 control_data[8]; | 
      
        |  |  | 86 |  | 
      
        |  |  | 87 | struct i2c_cmd { | 
      
        |  |  | 88 |   unsigned char type; | 
      
        |  |  | 89 |   unsigned char cmd; | 
      
        |  |  | 90 |   unsigned short flags; | 
      
        |  |  | 91 |   unsigned short addr; | 
      
        |  |  | 92 |   unsigned short len;   | 
      
        |  |  | 93 | }; | 
      
        |  |  | 94 |  | 
      
        |  |  | 95 | #define STATUS_IDLE          0 | 
      
        |  |  | 96 | #define STATUS_ADDRESS_ACK   1 | 
      
        |  |  | 97 | #define STATUS_ADDRESS_NAK   2 | 
      
        |  |  | 98 |  | 
      
        |  |  | 99 | unsigned int8 status = STATUS_IDLE; | 
      
        |  |  | 100 |  | 
      
        |  |  | 101 | void main() | 
      
        |  |  | 102 | { | 
      
        |  |  | 103 |  | 
      
        |  |  | 104 | unsigned int8 replyBuf[4]; | 
      
        |  |  | 105 |  | 
      
        |  |  | 106 |    setup_adc_ports(NO_ANALOGS|VSS_VDD); | 
      
        |  |  | 107 |    setup_adc(ADC_CLOCK_DIV_2); | 
      
        |  |  | 108 |    setup_psp(PSP_DISABLED); | 
      
        |  |  | 109 |    setup_wdt(WDT_OFF); | 
      
        |  |  | 110 |    setup_timer_0(RTCC_INTERNAL); | 
      
        |  |  | 111 |    setup_timer_1(T1_DISABLED); | 
      
        |  |  | 112 |    setup_timer_2(T2_DISABLED,0,1); | 
      
        |  |  | 113 |    setup_timer_3(T3_DISABLED|T3_DIV_BY_1); | 
      
        |  |  | 114 |    setup_ccp1(CCP_OFF); | 
      
        |  |  | 115 |    setup_comparator(NC_NC_NC_NC); | 
      
        |  |  | 116 |    setup_vref(FALSE); | 
      
        |  |  | 117 |  | 
      
        |  |  | 118 |    usb_init(); | 
      
        |  |  | 119 |  | 
      
        |  |  | 120 |  | 
      
        |  |  | 121 |  | 
      
        |  |  | 122 |    while (TRUE) { | 
      
        |  |  | 123 |       if (usb_enumerated())  | 
      
        |  |  | 124 |       { | 
      
        |  |  | 125 |          usb_gets(0,control_data,8,100); | 
      
        |  |  | 126 |  | 
      
        |  |  | 127 |          switch(control_data[1]) | 
      
        |  |  | 128 |          { | 
      
        |  |  | 129 |            case CMD_ECHO: // echo (for transfer reliability testing) | 
      
        |  |  | 130 |              replyBuf[0] = control_data[2]; | 
      
        |  |  | 131 |              replyBuf[1] = control_data[3]; | 
      
        |  |  | 132 |              usb_puts(0,replyBuf,2,50); | 
      
        |  |  | 133 |              break; | 
      
        |  |  | 134 |  | 
      
        |  |  | 135 |            case CMD_GET_FUNC: | 
      
        |  |  | 136 |              usb_puts(0,(I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL),32,50); | 
      
        |  |  | 137 |              break; | 
      
        |  |  | 138 |  | 
      
        |  |  | 139 |            case CMD_SET_DELAY: | 
      
        |  |  | 140 |              /* The delay function used delays 4 system ticks per cycle. */ | 
      
        |  |  | 141 |              /* This gives 1/3us at 12Mhz per cycle. The delay function is */ | 
      
        |  |  | 142 |              /* called twice per clock edge and thus four times per full cycle. */  | 
      
        |  |  | 143 |              /* Thus it is called one time per edge with the full delay */  | 
      
        |  |  | 144 |              /* value and one time with the half one. Resulting in */ | 
      
        |  |  | 145 |              /* 2 * n * 1/3 + 2 * 1/2 n * 1/3 = n us. */ | 
      
        |  |  | 146 |              clock_delay = *(unsigned short*)(control_data+2); | 
      
        |  |  | 147 |              if(!clock_delay) clock_delay = 1; | 
      
        |  |  | 148 |              clock_delay2 = clock_delay/2; | 
      
        |  |  | 149 |              if(!clock_delay2) clock_delay2 = 1; | 
      
        |  |  | 150 |              break; | 
      
        |  |  | 151 |  | 
      
        |  |  | 152 |            case CMD_I2C_IO: | 
      
        |  |  | 153 |            case CMD_I2C_IO + CMD_I2C_BEGIN: | 
      
        |  |  | 154 |            case CMD_I2C_IO                 + CMD_I2C_END: | 
      
        |  |  | 155 |            case CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END: | 
      
        |  |  | 156 |              // these are only allowed as class transfers | 
      
        |  |  | 157 |  | 
      
        |  |  | 158 | //             return i2c_do((struct i2c_cmd*)data); | 
      
        |  |  | 159 |              break; | 
      
        |  |  | 160 |  | 
      
        |  |  | 161 |            case CMD_GET_STATUS: | 
      
        |  |  | 162 |              replyBuf[0] = status; | 
      
        |  |  | 163 |              usb_puts(0,replyBuf,1,50); | 
      
        |  |  | 164 |              break; | 
      
        |  |  | 165 |  | 
      
        |  |  | 166 |            default: | 
      
        |  |  | 167 |              // must not happen ... | 
      
        |  |  | 168 |              break;           | 
      
        |  |  | 169 |          } | 
      
        |  |  | 170 |  | 
      
        |  |  | 171 |          delay_ms(10); | 
      
        |  |  | 172 |       } | 
      
        |  |  | 173 |    } | 
      
        |  |  | 174 | } |