Hallo,
danke für den Tipp, der war schon mal gold Wert. Nun brauche ich aber doch nochmal eure hilfe. Ich haben den Quelltext nun auf dem ATMEAG32 laufen. Leider sagt mein PC, dass er ein USB Device findet, dies aber Unknown ist und nicht erkannt wurde.
Ich tippe, das liegt evtl daran das ich den Prescaler in der Firmware nicht angepasst habe. Aber auf was soll ich den bei einem ATMEAG32 mit 16MHz setzen ???
Hier mal die Firmware, wie ich sie auf den AT gespielt habe. (Habe eigentlich alles so gelassen nur in der Makefile die CPU geändert und F_CPU auf 16 Mhz gesetzt. Dann habe ich noch in der USB Lib die 16 MHz aktiviert. Also denke ich dass es wirklich nur noch an dem Prescaler liegen kann.
Code:
/* Name: main.c
* Project: PowerSwitch based on AVR USB driver
* Author: Christian Starkjohann
* Creation Date: 2005-01-16
* Tabsize: 4
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
* This Revision: $Id: main.c 523 2008-02-15 09:46:40Z cs $
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include "usbdrv.h"
#include "oddebug.h"
#include <util/delay.h>
/*
This module implements an 8 bit parallel output controlled via USB. It is
intended to switch the power supply to computers and/or other electronic
devices.
Application examples:
- Rebooting computers located at the provider's site
- Remotely switch on/off of rarely used computers
- Rebooting other electronic equipment which is left unattended
- Control room heating from remote
*/
#ifndef TEST_DRIVER_SIZE /* define this to check out size of pure driver */
#define EEPROM_LOCATION (void *)37
static uchar actionTimers[8];
/* This is the AT90S2313 version of the routine. Change for others. */
static void outputByte(uchar b)
{
PORTB = (PORTB & ~0xfc) | (b & 0xfc);
PORTD = (PORTD & ~0x30) | ((b << 4) & 0x30);
}
static uchar computeTemporaryChanges(void)
{
uchar i, status = 0, mask = 1;
for(i=0;i<8;i++){
if(actionTimers[i])
status |= mask;
mask <<= 1;
}
return status;
}
static void computeOutputStatus(void)
{
uchar status = eeprom_read_byte(EEPROM_LOCATION) ^ computeTemporaryChanges();
outputByte(status);
}
/* We poll for the timer interrupt instead of declaring an interrupt handler
* with global interrupts enabled. This saves recursion depth. Our timer does
* not need high precision and does not run at a high rate anyway.
*/
static void timerInterrupt(void)
{
static uchar prescaler;
uchar i;
if(!prescaler--){
prescaler = 8; /* rate = 12M / 1024 * 256 * 9 */
for(i=0;i<8;i++){
if(actionTimers[i])
actionTimers[i]--;
}
computeOutputStatus();
}
}
USB_PUBLIC uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
uchar status = eeprom_read_byte(EEPROM_LOCATION);
static uchar replyBuf[2];
usbMsgPtr = replyBuf;
if(rq->bRequest == 0){ /* ECHO */
replyBuf[0] = rq->wValue.bytes[0];
replyBuf[1] = rq->wValue.bytes[1];
return 2;
}
if(rq->bRequest == 1){ /* GET_STATUS -> result = 2 bytes */
replyBuf[0] = status;
replyBuf[1] = computeTemporaryChanges();
return 2;
}
if(rq->bRequest == 2 || rq->bRequest == 3){ /* SWITCH_ON or SWITCH_OFF, index = bit number */
uchar bit = rq->wIndex.bytes[0] & 7;
uchar mask = 1 << bit;
uchar needChange, isOn = status & mask;
if(rq->bRequest == 2){ /* SWITCH_ON */
status |= mask;
needChange = !isOn;
}else{ /* SWITCH_OFF */
status &= ~mask;
needChange = isOn;
}
if(rq->wValue.bytes[0] == 0){ /* duration == 0 -> permanent switch */
actionTimers[bit] = 0; eeprom_write_byte(EEPROM_LOCATION, status);
}else if(needChange){ /* temporary switch: value = duration in 200ms units */
actionTimers[bit] = rq->wValue.bytes[0];
}
}
computeOutputStatus();
return 0;
}
/* allow some inter-device compatibility */
#if !defined TCCR0 && defined TCCR0B
#define TCCR0 TCCR0B
#endif
#if !defined TIFR && defined TIFR0
#define TIFR TIFR0
#endif
int main(void)
{
uchar i;
wdt_enable(WDTO_1S);
odDebugInit();
DDRD = ~(1 << 2); /* all outputs except PD2 = INT0 */
PORTD = 0;
PORTB = 0; /* no pullups on USB pins */
/* We fake an USB disconnect by pulling D+ and D- to 0 during reset. This is
* necessary if we had a watchdog reset or brownout reset to notify the host
* that it should re-enumerate the device. Otherwise the host's and device's
* concept of the device-ID would be out of sync.
*/
DDRB = ~USBMASK; /* set all pins as outputs except USB */
computeOutputStatus(); /* set output status before we do the delay */
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
i = 0;
while(--i){ /* fake USB disconnect for > 500 ms */
wdt_reset();
_delay_ms(2);
}
usbDeviceConnect();
TCCR0 = 5; /* set prescaler to 1/1024 */
usbInit();
sei();
for(;;){ /* main event loop */
wdt_reset();
usbPoll();
if(TIFR & (1 << TOV0)){
TIFR |= 1 << TOV0; /* clear pending flag */
timerInterrupt();
}
}
return 0;
}
#else /* TEST_DRIVER_SIZE */
/* This is the minimum do-nothing function to determine driver size. The
* resulting binary will consist of the C startup code, space for interrupt
* vectors and our minimal initialization. The C startup code and vectors
* (together ca. 70 bytes of flash) can not directly be considered a part
* of this driver. The driver is therefore ca. 70 bytes smaller than the
* resulting binary due to this overhead. The driver also contains strings
* of arbitrary length. You can save another ca. 50 bytes if you don't
* include a textual product and vendor description.
*/
uchar usbFunctionSetup(uchar data[8])
{
return 0;
}
int main(void)
{
#ifdef PORTD
PORTD = 0;
DDRD = ~(1 << 2); /* all outputs except PD2 = INT0 */
#endif
PORTB = 0; /* no pullups on USB pins */
DDRB = ~USBMASK; /* all outputs except USB data */
usbInit();
sei();
for(;;){ /* main event loop */
usbPoll();
}
return 0;
}
#endif /* TEST_DRIVER_SIZE */
Lesezeichen