#include <fx2macros.h>
#include <serial.h>
#include <stdio.h>
+#include "i2c.h"
/* Also update external declarations in "include/usb.h" if making changes to
* these variables!
.blength = sizeof(struct usb_device_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_DEVICE,
.bcdusb = 0x0200, /* BCD: 02.00 (Version 2.0 USB spec) */
- .bdeviceclass = 0xFF, /* 0xFF = vendor-specific */
- .bdevicesubclass = 0xFF,
- .bdeviceprotocol = 0xFF,
+ .bdeviceclass = 0xEF,
+ .bdevicesubclass = 0x02,
+ .bdeviceprotocol = 0x01,
.bmaxpacketsize0 = 64,
.idvendor = 0x584e,
.idproduct = 0x424e,
.blength = sizeof(struct usb_config_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_CONFIGURATION,
.wtotallength = sizeof(struct usb_config_descriptor) +
- sizeof(struct usb_interface_descriptor) +
- (NUM_ENDPOINTS * sizeof(struct usb_endpoint_descriptor)),
- .bnuminterfaces = 1,
+ 3 * sizeof(struct usb_interface_descriptor) +
+ ((NUM_ENDPOINTS + 2) * sizeof(struct usb_endpoint_descriptor)),
+ .bnuminterfaces = 2,
.bconfigurationvalue = 1,
- .iconfiguration = 4, /* String describing this configuration */
+ .iconfiguration = 1, /* String describing this configuration */
.bmattributes = 0x80, /* Only MSB set according to USB spec */
.maxpower = 50 /* 100 mA */
};
+__code struct usb_interface_association_descriptor interface_association_descriptor = {
+ .blength = sizeof(struct usb_interface_association_descriptor),
+ .bdescriptortype = DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION,
+ .bfirstinterface = 0x01,
+ .binterfacecount = 0x02,
+ .bfunctionclass = 0x02,
+ .bfunctionsubclass = 0x00,
+ .bfunctionprotocol = 0x00,
+ .ifunction = 0x00
+};
+
__code struct usb_interface_descriptor interface_descriptor00 = {
.blength = sizeof(struct usb_interface_descriptor),
.bdescriptortype = DESCRIPTOR_TYPE_INTERFACE,
.binterfacenumber = 0,
.balternatesetting = 0,
.bnumendpoints = NUM_ENDPOINTS,
- .binterfaceclass = 0xFF,
- .binterfacesubclass = 0xFF,
- .binterfaceprotocol = 0xFF,
- .iinterface = 0
+ .binterfaceclass = 0XFF,
+ .binterfacesubclass = 0x00,
+ .binterfaceprotocol = 0x00,
+ .iinterface = 4
};
__code struct usb_endpoint_descriptor bulk_ep1_out_endpoint_descriptor = {
.binterval = 0
};
-__code struct usb_endpoint_descriptor bulk_ep4_endpoint_descriptor = {
- .blength = sizeof(struct usb_endpoint_descriptor),
- .bdescriptortype = 0x05,
- .bendpointaddress = (4 | USB_DIR_IN),
- .bmattributes = 0x02,
- .wmaxpacketsize = 512,
- .binterval = 0
+__code struct usb_interface_descriptor interface_descriptor01 = {
+ .blength = sizeof(struct usb_interface_descriptor),
+ .bdescriptortype = DESCRIPTOR_TYPE_INTERFACE,
+ .binterfacenumber = 1,
+ .balternatesetting = 0,
+ .bnumendpoints = 2,
+ .binterfaceclass = 0x0A,
+ .binterfacesubclass = 0x00,
+ .binterfaceprotocol = 0x00,
+ .iinterface = 0x00
};
-__code struct usb_endpoint_descriptor bulk_ep6_endpoint_descriptor = {
+__code struct usb_endpoint_descriptor bulk_ep6_out_endpoint_descriptor = {
.blength = sizeof(struct usb_endpoint_descriptor),
.bdescriptortype = 0x05,
.bendpointaddress = (6 | USB_DIR_OUT),
.binterval = 0
};
-__code struct usb_endpoint_descriptor bulk_ep8_endpoint_descriptor = {
+__code struct usb_endpoint_descriptor bulk_ep8_in_endpoint_descriptor = {
.blength = sizeof(struct usb_endpoint_descriptor),
.bdescriptortype = 0x05,
- .bendpointaddress = (8 | USB_DIR_OUT),
+ .bendpointaddress = (8 | USB_DIR_IN),
.bmattributes = 0x02,
.wmaxpacketsize = 512,
.binterval = 0
};
-
__code struct usb_language_descriptor language_descriptor = {
.blength = 4,
.bdescriptortype = DESCRIPTOR_TYPE_STRING,
- .wlangid = {0x0409 /* US English */}
+ .wlangid = {0x0409} /* US English */
};
__code struct usb_string_descriptor strmanufacturer =
}
void ep6_isr(void)__interrupt EP6_ISR
{
+ i2c_recieve();
+ EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
+ EPIRQ = 0x40; /* Clear individual EP6OUT IRQ */
+
}
void ep8_isr(void)__interrupt EP8_ISR
{
+ EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
+ EPIRQ = 0x80; /* Clear individual EP8IN IRQ */
}
void ibn_isr(void)__interrupt IBN_ISR
{
switch (setup_data.bmrequesttype) {
case CF_DEVICE:
/* Clear remote wakeup not supported: stall EP0 */
- STALL_EP0();
- break;
+ STALL_EP0();
+ break;
case CF_ENDPOINT:
- if (setup_data.wvalue == 0) {
+ if (setup_data.wvalue == 0) {
/* Unstall the endpoint specified in wIndex */
- ep_cs = usb_get_endpoint_cs_reg(setup_data.windex);
- if (!ep_cs)
- return false;
- *ep_cs &= ~EPSTALL;
+ ep_cs = usb_get_endpoint_cs_reg(setup_data.windex);
+ if (!ep_cs)
+ return false;
+ *ep_cs &= ~EPSTALL;
} else {
/* Unsupported feature, stall EP0 */
- STALL_EP0();
- }
- break;
- default:
+ STALL_EP0();
+ }
+ break;
+ default:
/* Vendor commands... */
break;
}
/* wait until GPIF transaction has been completed */
while ((GPIFTRIG & BMGPIFDONE) == 0) {
if (ix-- == 0) {
- printf("GPIF done time out\n");
break;
}
delay_ms(1);
syncdelay(3);
EP4CFG = 0x00;
syncdelay(3);
- EP6CFG = 0x00;
+ EP6CFG = 0xA2;
syncdelay(3);
- EP8CFG = 0x00;
+ EP8CFG = 0xE2;
syncdelay(3);
/* arm EP1-OUT */
EP1INBC = 0;
syncdelay(3);
+ /* arm EP6-OUT */
+ EP6BCL = 0x80;
+ syncdelay(3);
+ EP6BCL = 0x80;
+ syncdelay(3);
+
/* Standard procedure to reset FIFOs */
FIFORESET = BMNAKALL; /* NAK all transfers during the reset */
syncdelay(3);
syncdelay(3);
}
+void i2c_recieve(void)
+{
+ PIN_SDA_DIR = 0;
+ if (EP6FIFOBUF[0] == 1) {
+ uint8_t rdwr = EP6FIFOBUF[0]; //read
+ uint8_t reg_adr_check = EP6FIFOBUF[1];
+ uint8_t count = EP6FIFOBUF[2]; //request data count
+ uint8_t adr = EP6FIFOBUF[3]; //address
+ uint8_t reg_adr = EP6FIFOBUF[4];
+ uint8_t address = get_address(adr, rdwr); //address byte (read command)
+ uint8_t address_2 = get_address(adr, 0); //address byte 2 (write command)
+
+ printf("%d\n", address);
+
+ /* start: */
+ start_cd();
+ /* address: */
+ send_byte(address_2); //write
+ /* ack: */
+ uint8_t ack = get_ack();
+
+ delay_us(10);
+
+ /* send data */
+ if (reg_adr_check) { //if there is a byte reg
+ send_byte(reg_adr);
+ /* ack(): */
+ ack = get_ack();
+ }
+
+ delay_us(10);
+
+ /* repeated start: */
+ repeated_start();
+ /* address: */
+ send_byte(address);
+ /* get ack: */
+ ack = get_ack();
+
+ delay_us(10);
+
+ /* receive data */
+ for (uint8_t i = 0; i < count; i++) {
+ EP8FIFOBUF[i] = receive_byte();
+
+ /* send ack: */
+ send_ack();
+ }
+
+ delay_ms(1);
+
+ /* stop */
+ stop_cd();
+
+ delay_us(10);
+
+ EP8BCH = 0; //EP8
+ syncdelay(3);
+ EP8BCL = count; //EP8
+
+ EP6BCL = 0x80; //EP6
+ syncdelay(3);
+ EP6BCL = 0x80; //EP6
+ } else {
+ uint8_t rdwr = EP6FIFOBUF[0]; //write
+ uint8_t count = EP6FIFOBUF[1]; //data count
+ uint8_t adr = EP6FIFOBUF[2]; //address
+ uint8_t address = get_address(adr, rdwr); //address byte (read command)
+ uint8_t ack_cnt = 0;
+
+/* start(): */
+ start_cd();
+/* address: */
+ send_byte(address); //write
+/* ack(): */
+ if (!get_ack())
+ ack_cnt++;
+/* send data */
+ for (uint8_t i = 0; i < count; i++) {
+ send_byte(EP6FIFOBUF[i + 3]);
+
+ /* get ack: */
+ if (!get_ack())
+ ack_cnt++;
+ }
+
+/* stop */
+ stop_cd();
+
+ EP8FIFOBUF[0] = ack_cnt;
+
+ EP8BCH = 0; //EP8
+ syncdelay(3);
+ EP8BCL = 1; //EP8
+
+ EP6BCL = 0x80; //EP6
+ syncdelay(3);
+ EP6BCL = 0x80; //EP6
+ }
+}
+
/**
* Interrupt initialization. Configures USB interrupts.
- */
+ **/
void interrupt_init(void)
{
/* Enable Interrupts */
/* Enable INT 2 & 4 Autovectoring */
INTSETUP |= (AV2EN | AV4EN);
- /* Enable individual EP1OUT&IN interrupts */
- EPIE |= 0x0C;
+ /* Enable individual EP1OUT&IN & EP6&8 interrupts */
+ EPIE |= 0xCC;
/* Clear individual USB interrupt IRQ */
- EPIRQ = 0x0C;
+ EPIRQ = 0xCC;
/* Enable SUDAV interrupt */
USBIEN |= SUDAVI;
PIN_TDI = 0;
PIN_SRST = 1;
+
+
/* PORT C */
PORTCCFG = 0x00; /* 0: normal ou 1: alternate function (each bit) */
- OEC = 0xEF;
+ OEC = 0xFF;
IOC = 0xFF;
+
+ /* PORT D */
+ OED = 0xFF;
+ IOD = 0xFF;
+ PIN_SDA_DIR = 0;
}