swithcing from atmeg8 to atmega168
swithcing from atmeg8 to atmega168
Hi all, I'm very new to usb dev, so sorry in advance if this is a simple question. I have been on a project using Objective Development's firmware-only USB driver. The project started with an ATMEGA8 chip and I reached the max size. So I'm migrating to the ATMEGA168 chip. I believe a few changes need to be made but I dont know where? I feel I have the correct fues settings and the necessary changes in the make file. The chip burns but the usb device is not recognized. So I'm guessing its in the descriptor file or the usbconfig.h. Would any one be willing to give me a hand?
Re: swithcing from atmeg8 to atmega168
Well I was able to test with a scope and an LED blinker that both chips are clocked the same.
also in my code I had to change
TCCR0 to TCCR0B
TCCR2 to TCCR2B
OCR20 to OCR0A
TIFR to TIFR0 ( OCF0 to OCF0A )
Anyone have a thought?
also in my code I had to change
TCCR0 to TCCR0B
TCCR2 to TCCR2B
OCR20 to OCR0A
TIFR to TIFR0 ( OCF0 to OCF0A )
Anyone have a thought?
Re: swithcing from atmeg8 to atmega168
OCR20 to OCR0A ?
That doesn't look right (I assume you meant OCR2).
OCR2A would seem to be the natural replacement for OCR2.
That doesn't look right (I assume you meant OCR2).
OCR2A would seem to be the natural replacement for OCR2.
Re: swithcing from atmeg8 to atmega168
Actually It was OCF2, and I think it may go from TIFR ( OCF2 ) to TIFR2 ( OCF2A ) as is seem like a better choice.
Does any one know of an example project for the 88 or amega168 I can test with. I would need a usb device hello world or something like that. It has to be for an 88 style chip not the atmega8.
Does any one know of an example project for the 88 or amega168 I can test with. I would need a usb device hello world or something like that. It has to be for an 88 style chip not the atmega8.
Last edited by ulao on Thu Apr 02, 2009 2:47 pm, edited 3 times in total.
Re: swithcing from atmeg8 to atmega168
Check out Replacing ATmega8 by ATmega88, Migrating between ATmega48, ATmega88 and ATmega168, and Migrating from ATmega48/88 and ATmega48P/88P to ATmega48PA/88PA. Also, IIRC the electrical specs for the I/O pins are different betw. the 8 and 88. If you use Z-diodes on D+/D-, they HAVE to be 3V6/<= 500mW.
Re: swithcing from atmeg8 to atmega168
So my 1w 1n4729a will not do... darn
Re: swithcing from atmeg8 to atmega168
dup
Last edited by ulao on Sat Apr 04, 2009 8:31 pm, edited 1 time in total.
Re: swithcing from atmeg8 to atmega168
3.6 V 0.50W with same results.
I was able to get the hid mouse example to work. So I now know its the code. but I really dont see what it could be. Here is my current hardware init.
I'm also thinking it could be something in the usbconfig as the original author made some changes. So I'm going to look in to that.
I was able to get the hid mouse example to work. So I now know its the code. but I really dont see what it could be. Here is my current hardware init.
Code: Select all
static void hardwareInit(void)
{
//PCICR &= !(1 << PCIE1);
uchar i, j;
// init port C as input with pullup
DDRC = 0x00; /* all pins input */
PORTC = 0xff;/* activate all pull-ups */
/* 1101 1000 bin: activate pull-ups except on USB lines
*
* USB signals are on bit 0 and 2.
*
* Bit 1 is connected with bit 0 (rev.C pcb error), so the pullup
* is not enabled. So pin 0 1 2 are all 0.
* */
PORTD = 0xf8;
/* Usb pin are init as outputs */
//dont reset pin 2
DDRD = 0x01 | 0x04; //0101 ( why not just use 0x05 ?
j = 0;
while(--j){ /* USB Reset by device only required on Watchdog Reset */
i = 0;
while(--i) { }; /* delay >10ms for USB reset */
}
// make sure pin 2 is also input, normal is 0x02.
DDRD = 0x00; /* 0000 0000 bin: remove USB reset condition */
/* configure timer 0 for a rate of 12M/(1024 * 256) = 45.78 Hz (~22ms) */
TCCR0A = 0; /* added for the atmega168, Normal Mode, OC disabled */
TCCR0B = 5; /* timer 0 prescaler: 1024 */
TCCR2A = (1<<WGM21);
TCCR2B = (1<<CS22)|(1<<CS21)|(1<<CS20);
OCR2A = 196; // for 60 hz
}
I'm also thinking it could be something in the usbconfig as the original author made some changes. So I'm going to look in to that.
Re: swithcing from atmeg8 to atmega168
turns out it was an old usbdrv, the actual file that was causing issues was usbdrvasm.o. I dont understand this level of the code but my guess is this fie was updated in 08. The bad usbdrvasm files show 12/12/07 the good show 3/12/08.
Re: swithcing from atmeg8 to atmega168
hEY
having the same problem with porting from atmega8 to atmega48 I stumbled over your very interessant post. So you say, I just would have to use a newer version of usbdrv.h and change my registers that way: TCCR0=5 -> TCCR0B=5; TIFR -> TIFR0 and I am off for a basic working set of HIDKeys?
I can't gat it to work doing only what I mentioned above. I used the usbdrv version 20081126 right now.
Please some help...
cheers
goeck
having the same problem with porting from atmega8 to atmega48 I stumbled over your very interessant post. So you say, I just would have to use a newer version of usbdrv.h and change my registers that way: TCCR0=5 -> TCCR0B=5; TIFR -> TIFR0 and I am off for a basic working set of HIDKeys?
I can't gat it to work doing only what I mentioned above. I used the usbdrv version 20081126 right now.
Please some help...
cheers
goeck
Re: swithcing from atmeg8 to atmega168
Should not be a problem, but to be honest there are so many thing to check.
the driver
the fuses
the code changes
the diodes
There is a bit more to each individual part above. If you know you have the latest driver, post your fuses, then post the code, or a bit of feed back so we can help.
the driver
the fuses
the code changes
the diodes
There is a bit more to each individual part above. If you know you have the latest driver, post your fuses, then post the code, or a bit of feed back so we can help.
Re: swithcing from atmeg8 to atmega168
Oh hey, someone there
Ok, there u go, here is my code:
Here are my fuses (high/low):
As I previously wrote, I am using the latest driver (at least one of the latest): Nov2008.
My circuit is the original circuit from the HIDKeys project. I also tried the circuit used by the usbasp project (with 3v6 and 3v3 zehners). Both did'nt work for me.
cheers guys
Ok, there u go, here is my code:
Code: Select all
/* Name: main.c
* Project: HID-Test
* Author: Christian Starkjohann
* Creation Date: 2006-02-02
* Tabsize: 4
* Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
* This Revision: $Id: main.c 299 2007-03-29 17:07:19Z cs $
*/
#define F_CPU 12000000L /* evaluation board runs on 4MHz */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include "usbdrv.h"
#include "oddebug.h"
/* ----------------------- hardware I/O abstraction ------------------------ */
/* pin assignments:
PB0 Key 1
PB1 Key 2
PB2 Key 3
PB3 Key 4
PB4 Key 5
PB5 Key 6
PC0 Key 7
PC1 Key 8
PC2 Key 9
PC3 Key 10
PC4 Key 11
PC5 Key 12
PD0 USB-
PD1 debug tx
PD2 USB+ (int0)
PD3 Key 13
PD4 Key 14
PD5 Key 15
PD6 Key 16
PD7 Key 17
*/
static void hardwareInit(void)
{
uchar i, j;
PORTB = 0xff; /* activate all pull-ups */
DDRB = 0xff; /* all pins input */
PORTC = 0xff; /* activate all pull-ups */
DDRC = 0; /* all pins input */
PORTD = 0xfa; /* 1111 1010 bin: activate pull-ups except on USB lines */
DDRD = 0x07; /* 0000 0111 bin: all pins input except USB (-> USB reset) */
j = 0;
while(--j){ /* USB Reset by device only required on Watchdog Reset */
i = 0;
while(--i); /* delay >10ms for USB reset */
}
DDRD = 0x02; /* 0000 0010 bin: remove USB reset condition */
/* configure timer 0 for a rate of 12M/(1024 * 256) = 45.78 Hz (~22ms) */
TCCR0B = 5; /* timer 0 prescaler: 1024 */
}
/* ------------------------------------------------------------------------- */
#define NUM_KEYS 17
/* The following function returns an index for the first key pressed. It
* returns 0 if no key is pressed.
*/
static uchar keyPressed(void)
{
uchar i, mask, x;
x = PINB;
mask = 1;
for(i=0;i<6;i++){
if((x & mask) == 0)
return i + 1;
mask <<= 1;
}
x = PINC;
mask = 1;
for(i=0;i<6;i++){
if((x & mask) == 0)
return i + 7;
mask <<= 1;
}
x = PIND;
mask = 1 << 3;
for(i=0;i<5;i++){
if((x & mask) == 0)
return i + 13;
mask <<= 1;
}
return 0;
}
/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */
static uchar reportBuffer[2]; /* buffer for HID reports */
static uchar idleRate; /* in 4 ms units */
PROGMEM char usbHidReportDescriptor[35] = { /* USB report descriptor */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
};
/* We use a simplifed keyboard report descriptor which does not support the
* boot protocol. We don't allow setting status LEDs and we only allow one
* simultaneous key press (except modifiers). We can therefore use short
* 2 byte input reports.
* The report descriptor has been created with usb.org's "HID Descriptor Tool"
* which can be downloaded from http://www.usb.org/developers/hidpage/.
* Redundant entries (such as LOGICAL_MINIMUM and USAGE_PAGE) have been omitted
* for the second INPUT item.
*/
/* Keyboard usage values, see usb.org's HID-usage-tables document, chapter
* 10 Keyboard/Keypad Page for more codes.
*/
#define MOD_CONTROL_LEFT (1<<0)
#define MOD_SHIFT_LEFT (1<<1)
#define MOD_ALT_LEFT (1<<2)
#define MOD_GUI_LEFT (1<<3)
#define MOD_CONTROL_RIGHT (1<<4)
#define MOD_SHIFT_RIGHT (1<<5)
#define MOD_ALT_RIGHT (1<<6)
#define MOD_GUI_RIGHT (1<<7)
#define KEY_A 4
#define KEY_B 5
#define KEY_C 6
#define KEY_D 7
#define KEY_E 8
#define KEY_F 9
#define KEY_G 10
#define KEY_H 11
#define KEY_I 12
#define KEY_J 13
#define KEY_K 14
#define KEY_L 15
#define KEY_M 16
#define KEY_N 17
#define KEY_O 18
#define KEY_P 19
#define KEY_Q 20
#define KEY_R 21
#define KEY_S 22
#define KEY_T 23
#define KEY_U 24
#define KEY_V 25
#define KEY_W 26
#define KEY_X 27
#define KEY_Y 28
#define KEY_Z 29
#define KEY_1 30
#define KEY_2 31
#define KEY_3 32
#define KEY_4 33
#define KEY_5 34
#define KEY_6 35
#define KEY_7 36
#define KEY_8 37
#define KEY_9 38
#define KEY_0 39
#define KEY_F1 58
#define KEY_F2 59
#define KEY_F3 60
#define KEY_F4 61
#define KEY_F5 62
#define KEY_F6 63
#define KEY_F7 64
#define KEY_F8 65
#define KEY_F9 66
#define KEY_F10 67
#define KEY_F11 68
#define KEY_F12 69
static const uchar keyReport[NUM_KEYS + 1][2] PROGMEM = {
/* none */ {0, 0}, /* no key pressed */
/* 1 */ {MOD_SHIFT_LEFT, KEY_A},
/* 2 */ {MOD_SHIFT_LEFT, KEY_B},
/* 3 */ {MOD_SHIFT_LEFT, KEY_C},
/* 4 */ {MOD_SHIFT_LEFT, KEY_D},
/* 5 */ {MOD_SHIFT_LEFT, KEY_E},
/* 6 */ {MOD_SHIFT_LEFT, KEY_F},
/* 7 */ {MOD_SHIFT_LEFT, KEY_G},
/* 8 */ {MOD_SHIFT_LEFT, KEY_H},
/* 9 */ {MOD_SHIFT_LEFT, KEY_I},
/* 10 */ {MOD_SHIFT_LEFT, KEY_J},
/* 11 */ {MOD_SHIFT_LEFT, KEY_K},
/* 12 */ {MOD_SHIFT_LEFT, KEY_L},
/* 13 */ {MOD_SHIFT_LEFT, KEY_M},
/* 14 */ {MOD_SHIFT_LEFT, KEY_N},
/* 15 */ {MOD_SHIFT_LEFT, KEY_O},
/* 16 */ {MOD_SHIFT_LEFT, KEY_P},
/* 17 */ {MOD_SHIFT_LEFT, KEY_Q},
};
static void buildReport(uchar key)
{
/* This (not so elegant) cast saves us 10 bytes of program memory */
*(int *)reportBuffer = pgm_read_word(keyReport[key]);
}
uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
usbMsgPtr = reportBuffer;
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 */
buildReport(keyPressed());
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;
}
/* ------------------------------------------------------------------------- */
int main(void)
{
uchar key, lastKey = 0, keyDidChange = 0;
uchar idleCounter = 0;
wdt_enable(WDTO_2S);
hardwareInit();
odDebugInit();
usbInit();
sei();
DBG1(0x00, 0, 0);
for(;;){ /* main event loop */
wdt_reset();
usbPoll();
key = keyPressed();
if(lastKey != key){
lastKey = key;
keyDidChange = 1;
}
if(TIFR0 & (1<<TOV0)){ /* 22 ms timer */
TIFR0 = 1<<TOV0;
if(idleRate != 0){
if(idleCounter > 4){
idleCounter -= 5; /* 22 ms in units of 4 ms */
}else{
idleCounter = idleRate;
keyDidChange = 1;
}
}
}
if(keyDidChange && usbInterruptIsReady()){
keyDidChange = 0;
/* use last key and not current key status in order to avoid lost
changes in key status. */
buildReport(lastKey);
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
}
}
return 0;
}
/* ------------------------------------------------------------------------- */
Here are my fuses (high/low):
Code: Select all
0xDD 0xDF
As I previously wrote, I am using the latest driver (at least one of the latest): Nov2008.
My circuit is the original circuit from the HIDKeys project. I also tried the circuit used by the usbasp project (with 3v6 and 3v3 zehners). Both did'nt work for me.
cheers guys
Re: swithcing from atmeg8 to atmega168
- Start here, the 1/2 will not work. You will need 1 what diodes. Fuses are good, and code looks ok.My circuit is the original circuit from the HIDKeys project. I also tried the circuit used by the usbasp project (with 3v6 and 3v3 zehners). Both did'nt work for me.
Re: swithcing from atmeg8 to atmega168
Hey, thanks for the post. That were my impressions too...only the circuit could be wrong...anyways.
I put in 3v6 zeners bzx85-3v6. It does'nt work. The scope tells me on D+ I have a DC-part of exactly 2V...That seems very wrong to me. I jused 68R on D- and D+ and 2k2 Ohms linking D- and V_Bus.
I have to say that I did'nt use 1k5, but 2k2 Ohms, as I already wrote above.
I put in 3v6 zeners bzx85-3v6. It does'nt work. The scope tells me on D+ I have a DC-part of exactly 2V...That seems very wrong to me. I jused 68R on D- and D+ and 2k2 Ohms linking D- and V_Bus.
I have to say that I did'nt use 1k5, but 2k2 Ohms, as I already wrote above.