From edb3b0c36a394b43f7f562729b0d302e94c56d67 Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Thu, 9 Dec 2010 22:29:24 +0100 Subject: [PATCH] display and usb testcode, seems to work --- cmdline/Makefile | 48 ++++++++++ cmdline/opendevice.c | 203 +++++++++++++++++++++++++++++++++++++++++++ cmdline/opendevice.h | 77 ++++++++++++++++ cmdline/opendevice.o | Bin 0 -> 12468 bytes cmdline/set-led.c | 82 +++++++++++++++++ cmdline/set-led.o | Bin 0 -> 5912 bytes firmware/Makefile | 2 +- firmware/main.c | 155 +++++++++++++++++++-------------- firmware/main.h | 1 + firmware/spi.c | 8 +- firmware/spi.h | 6 +- 11 files changed, 504 insertions(+), 78 deletions(-) create mode 100644 cmdline/Makefile create mode 100644 cmdline/opendevice.c create mode 100644 cmdline/opendevice.h create mode 100644 cmdline/opendevice.o create mode 100644 cmdline/set-led.c create mode 100644 cmdline/set-led.o diff --git a/cmdline/Makefile b/cmdline/Makefile new file mode 100644 index 0000000..aaa948a --- /dev/null +++ b/cmdline/Makefile @@ -0,0 +1,48 @@ +# Name: Makefile +# Project: custom-class example +# Author: Christian Starkjohann +# Creation Date: 2008-04-06 +# Tabsize: 4 +# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH +# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) +# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $ + + +# Concigure the following definitions according to your system. +# This Makefile has been tested on Mac OS X, Linux and Windows. + +# Use the following 3 lines on Unix (uncomment the framework on Mac OS X): +USBFLAGS = `libusb-config --cflags` +USBLIBS = `libusb-config --libs` +EXE_SUFFIX = + +# Use the following 3 lines on Windows and comment out the 3 above. You may +# have to change the include paths to where you installed libusb-win32 +#USBFLAGS = -I/usr/local/include +#USBLIBS = -L/usr/local/lib -lusb +#EXE_SUFFIX = .exe + +NAME = set-led + +OBJECTS = opendevice.o $(NAME).o + +CC = gcc +CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall +LIBS = $(USBLIBS) + +PROGRAM = $(NAME)$(EXE_SUFFIX) + + +all: $(PROGRAM) + +.c.o: + $(CC) $(CFLAGS) -c $< + +$(PROGRAM): $(OBJECTS) + $(CC) -o $(PROGRAM) $(OBJECTS) $(LIBS) + +strip: $(PROGRAM) + strip $(PROGRAM) + +clean: + rm -f *.o $(PROGRAM) diff --git a/cmdline/opendevice.c b/cmdline/opendevice.c new file mode 100644 index 0000000..137f50c --- /dev/null +++ b/cmdline/opendevice.c @@ -0,0 +1,203 @@ +/* Name: opendevice.c + * Project: V-USB host-side library + * Author: Christian Starkjohann + * Creation Date: 2008-04-10 + * Tabsize: 4 + * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH + * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) + * This Revision: $Id: opendevice.c 740 2009-04-13 18:23:31Z cs $ + */ + +/* +General Description: +The functions in this module can be used to find and open a device based on +libusb or libusb-win32. +*/ + +#include +#include "opendevice.h" + +/* ------------------------------------------------------------------------- */ + +#define MATCH_SUCCESS 1 +#define MATCH_FAILED 0 +#define MATCH_ABORT -1 + +/* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or MATCH_ABORT. */ +static int _shellStyleMatch(char *text, char *p) +{ +int last, matched, reverse; + + for(; *p; text++, p++){ + if(*text == 0 && *p != '*') + return MATCH_ABORT; + switch(*p){ + case '\\': + /* Literal match with following character. */ + p++; + /* FALLTHROUGH */ + default: + if(*text != *p) + return MATCH_FAILED; + continue; + case '?': + /* Match anything. */ + continue; + case '*': + while(*++p == '*') + /* Consecutive stars act just like one. */ + continue; + if(*p == 0) + /* Trailing star matches everything. */ + return MATCH_SUCCESS; + while(*text) + if((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED) + return matched; + return MATCH_ABORT; + case '[': + reverse = p[1] == '^'; + if(reverse) /* Inverted character class. */ + p++; + matched = MATCH_FAILED; + if(p[1] == ']' || p[1] == '-') + if(*++p == *text) + matched = MATCH_SUCCESS; + for(last = *p; *++p && *p != ']'; last = *p) + if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p) + matched = MATCH_SUCCESS; + if(matched == reverse) + return MATCH_FAILED; + continue; + } + } + return *text == 0; +} + +/* public interface for shell style matching: returns 0 if fails, 1 if matches */ +static int shellStyleMatch(char *text, char *pattern) +{ + if(pattern == NULL) /* NULL pattern is synonymous to "*" */ + return 1; + return _shellStyleMatch(text, pattern) == MATCH_SUCCESS; +} + +/* ------------------------------------------------------------------------- */ + +int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen) +{ +char buffer[256]; +int rval, i; + + if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ + return rval; + if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) + return rval; + if(buffer[1] != USB_DT_STRING){ + *buf = 0; + return 0; + } + if((unsigned char)buffer[0] < rval) + rval = (unsigned char)buffer[0]; + rval /= 2; + /* lossy conversion to ISO Latin1: */ + for(i=1;i buflen) /* destination buffer overflow */ + break; + buf[i-1] = buffer[2 * i]; + if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ + buf[i-1] = '?'; + } + buf[i-1] = 0; + return i-1; +} + +/* ------------------------------------------------------------------------- */ + +int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp) +{ +struct usb_bus *bus; +struct usb_device *dev; +usb_dev_handle *handle = NULL; +int errorCode = USBOPEN_ERR_NOTFOUND; + + usb_find_busses(); + usb_find_devices(); + for(bus = usb_get_busses(); bus; bus = bus->next){ + for(dev = bus->devices; dev; dev = dev->next){ /* iterate over all devices on all busses */ + if((vendorID == 0 || dev->descriptor.idVendor == vendorID) + && (productID == 0 || dev->descriptor.idProduct == productID)){ + char vendor[256], product[256], serial[256]; + int len; + handle = usb_open(dev); /* we need to open the device in order to query strings */ + if(!handle){ + errorCode = USBOPEN_ERR_ACCESS; + if(warningsFp != NULL) + fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); + continue; + } + /* now check whether the names match: */ + len = vendor[0] = 0; + if(dev->descriptor.iManufacturer > 0){ + len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor)); + } + if(len < 0){ + errorCode = USBOPEN_ERR_ACCESS; + if(warningsFp != NULL) + fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); + }else{ + errorCode = USBOPEN_ERR_NOTFOUND; + /* printf("seen device from vendor ->%s<-\n", vendor); */ + if(shellStyleMatch(vendor, vendorNamePattern)){ + len = product[0] = 0; + if(dev->descriptor.iProduct > 0){ + len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product)); + } + if(len < 0){ + errorCode = USBOPEN_ERR_ACCESS; + if(warningsFp != NULL) + fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); + }else{ + errorCode = USBOPEN_ERR_NOTFOUND; + /* printf("seen product ->%s<-\n", product); */ + if(shellStyleMatch(product, productNamePattern)){ + len = serial[0] = 0; + if(dev->descriptor.iSerialNumber > 0){ + len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial)); + } + if(len < 0){ + errorCode = USBOPEN_ERR_ACCESS; + if(warningsFp != NULL) + fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); + } + if(shellStyleMatch(serial, serialNamePattern)){ + if(printMatchingDevicesFp != NULL){ + if(serial[0] == 0){ + fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product); + }else{ + fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial); + } + }else{ + break; + } + } + } + } + } + } + usb_close(handle); + handle = NULL; + } + } + if(handle) /* we have found a deice */ + break; + } + if(handle != NULL){ + errorCode = 0; + *device = handle; + } + if(printMatchingDevicesFp != NULL) /* never return an error for listing only */ + errorCode = 0; + return errorCode; +} + +/* ------------------------------------------------------------------------- */ diff --git a/cmdline/opendevice.h b/cmdline/opendevice.h new file mode 100644 index 0000000..79c12f6 --- /dev/null +++ b/cmdline/opendevice.h @@ -0,0 +1,77 @@ +/* Name: opendevice.h + * Project: V-USB host-side library + * Author: Christian Starkjohann + * Creation Date: 2008-04-10 + * Tabsize: 4 + * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH + * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) + * This Revision: $Id: opendevice.h 755 2009-08-03 17:01:21Z cs $ + */ + +/* +General Description: +This module offers additional functionality for host side drivers based on +libusb or libusb-win32. It includes a function to find and open a device +based on numeric IDs and textual description. It also includes a function to +obtain textual descriptions from a device. + +To use this functionality, simply copy opendevice.c and opendevice.h into your +project and add them to your Makefile. You may modify and redistribute these +files according to the GNU General Public License (GPL) version 2 or 3. +*/ + +#ifndef __OPENDEVICE_H_INCLUDED__ +#define __OPENDEVICE_H_INCLUDED__ + +#include /* this is libusb, see http://libusb.sourceforge.net/ */ +#include + +int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen); +/* This function gets a string descriptor from the device. 'index' is the + * string descriptor index. The string is returned in ISO Latin 1 encoding in + * 'buf' and it is terminated with a 0-character. The buffer size must be + * passed in 'buflen' to prevent buffer overflows. A libusb device handle + * must be given in 'dev'. + * Returns: The length of the string (excluding the terminating 0) or + * a negative number in case of an error. If there was an error, use + * usb_strerror() to obtain the error message. + */ + +int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp); +/* This function iterates over all devices on all USB busses and searches for + * a device. Matching is done first by means of Vendor- and Product-ID (passed + * in 'vendorID' and 'productID'. An ID of 0 matches any numeric ID (wildcard). + * When a device matches by its IDs, matching by names is performed. Name + * matching can be done on textual vendor name ('vendorNamePattern'), product + * name ('productNamePattern') and serial number ('serialNamePattern'). A + * device matches only if all non-null pattern match. If you don't care about + * a string, pass NULL for the pattern. Patterns are Unix shell style pattern: + * '*' stands for 0 or more characters, '?' for one single character, a list + * of characters in square brackets for a single character from the list + * (dashes are allowed to specify a range) and if the lis of characters begins + * with a caret ('^'), it matches one character which is NOT in the list. + * Other parameters to the function: If 'warningsFp' is not NULL, warning + * messages are printed to this file descriptor with fprintf(). If + * 'printMatchingDevicesFp' is not NULL, no device is opened but matching + * devices are printed to the given file descriptor with fprintf(). + * If a device is opened, the resulting USB handle is stored in '*device'. A + * pointer to a "usb_dev_handle *" type variable must be passed here. + * Returns: 0 on success, an error code (see defines below) on failure. + */ + +/* usbOpenDevice() error codes: */ +#define USBOPEN_SUCCESS 0 /* no error */ +#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */ +#define USBOPEN_ERR_IO 2 /* I/O error */ +#define USBOPEN_ERR_NOTFOUND 3 /* device not found */ + + +/* Obdev's free USB IDs, see USB-IDs-for-free.txt for details */ + +#define USB_VID_OBDEV_SHARED 5824 /* obdev's shared vendor ID */ +#define USB_PID_OBDEV_SHARED_CUSTOM 1500 /* shared PID for custom class devices */ +#define USB_PID_OBDEV_SHARED_HID 1503 /* shared PID for HIDs except mice & keyboards */ +#define USB_PID_OBDEV_SHARED_CDCACM 1505 /* shared PID for CDC Modem devices */ +#define USB_PID_OBDEV_SHARED_MIDI 1508 /* shared PID for MIDI class devices */ + +#endif /* __OPENDEVICE_H_INCLUDED__ */ diff --git a/cmdline/opendevice.o b/cmdline/opendevice.o new file mode 100644 index 0000000000000000000000000000000000000000..559099b1de51376bd29ddc39fb105886eb1f82d0 GIT binary patch literal 12468 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 +#include +#include +#include /* this is libusb */ +#include "opendevice.h" /* common code moved to separate module */ + +#include "../firmware/usbdrv/usbconfig.h" /* device's VID/PID and names */ + +int main(int argc, char **argv) +{ +usb_dev_handle *handle = NULL; +const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID}; +char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0}; +char buffer[4]; +int cnt, vid, pid, isOn; + + usb_init(); + /* compute VID/PID from usbconfig.h so that there is a central source of information */ + vid = rawVid[1] * 256 + rawVid[0]; + pid = rawPid[1] * 256 + rawPid[0]; + /* The following function is in opendevice.c: */ + if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){ + fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid); + exit(1); + } + /* Since we use only control endpoint 0, we don't need to choose a + * configuration and interface. Reading device descriptor and setting a + * configuration and interface is done through endpoint 0 after all. + * However, newer versions of Linux require that we claim an interface + * even for endpoint 0. Enable the following code if your operating system + * needs it: */ +#if 0 + int retries = 1, usbConfiguration = 1, usbInterface = 0; + if(usb_set_configuration(handle, usbConfiguration) && showWarnings){ + fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror()); + } + /* now try to claim the interface and detach the kernel HID driver on + * Linux and other operating systems which support the call. */ + while((len = usb_claim_interface(handle, usbInterface)) != 0 && retries-- > 0){ +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP + if(usb_detach_kernel_driver_np(handle, 0) < 0 && showWarnings){ + fprintf(stderr, "Warning: could not detach kernel driver: %s\n", usb_strerror()); + } +#endif + } +#endif + int rxValue, rxIndex; + int value = 0, index = 0; + + int i=0; + cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, 2, value, index, buffer, sizeof(buffer), 5000); + if(cnt < 0){ + fprintf(stderr, "\nUSB error in iteration %d: %s\n", i, usb_strerror()); + } + rxValue = ((int)buffer[1] & 0xff) | (((int)buffer[0] & 0xff) << 8); + rxIndex = ((int)buffer[3] & 0xff) | (((int)buffer[2] & 0xff) << 8); + fprintf(stderr, "rxValue = %3d.%02d \n", rxValue/100, rxValue%100); + fprintf(stderr, "rxIndex = %3d.%02d \n", rxIndex/100, rxIndex%100); + + usb_close(handle); + return 0; +} diff --git a/cmdline/set-led.o b/cmdline/set-led.o new file mode 100644 index 0000000000000000000000000000000000000000..cdb20b83c1a2e86d7e3d406b002d98c3d611cb9a GIT binary patch literal 5912 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 literal 0 HcmV?d00001 diff --git a/firmware/Makefile b/firmware/Makefile index 983e53d..0abeb0f 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -1,7 +1,7 @@ DEFINES += -DF_CPU=16000000 CFLAGS += -save-temps -OBJECTS = usbdrv/usbdrvasm.o usbdrv/usbdrv.o main.o display.o lcd/lcd.o spi.o +OBJECTS = usbdrv/usbdrvasm.o usbdrv/usbdrv.o main.o display.o lcd/lcd.o diff --git a/firmware/main.c b/firmware/main.c index de78460..9ba01cd 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -3,98 +3,119 @@ #include #include #include +#include #include - #include "main.h" #include "display.h" +#include "spi.h" -void hardinit(){ - /* initializes the hardware */ - DDRB = _BV(1) | _BV(2) | _BV(0); - DDRC = 0x3f; +static uint8_t newThermoData = 1; +static uint16_t thermoData[] = {1024, 814, 2475, 2243}; - // no pullups; all digital outputs can take care of themselves - PORTB = 0x00; - PORTC = 0x00; - PORTD = 0x00; - /* hardware pwm for brightness/contrast: - */ +void hardinit() { + /* initializes the hardware */ + DDRB = _BV(1) | _BV(2) | _BV(0); + DDRC = 0x3f; - TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10); - TCCR1B = _BV(WGM12) | _BV(CS11); // clk/8 prescaler, 4kHz PWM-freq. + // no pullups; all digital outputs can take care of themselves + PORTB = 0x00; + PORTC = 0x00; + PORTD = 0x00; - OCR1A = 15; // contrast - OCR1B = 50; // brightness - - // init LCD: - lcd_init(1); - lcd_clrscr(1); + // hardware pwm for brightness/contrast: + TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10); + TCCR1B = _BV(WGM12) | _BV(CS11); // clk/8 prescaler, 4kHz PWM-freq. - // 1wire needs no own init, bus search is done in softinit + OCR1A = 15; // contrast + OCR1B = 50; // brightness + + // init LCD: + lcd_init(1); + lcd_clrscr(1); - sei(); + sei(); } - - -void softinit(){ - - lcd_defchar(1, LCD_CHAR_HALFBAR, lcd_halfbar_char); - lcd_defchar(1, LCD_CHAR_BAR, lcd_bar_char); - lcd_defchar(1, LCD_CHAR_DEGREE, lcd_degree_char); - +void softinit() { + lcd_defchar(1, LCD_CHAR_HALFBAR, lcd_halfbar_char); + lcd_defchar(1, LCD_CHAR_BAR, lcd_bar_char); + lcd_defchar(1, LCD_CHAR_DEGREE, lcd_degree_char); } +usbMsgLen_t usbFunctionSetup(uchar data[8]) { + usbRequest_t *rq = (void *)data; + static uchar dataBuffer[4]; /* buffer must stay valid when usbFunctionSetup returns */ + + if(rq->bRequest == 1){ /* echo -- used for reliability tests */ + dataBuffer[0] = (thermoData [0] & 0xff00)>>8; + dataBuffer[1] = thermoData [0] & 0x00ff; + dataBuffer[2] = (thermoData [1] & 0xff00)>>8; + dataBuffer[3] = thermoData [1] & 0x00ff; + usbMsgPtr = dataBuffer; /* tell the driver which data to return */ + return 4; + } + + if(rq->bRequest == 2){ /* echo -- used for reliability tests */ + dataBuffer[0] = (thermoData [2] & 0xff00)>>8; + dataBuffer[1] = thermoData [2] & 0x00ff; + dataBuffer[2] = (thermoData [3] & 0xff00)>>8; + dataBuffer[3] = thermoData [3] & 0x00ff; + usbMsgPtr = dataBuffer; /* tell the driver which data to return */ + return 4; + } + + return 0; /* default for not implemented requests: return no data back to host */ +} - -usbMsgLen_t usbFunctionSetup(uchar data[8]) -{ -usbRequest_t *rq = (void *)data; -static uchar dataBuffer[4]; /* buffer must stay valid when usbFunctionSetup returns */ - - if(rq->bRequest == 1){ /* echo -- used for reliability tests */ - dataBuffer[0] = rq->wValue.bytes[0]; - dataBuffer[1] = rq->wValue.bytes[1]; - dataBuffer[2] = rq->wIndex.bytes[0]; - dataBuffer[3] = rq->wIndex.bytes[1]; - usbMsgPtr = dataBuffer; /* tell the driver which data to return */ - return 4; - } - return 0; /* default for not implemented requests: return no data back to host */ +void updateDisplay() { + if(newThermoData==1) { + newThermoData = 0; + + char str[34]; + snprintf(str, 34, "%3d.%02d\x03||%3d.%02d\x03\n%3d.%02d\x03||%3d.%02d\x03", thermoData[0]/100, thermoData[0]%100, + thermoData[1]/100, thermoData[1]%100, + thermoData[2]/100, thermoData[2]%100, + thermoData[3]/100, thermoData[3]%100 + ); + display_gotoyx(0,0); + display_puts(str); + display_update(); + } } +int __attribute__((noreturn)) main(void) { + int i=0; + hardinit(); + softinit(); + usbInit(); -int __attribute__((noreturn)) main(void){ - hardinit(); - softinit(); - usbInit(); + display_puts("Hallo, Welt!\n\n"); + display_update(); - display_puts("Hallo, Welt!\n\n"); - display_update(); + + for(;;){ + usbPoll(); - - - for(;;){ - usbPoll(); - } + updateDisplay(); - -} + thermoData[0]=thermoData[0]+5; + thermoData[1]=thermoData[1]+15; + thermoData[2]=thermoData[2]+7; + thermoData[3]=thermoData[3]+18; + i++; if(i%200 == 0) newThermoData = 1; + } +} /* -ISR(TIMER1_OVF_vect, ISR_NAKED){ - asm volatile ("in %0, %1\n" : "=r" (sreg_store) : "I" (_SFR_IO_ADDR(SREG))); - timer1_acc++; - asm volatile ("out %1, %0\n" : "=r" (sreg_store) : "I" (_SFR_IO_ADDR(SREG))); - reti(); -}*/ - - - - + ISR(TIMER1_OVF_vect, ISR_NAKED){ + asm volatile ("in %0, %1\n" : "=r" (sreg_store) : "I" (_SFR_IO_ADDR(SREG))); + timer1_acc++; + asm volatile ("out %1, %0\n" : "=r" (sreg_store) : "I" (_SFR_IO_ADDR(SREG))); + reti(); + }*/ diff --git a/firmware/main.h b/firmware/main.h index f06c8ac..2f91f00 100644 --- a/firmware/main.h +++ b/firmware/main.h @@ -16,6 +16,7 @@ #ifndef __MAIN_H #define __MAIN_H + #include #define LED1PORT PORTC diff --git a/firmware/spi.c b/firmware/spi.c index 74b1e47..870a16d 100644 --- a/firmware/spi.c +++ b/firmware/spi.c @@ -34,23 +34,20 @@ void spi_init(){ d = spi_clock_divisor(); if(d>7){ -#warning "spi baudrate too slow, cannot be set" + #warning "spi baudrate too slow, cannot be set" d=7; } //TODO: DDRs setzen - spsr = 0; spsr |= (d & 1) ? 0 : _BV(SPI2X); spcr = 0 | _BV(SPIE) | _BV(SPE); spcr |= (d & 2) ? _BV(SPR0) : 0; spcr |= (d & 4) ? _BV(SPR1) : 0; - #ifdef SPI_MASTER spcr |= _BV(MSTR); #endif - SPCR = spcr; SPSR = spsr; @@ -60,7 +57,6 @@ void spi_init(){ spi_writeptr = NULL; } - // return true on success, false on error uint8_t spi_write(uint8_t *data, uint8_t len){ if(spi_writeptr != NULL){ @@ -72,8 +68,6 @@ uint8_t spi_write(uint8_t *data, uint8_t len){ return 1; } - - #ifdef SPI_MASTER ISR(SPI_vector){ diff --git a/firmware/spi.h b/firmware/spi.h index 493f10d..bc9969b 100644 --- a/firmware/spi.h +++ b/firmware/spi.h @@ -1,6 +1,6 @@ - - - #define SPI_BAUDRATE 1000000 #define SPI_MASTER 1 #define SPI_READBUF_LEN 32 + +uint8_t spi_write(uint8_t *data, uint8_t len); +void spi_init();