Не получается правильно передать данные

Нет ответов
xorkrus
Offline
Зарегистрирован: 22.09.2013

Проблема в том, что пытаюсь выполнить задачу не по силам :)

Задача: данные с BMP085 отправить через CDC на компьютер

Код на данный момент такой:

/* Name: main.c
 * Project: AVR USB driver for CDC interface on Low-Speed USB
 *          - Simple peripheral controller
 * Author: Osamu Tamura
 * Creation Date: 2007-05-12
 * Tabsize: 4
 * Copyright: (c) 2007 by Recursion Co., Ltd.
 * License: Proprietary, free under certain conditions. See Documentation.
 *
 */

#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include "usbdrv.h"
#include "oddebug.h"
//BMP
#include <stdlib.h>
#include <stdio.h>
#include "types.h"
#include "defs.h"
#include "i2c.h"
#define BMP085_R 0xEF
#define BMP085_W 0xEE
#define OSS 0	// Oversampling Setting (note: code is not set up to use other OSS values)

#define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
#define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))

///============Function Prototypes=========/////////////////
void BMP085_Calibration(void);

///============I2C Prototypes=============//////////////////
short bmp085ReadShort(unsigned char address);
long bmp085ReadTemp(void);
long bmp085ReadPressure(void);
void bmp085Convert(long * temperature, long * pressure);

///============Initialize Prototypes=====//////////////////
void ioinit(void);
void delay_ms(uint16_t x);

/////=========Global Variables======////////////////////
short ac1;
short ac2; 
short ac3; 
unsigned short ac4;
unsigned short ac5;
unsigned short ac6;
short b1; 
short b2;
short mb;
short mc;
short md;

//BMP

#define INTERRUPT_REPORT    1

#define CMD_WHO     "cdc-io"

enum {
    SEND_ENCAPSULATED_COMMAND = 0,
    GET_ENCAPSULATED_RESPONSE,
    SET_COMM_FEATURE,
    GET_COMM_FEATURE,
    CLEAR_COMM_FEATURE,
    SET_LINE_CODING = 0x20,
    GET_LINE_CODING,
    SET_CONTROL_LINE_STATE,
    SEND_BREAK
};


static PROGMEM char configDescrCDC[] = {   /* USB configuration descriptor */
    9,          /* sizeof(usbDescrConfig): length of descriptor in bytes */
    USBDESCR_CONFIG,    /* descriptor type */
    67,
    0,          /* total length of data returned (including inlined descriptors) */
    2,          /* number of interfaces in this configuration */
    1,          /* index of this configuration */
    0,          /* configuration name string index */
#if USB_CFG_IS_SELF_POWERED
    USBATTR_SELFPOWER,  /* attributes */
#else
    USBATTR_BUSPOWER,   /* attributes */
#endif
    USB_CFG_MAX_BUS_POWER/2,            /* max USB current in 2mA units */

    /* interface descriptor follows inline: */
    9,          /* sizeof(usbDescrInterface): length of descriptor in bytes */
    USBDESCR_INTERFACE, /* descriptor type */
    0,          /* index of this interface */
    0,          /* alternate setting for this interface */
    USB_CFG_HAVE_INTRIN_ENDPOINT,   /* endpoints excl 0: number of endpoint descriptors to follow */
    USB_CFG_INTERFACE_CLASS,
    USB_CFG_INTERFACE_SUBCLASS,
    USB_CFG_INTERFACE_PROTOCOL,
    0,          /* string index for interface */

    /* CDC Class-Specific descriptor */
    5,           /* sizeof(usbDescrCDC_HeaderFn): length of descriptor in bytes */
    0x24,        /* descriptor type */
    0,           /* header functional descriptor */
    0x10, 0x01,

    4,           /* sizeof(usbDescrCDC_AcmFn): length of descriptor in bytes */
    0x24,        /* descriptor type */
    2,           /* abstract control management functional descriptor */
    0x02,        /* SET_LINE_CODING,    GET_LINE_CODING, SET_CONTROL_LINE_STATE    */

    5,           /* sizeof(usbDescrCDC_UnionFn): length of descriptor in bytes */
    0x24,        /* descriptor type */
    6,           /* union functional descriptor */
    0,           /* CDC_COMM_INTF_ID */
    1,           /* CDC_DATA_INTF_ID */

    5,           /* sizeof(usbDescrCDC_CallMgtFn): length of descriptor in bytes */
    0x24,        /* descriptor type */
    1,           /* call management functional descriptor */
    3,           /* allow management on data interface, handles call management by itself */
    1,           /* CDC_DATA_INTF_ID */

    /* Endpoint Descriptor */
    7,           /* sizeof(usbDescrEndpoint) */
    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
    0x80|USB_CFG_EP3_NUMBER,        /* IN endpoint number */
    0x03,        /* attrib: Interrupt endpoint */
    8, 0,        /* maximum packet size */
    USB_CFG_INTR_POLL_INTERVAL,        /* in ms */

    /* Interface Descriptor  */
    9,           /* sizeof(usbDescrInterface): length of descriptor in bytes */
    USBDESCR_INTERFACE,           /* descriptor type */
    1,           /* index of this interface */
    0,           /* alternate setting for this interface */
    2,           /* endpoints excl 0: number of endpoint descriptors to follow */
    0x0A,        /* Data Interface Class Codes */
    0,
    0,           /* Data Interface Class Protocol Codes */
    0,           /* string index for interface */

    /* Endpoint Descriptor */
    7,           /* sizeof(usbDescrEndpoint) */
    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
    0x01,        /* OUT endpoint number 1 */
    0x02,        /* attrib: Bulk endpoint */
    8, 0,        /* maximum packet size */
    0,           /* in ms */

    /* Endpoint Descriptor */
    7,           /* sizeof(usbDescrEndpoint) */
    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
    0x81,        /* IN endpoint number 1 */
    0x02,        /* attrib: Bulk endpoint */
    8, 0,        /* maximum packet size */
    0,           /* in ms */
};

