Не получается правильно передать данные
- Войдите на сайт для отправки комментариев
Ср, 14/05/2014 - 09:40
Проблема в том, что пытаюсь выполнить задачу не по силам :)
Задача: данные с 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. На компьютере принимаю нечитаемые символы, которые, тем не менее, изменяются при нагреве\охлаждении датчика.
Подскажите, пожалуйста, в чем теперь проблема.