| 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 | { | 
      
        | 3331 | kaklik | 103 | unsigned int8 data[64]; | 
      
        | 3325 | kaklik | 104 | unsigned int8 replyBuf[4]; | 
      
        | 3326 | kaklik | 105 | unsigned int8 i=0; | 
      
        | 3325 | kaklik | 106 |  | 
      
        |  |  | 107 |    setup_adc_ports(NO_ANALOGS|VSS_VDD); | 
      
        |  |  | 108 |    setup_adc(ADC_CLOCK_DIV_2); | 
      
        |  |  | 109 |    setup_psp(PSP_DISABLED); | 
      
        |  |  | 110 |    setup_wdt(WDT_OFF); | 
      
        |  |  | 111 |    setup_timer_0(RTCC_INTERNAL); | 
      
        |  |  | 112 |    setup_timer_1(T1_DISABLED); | 
      
        |  |  | 113 |    setup_timer_2(T2_DISABLED,0,1); | 
      
        |  |  | 114 |    setup_timer_3(T3_DISABLED|T3_DIV_BY_1); | 
      
        |  |  | 115 |    setup_ccp1(CCP_OFF); | 
      
        |  |  | 116 |    setup_comparator(NC_NC_NC_NC); | 
      
        |  |  | 117 |    setup_vref(FALSE); | 
      
        |  |  | 118 |  | 
      
        | 3326 | kaklik | 119 |    printf("MLAB I2C to USB adapter started \n\r "); | 
      
        | 3325 | kaklik | 120 |  | 
      
        | 3326 | kaklik | 121 |          output_high(PIN_B4); | 
      
        | 3325 | kaklik | 122 |  | 
      
        | 3326 | kaklik | 123 |    usb_init(); | 
      
        | 3331 | kaklik | 124 |    usb_wait_for_enumeration();    | 
      
        | 3325 | kaklik | 125 |  | 
      
        | 3331 | kaklik | 126 |  | 
      
        |  |  | 127 |    printf("device enumerated \n\r "); | 
      
        |  |  | 128 |  | 
      
        |  |  | 129 | if(usb_tbe(0)) printf(" endpoint 0 ready \n\r "); | 
      
        |  |  | 130 | else printf(" endpoint 0 disabled \n\r "); | 
      
        |  |  | 131 | if(usb_tbe(1)) printf(" endpoint 1 ready \n\r "); | 
      
        |  |  | 132 | else printf(" endpoint 1 disabled \n\r "); | 
      
        |  |  | 133 | if(usb_tbe(2)) printf(" endpoint 2 ready \n\r "); | 
      
        |  |  | 134 | else printf(" endpoint 2 disabled \n\r "); | 
      
        |  |  | 135 |  | 
      
        |  |  | 136 | if(usb_puts(0,data,64,1000)) printf(" endpoint 0 inicialized \n\r "); | 
      
        |  |  | 137 | else printf("cannot write to endpoint 0 \n\r "); | 
      
        |  |  | 138 |  | 
      
        | 3325 | kaklik | 139 |    while (TRUE) { | 
      
        |  |  | 140 |       if (usb_enumerated())  | 
      
        |  |  | 141 |       { | 
      
        |  |  | 142 |  | 
      
        | 3326 | kaklik | 143 |       output_low(PIN_B4); | 
      
        |  |  | 144 |  | 
      
        |  |  | 145 | /*         if(usb_kbhit(0)) | 
      
        | 3325 | kaklik | 146 |          { | 
      
        | 3326 | kaklik | 147 |             printf("control data received...  \n\r"); | 
      
        |  |  | 148 |  | 
      
        |  |  | 149 |             usb_gets(0,control_data,8,100); | 
      
        |  |  | 150 |  | 
      
        |  |  | 151 |             switch(control_data[1]) | 
      
        |  |  | 152 |             { | 
      
        |  |  | 153 |               case CMD_ECHO: // echo (for transfer reliability testing) | 
      
        |  |  | 154 |                 replyBuf[0] = control_data[2]; | 
      
        |  |  | 155 |                 replyBuf[1] = control_data[3]; | 
      
        |  |  | 156 |                 usb_puts(0,replyBuf,2,50); | 
      
        |  |  | 157 |                 break; | 
      
        |  |  | 158 |  | 
      
        |  |  | 159 |               case CMD_GET_FUNC: | 
      
        |  |  | 160 |                 usb_puts(0,(I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL),32,50); | 
      
        |  |  | 161 |                 break; | 
      
        |  |  | 162 |  | 
      
        |  |  | 163 |               case CMD_SET_DELAY: | 
      
        |  |  | 164 |                 clock_delay = *(unsigned short*)(control_data+2); | 
      
        |  |  | 165 |                 if(!clock_delay) clock_delay = 1; | 
      
        |  |  | 166 |                 clock_delay2 = clock_delay/2; | 
      
        |  |  | 167 |                 if(!clock_delay2) clock_delay2 = 1; | 
      
        |  |  | 168 |                 break; | 
      
        |  |  | 169 |  | 
      
        |  |  | 170 |               case CMD_I2C_IO: | 
      
        |  |  | 171 |               case CMD_I2C_IO + CMD_I2C_BEGIN: | 
      
        |  |  | 172 |               case CMD_I2C_IO                 + CMD_I2C_END: | 
      
        |  |  | 173 |               case CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END: | 
      
        |  |  | 174 |                 // these are only allowed as class transfers | 
      
        |  |  | 175 |  | 
      
        |  |  | 176 |                 return i2c_do((struct i2c_cmd*)data); | 
      
        |  |  | 177 |                 break; | 
      
        |  |  | 178 |  | 
      
        |  |  | 179 |               case CMD_GET_STATUS: | 
      
        |  |  | 180 |                 replyBuf[0] = status; | 
      
        |  |  | 181 |                 usb_puts(0,replyBuf,1,50); | 
      
        |  |  | 182 |                 break; | 
      
        |  |  | 183 |  | 
      
        |  |  | 184 |               default: | 
      
        |  |  | 185 |                 // must not happen ... | 
      
        |  |  | 186 |                 break;           | 
      
        |  |  | 187 |             } | 
      
        |  |  | 188 |          }*/ | 
      
        |  |  | 189 |  | 
      
        |  |  | 190 |          if(usb_kbhit(i)) | 
      
        |  |  | 191 |          { | 
      
        |  |  | 192 |            printf(" data received at endpoint %d \n\r ", i); | 
      
        | 3331 | kaklik | 193 |            usb_gets(i,data,64,1000); | 
      
        | 3325 | kaklik | 194 |          } | 
      
        |  |  | 195 |  | 
      
        |  |  | 196 |          delay_ms(10); | 
      
        | 3326 | kaklik | 197 |  | 
      
        |  |  | 198 |          output_high(PIN_B4); | 
      
        | 3331 | kaklik | 199 |          if( i==1 )i=0; | 
      
        |  |  | 200 |          else i=1; | 
      
        | 3325 | kaklik | 201 |       } | 
      
        |  |  | 202 |    } | 
      
        |  |  | 203 | } |