uchar usbFunctionDescriptor(usbRequest_t *rq)
{

    if(rq->wValue.bytes[1] == USBDESCR_DEVICE){
        usbMsgPtr = (uchar *)usbDescriptorDevice;
        return usbDescriptorDevice[0];
    }else{  /* must be config descriptor */
        usbMsgPtr = (uchar *)configDescrCDC;
        return sizeof(configDescrCDC);
    }
}

static uchar    modeBuffer[7];
static uchar    sendEmptyFrame;
static uchar    intr3Status;    /* used to control interrupt endpoint transmissions */

/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */

uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t    *rq = (void *)data;

    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */

        if( rq->bRequest==GET_LINE_CODING || rq->bRequest==SET_LINE_CODING ){
            return 0xff;
        /*    GET_LINE_CODING -> usbFunctionRead()    */
        /*    SET_LINE_CODING -> usbFunctionWrite()    */
        }
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
        if(rq->bRequest == SET_CONTROL_LINE_STATE){
            /* Report serial state (carrier detect). On several Unix platforms,
             * tty devices can only be opened when carrier detect is set.
             */
            if( intr3Status==0 )
                intr3Status = 2;
        }
#endif
#if 1
        /*  Prepare bulk-in endpoint to respond to early termination   */
        if((rq->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_HOST_TO_DEVICE)
            sendEmptyFrame  = 1;
#endif
    }

    return 0;
}

/*---------------------------------------------------------------------------*/
/* usbFunctionRead                                                           */
/*---------------------------------------------------------------------------*/

uchar usbFunctionRead( uchar *data, uchar len )
{
    memcpy( data, modeBuffer, 7 );
    return 7;
}

/*---------------------------------------------------------------------------*/
/* usbFunctionWrite                                                          */
/*---------------------------------------------------------------------------*/

uchar usbFunctionWrite( uchar *data, uchar len )
{
    memcpy( modeBuffer, data, 7 );
    return 1;
}


#define TBUF_SZ     256
#define TBUF_MSK    (TBUF_SZ-1)
//static uchar tos, val, val2;
static uchar rcnt, twcnt, trcnt;
static char tbuf[TBUF_SZ];
//static char rbuf[8], tbuf[TBUF_SZ];




static uchar u2h( uchar u )
{
    if( u>9 )
        u    += 7;
    return u+'0';
}

/*static uchar h2u( uchar h )
{
    h    -= '0';
    if( h>9 )
        h    -= 7;
    return h;
}*/

