Estoy trabajando con la transferencia de datos UART de un ATmega8 a otro mientras el receptor ejecuta VUSB actuando como un Ratón HID a la PC.
UART aunque init con 9600, más tarde se establece en velocidad máxima - > UBRR = 0;
Problemas:
- VUSB no es estable en ambas comunicaciones basadas en interrupciones. o comunicación no basada en interrupciones.
- Tuve éxito en tenerlo estable solo una vez ... pero los datos recibidos fueron basura.
¿Cómo puedo superar estos problemas?
hizo un pequeño protocolo para datos ..
SYNC_START X Y END_SYNC
el código del transmisor:
//////////////////////////////////////////////////////////////////////////
//Defines
//////////////////////////////////////////////////////////////////////////
#define F_CPU 16000000UL
#define true 0x01
#define false 0x00
#define uchar unsigned char
#define uint unsigned int
#define START_SYNC_BYTE 0b10101010
#define END_SYNC_BYTE 0b01010101
//////////////////////////////////////////////////////////////////////////
#include <avr/io.h>
#include <util/delay.h>
#include "uart/UART.h"
#include "IMU.h"
//////////////////////////////////////////////////////////////////////////
//GLOBAL VARIABLES
//////////////////////////////////////////////////////////////////////////
uint X=0,Y=0;
//////////////////////////////////////////////////////////////////////////
int main(void)
{
i2c_init();
WakeUpIMU();
UART_Init(9600,true,false,false);
UBRRH = 0;
UBRRL = 0;
while(1)
{
X = Get16Bits(MPU6050_RA_ACCEL_XOUT_H);
Y = Get16Bits(MPU6050_RA_ACCEL_YOUT_H);
BlockingTransmitt(START_SYNC_BYTE);
BlockingTransmitt(START_SYNC_BYTE);
BlockingTransmitt(X);
BlockingTransmitt(Y);
BlockingTransmitt(END_SYNC_BYTE);
_delay_ms(5);
}
}
El código del receptor:
//////////////////////////////////////////////////////////////////////////
//Defines
//////////////////////////////////////////////////////////////////////////
#define F_CPU 16000000UL
#define true 0x01
#define false 0x00
#define uchar unsigned char
#define uint unsigned int
#define START_SYNC_BYTE 0b10101010
#define END_SYNC_BYTE 0b01010101
//////////////////////////////////////////////////////////////////////////
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <util/delay.h>
#include "uart/UART.h"
#include "usbdrv/usbdrv.h"
//////////////////////////////////////////////////////////////////////////
//GLOBAL VARIABLES
//////////////////////////////////////////////////////////////////////////
uint X,Y;
bool WaitingForX=false,WaitingForY=false;
bool TransmissionComplete = false;
//////////////////////////////////////////////////////////////////////////
PROGMEM const char usbHidReportDescriptor[52] =
{ /* USB report descriptor, size must match usbconfig.h */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xA1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM
0x29, 0x03, // USAGE_MAXIMUM
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Const,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7F, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xC0, // END_COLLECTION
0xC0, // END COLLECTION
};
typedef struct{
uchar buttonMask;
char dx;
char dy;
char dWheel;
}report_t;
static report_t reportBuffer;
static uchar idleRate;
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
/* The following requests are never used. But since they are required by
* the specification, we implement them in this example.
*/
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
/* we only have one report type, so don't look at wValue */
usbMsgPtr = (void *)&reportBuffer;
return sizeof(reportBuffer);
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
usbMsgPtr = &idleRate;
return 1;
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){
idleRate = rq->wValue.bytes[1];
}
}
else{
/* no vendor specific requests implemented */
}
return 0; /* default for not implemented requests: return no data back to host */
}
int main(void)
{
uchar i;
wdt_enable(WDTO_1S);
usbInit();
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
i = 0;
while(--i){ /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
UART_Init(9600 , false , true , false);
UBRRH = 0;
UBRRL = 0;
sei();
while(1)
{
wdt_reset();
usbPoll();
RecieveUARTdata();
if(TransmissionComplete && usbInterruptIsReady()){
/* called after every poll of the interrupt endpoint */
usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
}
}
return 0;
}
void ResetValues(){
X=0;Y=0;
WaitingForX=false;
WaitingForY=false;
}
void RecieveUARTdata(){
//Get the data is available by checking the RXC in UCSRA
if ( UCSRA & (1<<RXC) )
{
uint data = UDR;
//if the data received is START SYNC DATA
if(data==START_SYNC_BYTE){
WaitingForX = true;return;
}
else {
if(WaitingForX){
X=data; WaitingForX=false;
WaitingForY=true;return;
}
else if(WaitingForY && !WaitingForX){
Y=data; WaitingForY=false;return;
}
else if(!WaitingForX && !WaitingForY && (UDR==END_SYNC_BYTE)){
reportBuffer.dx = X;
reportBuffer.dy = Y;
TransmissionComplete = true;return;
}else ResetValues();
return;
}
}
}