avr-fw-modules/usb/src/usb_endpoint.c

85 lines
2.0 KiB
C

#include <usb/usb.h>
#include <io/pipe.h>
#include <avr/io.h>
#include <stdlib.h>
#include <sys/errno.h>
int usb_endpoint_set_buffer (int endpoint,void *buffer,int size){
ATOMIC
uint8_t cfg0x;
usb_device.endpoints[ endpoint ].buffer = buffer;
usb_device.endpoints[ endpoint ].blen = size;
usb_device.endpoints[ endpoint ].bpos = 0;
usb_ll_endpoint_select( endpoint );
cfg0x = UECFG0X;
if ((cfg0x & 0xC0) == 0){ // CONTROL-EP
if ((usb_device.endpoints[ endpoint ].request->bmRequestType & 0x80 )) {
usb_ll_enable_irq( USB_IRQ_TXIN );
usb_ll_enable_irq( USB_IRQ_RXOUT );
} else {
if (usb_device._addr_setup){
usb_ll_enable_irq( USB_IRQ_TXIN );
} else {
usb_ll_enable_irq( USB_IRQ_RXOUT );
usb_ll_clear_irq( USB_IRQ_NAKIN );
usb_ll_enable_irq( USB_IRQ_NAKIN );
};
};
} else if (cfg0x & _BV(0)){
usb_ll_enable_irq( USB_IRQ_TXIN );
} else {
usb_ll_enable_irq( USB_IRQ_RXOUT );
};
return ESUCCESS;
};
int usb_endpoint_unset_buffer (int endpoint){
ATOMIC
int l = usb_device.endpoints[ endpoint ].bpos;
usb_device.endpoints[ endpoint ].buffer = NULL;
usb_device.endpoints[ endpoint ].blen = 0;
usb_device.endpoints[ endpoint ].bpos = 0;
usb_ll_endpoint_select( endpoint );
usb_ll_disable_irq( USB_IRQ_RXOUT );
usb_ll_disable_irq( USB_IRQ_TXIN );
return l;
};
int usb_endpoint_check_buffer (int endpoint){
ATOMIC
if (!usb_device.endpoints[ endpoint ].buffer){
return -ENULLPTR;
};
return usb_device.endpoints[ endpoint ].blen - usb_device.endpoints[ endpoint ].bpos;
};
int usb_endpoint_write(int endpoint,void *buffer,int len){
usb_endpoint_set_buffer( endpoint, buffer, len );
while (usb_endpoint_check_buffer( endpoint ) > 0){
wait_ms(1);
};
return usb_endpoint_unset_buffer( endpoint );
};
int usb_endpoint_read(int endpoint,void *buffer,int len){
usb_endpoint_set_buffer( endpoint, buffer, len );
while (usb_endpoint_check_buffer( endpoint ) > 0){
wait_ms(1);
};
return usb_endpoint_unset_buffer( endpoint );
};