static void out_char( uchar c )
{
    tbuf[twcnt++]    = c;
#if TBUF_SZ<256
    twcnt   &= TBUF_MSK;
#endif
}

//////////-----------------///////////////

#if INTERRUPT_REPORT

static uchar   intr_flag[4];

#define INTR_REG(x)     { intr_flag[x>>3] |= 1<<(x&7); }

#if _AVR_IOM8_H_ || _AVR_IOM16_H_
#define INTR_MIN        4
    ISR( TIMER2_COMP_vect )     INTR_REG(4)
    ISR( TIMER2_OVF_vect )      INTR_REG(5)
    ISR( TIMER1_CAPT_vect )     INTR_REG(6)
    ISR( TIMER1_COMPA_vect )    INTR_REG(7)
    ISR( TIMER1_COMPB_vect )    INTR_REG(8)
    ISR( TIMER1_OVF_vect )      INTR_REG(9)
    ISR( TIMER0_OVF_vect )      INTR_REG(10)
    ISR( SPI_STC_vect )         INTR_REG(11)
    ISR( USART_RXC_vect )       INTR_REG(12)
    ISR( USART_UDRE_vect )      INTR_REG(13)
    ISR( USART_TXC_vect )       INTR_REG(14)
    ISR( ADC_vect )             INTR_REG(15)
    ISR( EE_RDY_vect )          INTR_REG(16)
    ISR( ANA_COMP_vect )        INTR_REG(17)
    ISR( TWI_vect )             INTR_REG(18)
#if _AVR_IOM8_H_
#define INTR_MAX        19
    ISR( SPM_RDY_vect )         INTR_REG(19)
#else
#define INTR_MAX        21
    ISR( INT2_vect )            INTR_REG(19)
    ISR( TIMER0_COMP_vect )     INTR_REG(20)
    ISR( SPM_RDY_vect )         INTR_REG(21)
#endif
#endif
#if _AVR_IOMX8_H_ || _AVR_IOM328P_H_
#define INTR_MIN        4
#define INTR_MAX        26
    ISR( PCINT0_vect )          INTR_REG(4)
    ISR( PCINT1_vect )          INTR_REG(5)
    ISR( PCINT2_vect )          INTR_REG(6)
    ISR( WDT_vect )             INTR_REG(7)
    ISR( TIMER2_COMPA_vect )    INTR_REG(8)
    ISR( TIMER2_COMPB_vect )    INTR_REG(9)
    ISR( TIMER2_OVF_vect )      INTR_REG(10)
    ISR( TIMER1_CAPT_vect )     INTR_REG(11)
    ISR( TIMER1_COMPA_vect )    INTR_REG(12)
    ISR( TIMER1_COMPB_vect )    INTR_REG(13)
    ISR( TIMER1_OVF_vect )      INTR_REG(14)
    ISR( TIMER0_COMPA_vect )    INTR_REG(15)
    ISR( TIMER0_COMPB_vect )    INTR_REG(16)
    ISR( TIMER0_OVF_vect )      INTR_REG(17)
    ISR( SPI_STC_vect )         INTR_REG(18)
    ISR( USART_RX_vect )        INTR_REG(19)
    ISR( USART_UDRE_vect )      INTR_REG(20)
    ISR( USART_TX_vect )        INTR_REG(21)
    ISR( ADC_vect )             INTR_REG(22)
    ISR( EE_READY_vect )        INTR_REG(23)
    ISR( ANALOG_COMP_vect )     INTR_REG(24)
    ISR( TWI_vect )             INTR_REG(25)
    ISR( SPM_READY_vect )       INTR_REG(26)
#endif

static void report_interrupt(void)
{
uchar    i, j;

    for( i=INTR_MIN; i<=INTR_MAX; i++ ) {
        j   = i >> 3;
        if( intr_flag[j]==0 ) {
            i   = ( ++j << 3 ) - 1;
            continue;
        }
        if( intr_flag[j] & 1<<(i&7) ) {
            intr_flag[j] &= ~(1<<(i&7));

            out_char( '\\' ); 
            out_char( u2h(i>>4) ); 
            out_char( u2h(i&0x0f) ); 
            out_char( '\r' ); 
            out_char( '\n' ); 
            break;
        }
    }
}
#endif


