ATmega164P に対応する

ATmega164P は ATmega16 より単価が100円安い上に消費電力が少ないので動いてくれないと困る。前回ヒューズを書こうとしたら AVR ライタが死ぬという忌まわしい出来事が起きてから流してたんだが、最後の壁となったので ROM ライタで書き込んで対応する。

動かない理由だが、下記のソースに対するオブジェクトの出力が変だった。

USB_PUBLIC void usbInit(void)
{
#if USB_INTR_CFG_SET != 0
    USB_INTR_CFG |= USB_INTR_CFG_SET;
    133c:	e9 e6       	ldi	r30, 0x69	; 105
    133e:	f0 e0       	ldi	r31, 0x00	; 0
    1340:	80 81       	ld	r24, Z
    1342:	8b 60       	ori	r24, 0x0B	; 11
    1344:	80 83       	st	Z, r24
#endif
#if USB_INTR_CFG_CLR != 0
    USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
#endif
    USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
    1346:	e8 9a       	sbi	0x1d, 0	; 29
    usbTxLen1 = USBPID_NAK;
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
    usbTxLen3 = USBPID_NAK;
#endif
#endif
}
    1348:	08 95       	ret
}

Z レジスタがいみわからんことになってるので、ソースは悪くないけどこうやってなおした。

USB_PUBLIC void usbInit(void)
{
#if USB_INTR_CFG_SET != 0
    //USB_INTR_CFG |= USB_INTR_CFG_SET;
    USB_INTR_CFG = USB_INTR_CFG_SET;
    133c:	8b e0       	ldi	r24, 0x0B	; 11
    133e:	80 93 69 00 	sts	0x0069, r24
#endif
#if USB_INTR_CFG_CLR != 0
    USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
#endif
    USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
    1342:	e8 9a       	sbi	0x1d, 0	; 29
    usbTxLen1 = USBPID_NAK;
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
    usbTxLen3 = USBPID_NAK;
#endif
#endif
}
    1344:	08 95       	ret

そしたら動いてくれた。ただ、こんなん運良く見つかったからよかったもののずーとつまるところだったぞ。直接は関係ないけど、mega16 と mega164p の object ディレクトリを分けたとかファイル整理もやった。

補足。 ROM ライタのプログラムは mega164p には対応してないが、対応している mega16 として無理矢理書いた。ただし、 extented fuse bit は設定できないので注意。