Beispiel #1
0
/* Send the next transaction containing data from the medium to the host. */
static int8_t send_next_data_transaction(struct msc_application_data *msc)
{
	const uint8_t *cur = msc->tx_buf;
	const uint16_t len = msc->tx_len_remaining;

	if (!usb_is_configured() || usb_in_endpoint_busy(msc->in_endpoint))
		return -1;

	if (len > 0) {
		/* There is data to send; send one packet worth. */
		uint8_t *buf;
		uint16_t to_copy;

		buf = usb_get_in_buffer(msc->in_endpoint);
		to_copy = MIN(len, msc->in_endpoint_size);
		memcpy(buf, cur, to_copy);

		usb_send_in_buffer(msc->in_endpoint, to_copy);

		msc->transferred_bytes += to_copy;
		msc->tx_buf += to_copy;
		msc->tx_len_remaining -= to_copy;
	}
	else {
		/* Transfer of block has completed */
		msc->operation_complete_callback(msc, true);
		msc->operation_complete_callback = NULL;
		msc->tx_buf = NULL;
	}

	return 0;
}
Beispiel #2
0
int main(void)
{
    OSCCONbits.IRCF = 0b1111; // 0b1111 = 16MHz HFINTOSC postscaler
    ANSELA = 0x00; // digital I/O on PORTA
    ANSELB = 0x00; // digital I/O on PORTB
    ANSELC = 0x00; // digital I/O on PORTC
    APFCON = 0x00; // a little bit of voodoo
    MODE_SW_TRIS = PIN_OUTPUT;
    MODE_SW = POTENTIOSTATIC; // initialize mode to potentiostatic
    CELL_ON_TRIS = PIN_OUTPUT;
    CELL_ON_PIN = CELL_OFF; // initialize cell to off position
    TRISC = 0x00; // all outputs on PORTC
    LATC = RANGE1; // initialize range to range 1

    // Enable Active clock-tuning from the USB
    ACTCONbits.ACTSRC = 1; // 1=USB
    ACTCONbits.ACTEN = 1;

    // Configure interrupts
    INTCONbits.PEIE = 1;
    INTCONbits.GIE = 1;

    // Initialize USB
    usb_init();

    while (1)
    {
        if (usb_is_configured() && usb_out_endpoint_has_data(1)) // wait for data received from host
        {
            if (!usb_in_endpoint_halted(1))
            {
                while (usb_in_endpoint_busy(1)) // wait for EP1 IN to become free
                    ;
                received_data_length = usb_get_out_buffer(1, &received_data);
                transmit_data = usb_get_in_buffer(1);
                interpret_command(); // this reads received_data and sets transmit_data and transmit_data_length
                usb_send_in_buffer(1, transmit_data_length); // send the data back
            }
            usb_arm_out_endpoint(1);
        }
    }

    return 0;
}
Beispiel #3
0
USBSerial::operator bool() {
    return usb_is_connected(USBLIB) && usb_is_configured(USBLIB) && usb_cdcacm_get_dtr();
}
Beispiel #4
0
int main(void) {
    hardware_init();

    luke_init();
    
#ifdef MULTI_CLASS_DEVICE
    hid_set_interface_list(hid_interfaces, sizeof (hid_interfaces));
#endif
    usb_init();

    uint8_t  regAddr = 0;
    
    while (1) {
        if (usb_is_configured() && usb_out_endpoint_has_data(1)) {
            //                uint8_t len;
            const unsigned char *RxDataBuffer;
            unsigned char *TxDataBuffer = usb_get_in_buffer(1);
            /* Data received from host */

            if (!usb_in_endpoint_halted(1)) {
                /* Wait for EP 1 IN to become free then send. This of
                 * course only works using interrupts. */
                while (usb_in_endpoint_busy(1))
                    ;

                usb_get_out_buffer(1, &RxDataBuffer);

                uint8_t pcktVer = RxDataBuffer[0] & 0xC0;
                uint8_t pcktLen = RxDataBuffer[0] & 0x2F;

                if (pcktVer == PROTOCOL_VERSION && pcktLen > 1) {

                    uint8_t opcode = RxDataBuffer[1];
                    TxDataBuffer[1] = opcode; // echo back operation code
                    ATTID id = (RxDataBuffer[2] << 8) + RxDataBuffer[3];                        
                    uint8_t len;
                    
                    switch (opcode) {
                        case OP_ATT_VALUE_GET:
                            TxDataBuffer[2] = RC_OK; // Return OK code
                            TxDataBuffer[0] = PROTOCOL_VERSION;

                            switch (id) {
                                case ATT_PRODUCT_NAME:
                                    len = strlen(PRODUCT_NAME) + 1; // +1 for NULL
                                    TxDataBuffer[0] |= len + 3; // packet length
                                    memcpy(&TxDataBuffer[3], PRODUCT_NAME, len);
                                    break;
                                    
                                case ATT_PRODUCT_REVISION:
                                    TxDataBuffer[0] |= 2 + 3; // packet length
                                    TxDataBuffer[3] = '0' + PORTCbits.RC2;
                                    TxDataBuffer[4] = NULL;
                                    break;
                            
                                case ATT_PRODUCT_SERIAL:
                                /*  TxDataBuffer[0]  |= NVM_PRODUCT_SERIAL_SIZE + 3; // packet length
                                    for (uint8_t i=0; i<NVM_PRODUCT_SERIAL_SIZE; i++) {
                                    // Please note that 1 word of HEF is 14bits but lower 8bits is high-endurance
                                    TxDataBuffer[i+3] = (uint8_t) FLASH_ReadWord(NVM_PRODUCT_SERIAL_ADDR + i);
                                } */
                                    TxDataBuffer[0]  |= NVM_PRODUCT_SERIAL_SIZE + 3; // packet length
                                    memcpy(&TxDataBuffer[3], NVM_PRODUCT_SERIAL_ADDR, NVM_PRODUCT_SERIAL_SIZE);
                                    break;
                                
                                case ATT_FIRM_VERSION:
                                    len = strlen(FIRM_VERSION) + 1; // +1 for NULL
                                    TxDataBuffer[0] |= len + 3; // packet length
                                    memcpy(&TxDataBuffer[3], FIRM_VERSION, len);
                                    break;
                                    
                                case ATT_I2C0_RW_2BYTE:
                                    TxDataBuffer[0]  |= 2 + 3; // packet length
                                    uint16_t dat = i2c_reg_read(regAddr);
                                    TxDataBuffer[4] = dat >> 8; 
                                    TxDataBuffer[3] = dat;
                                    break;
                                    
                                case ATT_VOLTAGE:
                                    TxDataBuffer[0] |= 4 + 3; // packet length
                                    float volt = get_voltage();
                                    TxDataBuffer[3] = 0x00;
                                    memcpy(&TxDataBuffer[4], &volt, 3);
                                    break;
                                
                                case ATT_CURRENT:
                                    TxDataBuffer[0] |= 4 + 3; // packet length
                                    float curr = get_current();
                                    TxDataBuffer[3] = 0x00;
                                    memcpy(&TxDataBuffer[4], &curr, 3);
                                    break;

                                default:
                                    TxDataBuffer[0] |= 3; // packet length
                                    TxDataBuffer[2] = RC_FAIL; // Return error code
                                    break;
                                    
                            } // end of switch (id)
                            break;
                            
                        case  OP_ATT_VALUE_SET:
                            TxDataBuffer[0] = PROTOCOL_VERSION | 3; // packet length
                            TxDataBuffer[2] = RC_OK; // Return OK code
                            
                            switch (id) {
                                case ATT_I2C0_REG_ADDR:
                                    regAddr = RxDataBuffer[4];
                                    break;
                                    
                                case ATT_I2C0_RW_2BYTE:
                                    i2c_reg_write(regAddr, RxDataBuffer[5], RxDataBuffer[4]);
                                    break;
                                
                                default:
                                    TxDataBuffer[2] = RC_FAIL; // Return error code
                                    break;
                                    
                            } // end of switch (id)
                            break;
                            
                        default:
                            TxDataBuffer[0] = PROTOCOL_VERSION | 3; // packet length
                            TxDataBuffer[2] = RC_FAIL; // Return error code
                            break;
                                                        
                    } // switch (opcode)
                          
                    // Send response
                    memcpy(usb_get_in_buffer(1), TxDataBuffer, EP_1_IN_LEN);
                    usb_send_in_buffer(1, EP_1_IN_LEN);

                } // end of if (pcktVer == PROTOCOL_VERSION && pcktLen > 1)
            }
            usb_arm_out_endpoint(1);
        }

#ifndef USB_USE_INTERRUPTS
        usb_service();
#endif
    }
Beispiel #5
0
int main(void)
{
#if defined(__PIC24FJ64GB002__) || defined(__PIC24FJ256DA206__)
	unsigned int pll_startup_counter = 600;
	CLKDIVbits.PLLEN = 1;
	while(pll_startup_counter--);
#elif _18F46J50
	unsigned int pll_startup = 600;
	OSCTUNEbits.PLLEN = 1;
	while (pll_startup--)
		;
#elif _16F1459 || _16F1454
	OSCCONbits.IRCF = 0b1111; /* 0b1111 = 16MHz HFINTOSC postscalar */

	/* Enable Active clock-tuning from the USB */
	ACTCONbits.ACTSRC = 1; /* 1=USB */
	ACTCONbits.ACTEN = 1;
#elif __32MX460F512L__
	SYSTEMConfigPerformance(80000000);
#endif


/* Configure interrupts, per architecture */
#ifdef USB_USE_INTERRUPTS
	#if defined (_PIC18) || defined(_PIC14E)
		INTCONbits.PEIE = 1;
		INTCONbits.GIE = 1;
	#elif __PIC32MX__
		INTCONbits.MVEC = 1; /* Multi-vector interrupts */
		IPC11bits.USBIP = 4; /* Interrupt priority, must set to != 0. */
		__asm volatile("ei");
	#endif
#endif

#ifdef MULTI_CLASS_DEVICE
	hid_set_interface_list(hid_interfaces, sizeof(hid_interfaces));
#endif
	usb_init();

	/* Setup mouse movement. This implementation sends back data for every
	 * IN packet, but sends no movement for all but every delay-th frame.
	 * Adjusting delay will slow down or speed up the movement, which is
	 * also dependent upon the rate at which the host sends IN packets,
	 * which varies between implementations.
	 *
	 * In real life, you wouldn't want to send back data that hadn't
	 * changed, but since there's no real hardware to poll, and since this
	 * example is about showing the HID class, and not about creative ways
	 * to do timing, we send back data every frame. The interested reader
	 * may want to modify it to use the start-of-frame callback for
	 * timing.
	 */
	uint8_t x_delay = 14;
	uint8_t x_count = 100;
	int8_t x_direc = 1;
	uint8_t y_delay = 14;
	uint8_t y_count = 25;
	int8_t y_direc = 1;

	while (1) {
		if (usb_is_configured() &&
		    !usb_in_endpoint_halted(1) &&
		    !usb_in_endpoint_busy(1)) {

			/* Interface 1: Move mouse Left and Right. This
			 * interface only has an X axis. */
			unsigned char *buf = usb_get_in_buffer(1);
			buf[0] = 0x0;
			buf[1] = (--x_delay)? 0: x_direc;
			buf[2] = 0; /* Don't move Y */
			usb_send_in_buffer(1, 3);

			if (x_delay == 0) {
				if (--x_count == 0) {
					x_count = 100;
					x_direc *= -1;
				}
				x_delay = 14;
			}
		}

		if (usb_is_configured() &&
		    !usb_in_endpoint_halted(2) &&
		    !usb_in_endpoint_busy(2)) {

			/* Interface 2: Move mouse up and Down. This
			 * interface only has a Y axis. */
			unsigned char *buf = usb_get_in_buffer(2);
			buf[0] = 0x0;
			buf[1] = 0; /* Don't move X */
			buf[2] = (--y_delay)? 0: y_direc;
			buf[3] = 0; /* Don't move Z */
			usb_send_in_buffer(2, 4);

			if (y_delay == 0) {
				if (--y_count == 0) {
					y_count = 25;
					y_direc *= -1;
				}
				y_delay = 14;
			}
		}

		#ifndef USB_USE_INTERRUPTS
		usb_service();
		#endif
	}

	return 0;
}
Beispiel #6
0
int main(void)
{
	hardware_init();

#ifdef MULTI_CLASS_DEVICE
	hid_set_interface_list(hid_interfaces, sizeof(hid_interfaces));
#endif
	usb_init();

	/* Setup mouse movement. This implementation sends back data for every
	 * IN packet, but sends no movement for all but every delay-th frame.
	 * Adjusting delay will slow down or speed up the movement, which is
	 * also dependent upon the rate at which the host sends IN packets,
	 * which varies between implementations.
	 *
	 * In real life, you wouldn't want to send back data that hadn't
	 * changed, but since there's no real hardware to poll, and since this
	 * example is about showing the HID class, and not about creative ways
	 * to do timing, we send back data every frame. The interested reader
	 * may want to modify it to use the start-of-frame callback for
	 * timing.
	 */
	uint8_t x_delay = 14;
	uint8_t x_count = 100;
	int8_t x_direc = 1;
	uint8_t y_delay = 14;
	uint8_t y_count = 25;
	int8_t y_direc = 1;

	while (1) {
		if (usb_is_configured() &&
		    !usb_in_endpoint_halted(1) &&
		    !usb_in_endpoint_busy(1)) {

			/* Interface 1: Move mouse Left and Right. This
			 * interface only has an X axis. */
			unsigned char *buf = usb_get_in_buffer(1);
			buf[0] = 0x0;
			buf[1] = (--x_delay)? 0: x_direc;
			buf[2] = 0; /* Don't move Y */
			usb_send_in_buffer(1, 3);

			if (x_delay == 0) {
				if (--x_count == 0) {
					x_count = 100;
					x_direc *= -1;
				}
				x_delay = 14;
			}
		}

		if (usb_is_configured() &&
		    !usb_in_endpoint_halted(2) &&
		    !usb_in_endpoint_busy(2)) {

			/* Interface 2: Move mouse up and Down. This
			 * interface only has a Y axis. */
			unsigned char *buf = usb_get_in_buffer(2);
			buf[0] = 0x0;
			buf[1] = 0; /* Don't move X */
			buf[2] = (--y_delay)? 0: y_direc;
			buf[3] = 0; /* Don't move Z */
			usb_send_in_buffer(2, 4);

			if (y_delay == 0) {
				if (--y_count == 0) {
					y_count = 25;
					y_direc *= -1;
				}
				y_delay = 14;
			}
		}

		#ifndef USB_USE_INTERRUPTS
		usb_service();
		#endif
	}

	return 0;
}
Beispiel #7
0
int main(void)
{

    hardware_init();

#ifdef MULTI_CLASS_DEVICE
	cdc_set_interface_list(cdc_interfaces, sizeof(cdc_interfaces));
#endif
	usb_init();

	uint8_t char_to_send = 'A';
	bool send = true;
	bool loopback = false;

	while (1) {

		/* Send data to the PC */
		if (usb_is_configured() &&
		    !usb_in_endpoint_halted(2) &&
		    !usb_in_endpoint_busy(2) && send) {

			int i;
			unsigned char *buf = usb_get_in_buffer(2);

			for (i = 0; i < 16; i++) {
				buf[i] = char_to_send++;
				if (char_to_send > 'Z')
					char_to_send = 'A';
			}
			buf[i++] = '\r';
			buf[i++] = '\n';
			usb_send_in_buffer(2, i);
		}

		/* Handle data received from the host */
		if (usb_is_configured() &&
		    !usb_out_endpoint_halted(2) &&
		    usb_out_endpoint_has_data(2)) {
			const unsigned char *out_buf;
			size_t out_buf_len;
			int i;

			/* Check for an empty transaction. */
			out_buf_len = usb_get_out_buffer(2, &out_buf);
			if (out_buf_len <= 0)
				goto empty;

			if (send) {
				/* Stop sendng if a key was hit. */
				send = false;
				send_string_sync(2, "Data send off ('h' for help)\r\n");
			}
			else if (loopback) {
				/* Loop data back to the PC */

				/* Wait until the IN endpoint can accept it */
				while (usb_in_endpoint_busy(2))
					;

				/* Copy contents of OUT buffer to IN buffer
				 * and send back to host. */
				memcpy(usb_get_in_buffer(2), out_buf, out_buf_len);
				usb_send_in_buffer(2, out_buf_len);

				/* Send a zero-length packet if the transaction
				 * length was the same as the endpoint
				 * length. This is for demo purposes. In real
				 * life, you only need to do this if the data
				 * you're transferring ends on a multiple of
				 * the endpoint length. */
				if (out_buf_len == EP_2_LEN) {
					/* Wait until the IN endpoint can accept it */
					while (usb_in_endpoint_busy(2))
						;
					usb_send_in_buffer(2, 0);
				}

				/* Scan for ~ character to end loopback mode */
				for (i = 0; i < out_buf_len; i++) {
					if (out_buf[i] == '~') {
						loopback = false;
						send_string_sync(2, "\r\nLoopback off ('h' for help)\r\n");
						break;
					}
				}
			}
			else {
				/* Scan for commands if not in loopback or
				 * send mode.
				 *
				 * This is a hack. One should really scan the
				 * entire string. In this case, since this
				 * is a demo, assume that the user is using
				 * a terminal program and typing the input,
				 * all but ensuring the data will come in
				 * single-character transactions. */
				if (out_buf[0] == 'h' || out_buf[0] == '?') {
					/* Show help.
					 * Make sure to not try to send more
					 * than 63 bytes of data in one
					 * transaction */
					send_string_sync(2,
						"\r\nHelp:\r\n"
						"\ts: send data\r\n"
						"\tl: loopback\r\n");
					send_string_sync(2,
						"\tn: send notification\r\n"
						"\th: help\r\n");
				}
				else if (out_buf[0] == 's')
					send = true;
				else if (out_buf[0] == 'l') {
					loopback = true;
					send_string_sync(2, "loopback enabled; press ~ to disable\r\n");
				}
				else if (out_buf[0] == 'n') {
					/* Send a Notification on Endpoint 1 */
					struct cdc_serial_state_notification *n =
						(struct cdc_serial_state_notification *)
							usb_get_in_buffer(1);

					n->header.REQUEST.bmRequestType = 0xa1;
					n->header.bNotification = CDC_SERIAL_STATE;
					n->header.wValue = 0;
					n->header.wIndex = 1; /* Interface */
					n->header.wLength = 2;
					n->data.serial_state = 0; /* Zero the whole bit mask */
					n->data.bits.bRxCarrier = 1;
					n->data.bits.bTxCarrier = 1;
					n->data.bits.bBreak = 0;
					n->data.bits.bRingSignal = 0;
					n->data.bits.bFraming = 0;
					n->data.bits.bParity = 0;
					n->data.bits.bOverrun = 0;

					/* Wait for the endpoint to be free */
					while (usb_in_endpoint_busy(1))
						;

					/* Send to to host */
					usb_send_in_buffer(1, sizeof(*n));

					send_string_sync(2, "Notification Sent\r\n");
				}
			}
empty:
			usb_arm_out_endpoint(2);
		}

		#ifndef USB_USE_INTERRUPTS
		usb_service();
		#endif
	}

	return 0;
}
Beispiel #8
0
int main(void)
{
#if defined(__PIC24FJ64GB002__) || defined(__PIC24FJ256DA206__)
	unsigned int pll_startup_counter = 600;
	CLKDIVbits.PLLEN = 1;
	while(pll_startup_counter--);
#elif _18F46J50
	unsigned int pll_startup = 600;
	OSCTUNEbits.PLLEN = 1;
	while (pll_startup--)
		;
#elif _16F1459
	OSCCONbits.IRCF = 0b1111; /* 0b1111 = 16MHz HFINTOSC postscalar */

	/* Enable Active clock-tuning from the USB */
	ACTCONbits.ACTSRC = 1; /* 1=USB */
	ACTCONbits.ACTEN = 1;
#elif __32MX460F512L__
	SYSTEMConfigPerformance(80000000);
#endif


/* Configure interrupts, per architecture */
#ifdef USB_USE_INTERRUPTS
	#if defined (_PIC18) || defined(_PIC14E)
		INTCONbits.PEIE = 1;
		INTCONbits.GIE = 1;
	#elif __PIC32MX__
		INTCONbits.MVEC = 1; /* Multi-vector interrupts */
		IPC11bits.USBIP = 4; /* Interrupt priority, must set to != 0. */
		__asm volatile("ei");
	#endif
#endif
	usb_init();
	
	unsigned char *buf = usb_get_in_buffer(1);
	memset(buf, 0xa0, EP_1_IN_LEN);

	while (1) {
		if (usb_is_configured() && usb_out_endpoint_has_data(1)) {
			uint8_t len;
			const unsigned char *data;
			/* Data received from host */

			if (!usb_in_endpoint_halted(1)) {
				/* Wait for EP 1 IN to become free then send. This of
				 * course only works using interrupts. */
				while (usb_in_endpoint_busy(1))
					;

				len = usb_get_out_buffer(1, &data);
				memcpy(usb_get_in_buffer(1), data, EP_1_IN_LEN);
				usb_send_in_buffer(1, len);
			}
			usb_arm_out_endpoint(1);
		}

		#ifndef USB_USE_INTERRUPTS
		usb_service();
		#endif
	}

	return 0;
}
Beispiel #9
0
uint8 USBMidi::isConnected(void) {
    return usb_is_connected(USBLIB) && usb_is_configured(USBLIB);
}