static void hardwareInit(void)
{
uchar    i;

    /* activate pull-ups except on USB lines */
    USB_CFG_IOPORT   = (uchar)~((1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT));
    /* all pins input except USB (-> USB reset) */
#ifdef USB_CFG_PULLUP_IOPORT    /* use usbDeviceConnect()/usbDeviceDisconnect() if available */
    USBDDR    = 0;    /* we do RESET by deactivating pullup */
    usbDeviceDisconnect();
#else
    USBDDR    = (1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT);
#endif

    for(i=0;i<20;i++){  /* 300 ms disconnect */
        wdt_reset();
            _delay_ms(15);
    }

#ifdef USB_CFG_PULLUP_IOPORT
    usbDeviceConnect();
#else
    USBDDR    = 0;      /*  remove USB reset condition */
#endif
}
char buffer[33];
char buffer2[33];
int main(void)
{
	// BMP
	long temperature = 0;
	long pressure = 0;
	ioinit();
	i2cInit();
	delay_ms(100);
	BMP085_Calibration();
	// BMP

	wdt_enable(WDTO_1S);
    odDebugInit();
    hardwareInit();
    usbInit();

    intr3Status = 0;
    sendEmptyFrame  = 0;

    rcnt    = 0;
    twcnt   = 0;
    trcnt   = 0;

    sei();
    for(;;){    /* main event loop */
        wdt_reset();
        usbPoll();
		
        /*    device -> host    */
        if( usbInterruptIsReady() ) {
            if( twcnt!=trcnt || sendEmptyFrame ) {
//////////////////////////////////////////////////////////////////////
				bmp085Convert(&temperature, &pressure);

				out_char( temperature ); 
				out_char( '|' );
				out_char( pressure );
				out_char( '|' );

				itoa (temperature,buffer,33);
				out_char( *buffer );

				out_char( '|' );

				itoa (pressure,buffer2,33);
				out_char( *buffer2 );

				out_char( '\n' ); 
//////////////////////////////////////////////////////////////////////
                uchar    tlen;
                tlen    = twcnt>=trcnt? (twcnt-trcnt):(TBUF_SZ-trcnt);
                if( tlen>8 )
                    tlen    = 8;
                usbSetInterrupt((uchar *)tbuf+trcnt, tlen);
                trcnt   += tlen;
                trcnt   &= TBUF_MSK;
                /* send an empty block after last data block to indicate transfer end */
                sendEmptyFrame = (tlen==8 && twcnt==trcnt)? 1:0;
            }
        }

#if INTERRUPT_REPORT
        report_interrupt();
#endif

#if USB_CFG_HAVE_INTRIN_ENDPOINT3
        /* We need to report rx and tx carrier after open attempt */
        if(intr3Status != 0 && usbInterruptIsReady3()){
            static uchar serialStateNotification[10] = {0xa1, 0x20, 0, 0, 0, 0, 2, 0, 3, 0};

            if(intr3Status == 2){
                usbSetInterrupt3(serialStateNotification, 8);
            }else{
                usbSetInterrupt3(serialStateNotification+8, 2);
            }
            intr3Status--;
        }
#endif
    }
    return 0;
}
// BMP
void BMP085_Calibration(void)
{
	ac1 = bmp085ReadShort(0xAA);
	ac2 = bmp085ReadShort(0xAC);
	ac3 = bmp085ReadShort(0xAE);
	ac4 = bmp085ReadShort(0xB0);
	ac5 = bmp085ReadShort(0xB2);
	ac6 = bmp085ReadShort(0xB4);
	b1 = bmp085ReadShort(0xB6);
	b2 = bmp085ReadShort(0xB8);
	mb = bmp085ReadShort(0xBA);
	mc = bmp085ReadShort(0xBC);
	md = bmp085ReadShort(0xBE);
}

short bmp085ReadShort(unsigned char address)
{
	char msb, lsb;
	short data;
	
	i2cSendStart();
	i2cWaitForComplete();
	
	i2cSendByte(BMP085_W);	// write 0xEE
	i2cWaitForComplete();
	
	i2cSendByte(address);	// write register address
	i2cWaitForComplete();
	
	i2cSendStart();
	
	i2cSendByte(BMP085_R);	// write 0xEF
	i2cWaitForComplete();
	
	i2cReceiveByte(TRUE);
	i2cWaitForComplete();
	msb = i2cGetReceivedByte();	// Get MSB result
	i2cWaitForComplete();
	
	i2cReceiveByte(FALSE);
	i2cWaitForComplete();
	lsb = i2cGetReceivedByte();	// Get LSB result
	i2cWaitForComplete();
	
	i2cSendStop();
	
	data = msb << 8;
	data |= lsb;
	
	return data;
}

long bmp085ReadTemp(void)
{
	i2cSendStart();
	i2cWaitForComplete();
	
	i2cSendByte(BMP085_W);	// write 0xEE
	i2cWaitForComplete();
	
	i2cSendByte(0xF4);	// write register address
	i2cWaitForComplete();
	
	i2cSendByte(0x2E);	// write register data for temp
	i2cWaitForComplete();
	
	i2cSendStop();
	
	delay_ms(1000);	// max time is 4.5ms
	
	return (long) bmp085ReadShort(0xF6);
}

long bmp085ReadPressure(void)
{
	long pressure = 0;
	
	i2cSendStart();
	i2cWaitForComplete();
	
	i2cSendByte(BMP085_W);	// write 0xEE
	i2cWaitForComplete();
	
	i2cSendByte(0xF4);	// write register address
	i2cWaitForComplete();
	
	i2cSendByte(0x34);	// write register data for temp
	i2cWaitForComplete();
	
	i2cSendStop();
	
	delay_ms(1000);	// max time is 4.5ms
	
	pressure = bmp085ReadShort(0xF6);
	pressure &= 0x0000FFFF;
	
	return pressure;
	
	//return (long) bmp085ReadShort(0xF6);
}

void bmp085Convert(long* temperature, long* pressure)
{
	long ut;
	long up;
	long x1, x2, b5, b6, x3, b3, p;
	unsigned long b4, b7;
	
	ut = bmp085ReadTemp();
	ut = bmp085ReadTemp();	// some bug here, have to read twice to get good data
	up = bmp085ReadPressure();
	up = bmp085ReadPressure();
	
	x1 = ((long)ut - ac6) * ac5 >> 15;
	x2 = ((long) mc << 11) / (x1 + md);
	b5 = x1 + x2;
	*temperature = ((b5 + 8) >> 4)/10.0;

	b6 = b5 - 4000;
	x1 = (b2 * (b6 * b6 >> 12)) >> 11;
	x2 = ac2 * b6 >> 11;
	x3 = x1 + x2;
	b3 = (((int32_t) ac1 * 4 + x3) + 2)/4;
	x1 = ac3 * b6 >> 13;
	x2 = (b1 * (b6 * b6 >> 12)) >> 16;
	x3 = ((x1 + x2) + 2) >> 2;
	b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
	b7 = ((unsigned long) up - b3) * (50000 >> OSS);
	p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
	x1 = (p >> 8) * (p >> 8);
	x1 = (x1 * 3038) >> 16;
	x2 = (-7357 * p) >> 16;
	*pressure = (p + ((x1 + x2 + 3791) >> 4))/133.32;
}

void ioinit (void)
{
    //1 = output, 0 = input
    DDRC = 0b00010000; //PORTC4 (SDA), PORTC5 (SCL), PORTC all others are inputs
	PORTC = 0b00110000; //pullups on the I2C bus
}

// BMP


void usbFunctionWriteOut( uchar *data, uchar len )
{
    //  postpone receiving next data    
    usbDisableAllRequests();
	
    //    host -> device:  request   
        char    c;
        //    delimiter?
        c    = *data++;
        if( rcnt>=1 || rcnt == 0 ) {
            const char            *ptr;
                        ptr = PSTR( CMD_WHO );
						//ptr = (PSTR("%d"), temperature);
                        while( (c=pgm_read_byte(ptr++))!=0 ) {
                            out_char(c); 
                        }
            out_char( '\n' ); 
        }
    usbEnableAllRequests();
}

В строках с 413 по 430 собственно пытаюсь отправить данные. temperature и pressure содержат данные типа long. На компьютере принимаю нечитаемые символы, которые, тем не менее, изменяются при нагреве\охлаждении датчика.

Подскажите, пожалуйста, в чем теперь проблема.