Support for avrxmega3 architecture
vslinuxdotnet opened this issue · 13 comments
Hello,
Exists some plans to v-usb works with avrxmega3 architecture, ex: attiny1614
Thank you
I'm looking into this. I'm not an AVR expert at all, so might need some help -- it would even be encouraging to hear that this is practically possible.
- usbconfig.h has USB_CFG_IOPORTNAME set to
B
, DMINUS_BIT set to 1 and DPLUS_BIT set to 0, so that DB0 is USB D+ and DB1 is USB D-. - After this, C code most likely already works or is easy to port, so I'm not too worried about usbdrv.c and oddebug.c.
- The challenge will mostly be in the assembly files: usbdrvasm.S, asmcommon.inc and asmdrvasm{clockrate}.inc.
So far, I've succeeded in getting my attiny1614 in 16 MHz, the lowest speed it supports without an external crystal. So, I'll mostly try to patch asmdrvasm16.inc as necessary until I can get this to work. I have a scope that'll hopefully help to figure out whether I'm doing the timing & protocol correctly after that.
I think the following patterns need to be fixed since the 1-series chips use different assembly for these:
- The name of the interrupt vector
- Clearing interrupt flags
- Setting pin direction
- Setting pin level
- Reading pin level (?)
The inc file is only about 300 lines of code, so it'll probably be fine to make manual changes; testing the changes and figuring out what's still wrong will likely be the larger challenge.
Actually, I have the code at least compiling by:
- in usbconfig.h, setting:
#define USB_CFG_IOPORTNAME B
#define USB_CFG_DMINUS_BIT 1
#define USB_CFG_DPLUS_BIT 0
[...]
#define USB_INTR_CFG PORTB.PIN0CTRL
#define USB_INTR_CFG_SET PORT_ISC_FALLING_gc
#define USB_INTR_CFG_CLR (~PORT_ISC_FALLING_gc)
/* #define USB_INTR_ENABLE GIMSK */
/* #define USB_INTR_ENABLE_BIT INT0 */
#define USB_INTR_PENDING VPORTB_INTFLAGS
#define USB_INTR_PENDING_BIT VPORT_INT0_bm
#define USB_INTR_VECTOR __vector_4
- applying this patch to v-usb:
diff --git a/usbdrv/usbdrv.c b/usbdrv/usbdrv.c
index 1d80ac6..1b0f866 100644
--- a/usbdrv/usbdrv.c
+++ b/usbdrv/usbdrv.c
@@ -621,7 +621,8 @@ USB_PUBLIC void usbInit(void)
#if USB_INTR_CFG_CLR != 0
USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
#endif
- USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
+ // TODO: enable interrupts by setting Global Interrupt Enable bit in CPU.SREG?
+ //USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
usbResetDataToggling();
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
usbTxLen1 = USBPID_NAK;
diff --git a/usbdrv/usbdrv.h b/usbdrv/usbdrv.h
index f094120..1bfb0cf 100644
--- a/usbdrv/usbdrv.h
+++ b/usbdrv/usbdrv.h
@@ -531,11 +531,12 @@ int usbDescriptorStringSerialNumber[];
/* ------------------------------------------------------------------------- */
#define USB_CONCAT(a, b) a ## b
+#define USB_CONCAT3(a, b, c) a ## b ## c
#define USB_CONCAT_EXPANDED(a, b) USB_CONCAT(a, b)
-#define USB_OUTPORT(name) USB_CONCAT(PORT, name)
-#define USB_INPORT(name) USB_CONCAT(PIN, name)
-#define USB_DDRPORT(name) USB_CONCAT(DDR, name)
+#define USB_OUTPORT(name) USB_CONCAT3(VPORT, name, _OUT)
+#define USB_INPORT(name) USB_CONCAT3(VPORT, name, _IN)
+#define USB_DDRPORT(name) USB_CONCAT3(VPORT, name, _DIR)
/* The double-define trick above lets us concatenate strings which are
* defined by macros.
*/
By using VPORTs, no other code changes need to happen I think.
I can flash the device now, and it seems that usbInit() and usbPoll() return normally, but when I connect the device, my Mac doesn't see any new USB devices attaching. I'll try some more host devices to see if that makes any difference, but if that doesn't help, I'll try to attach a scope and see if I can see some communication on the line.
I finally have it working \o/
The main impediments to the software are that some instructions take a different amount of cycles. For example, PUSH takes 1 instead of 2, ST takes 1 cycle instead of 2, but LDS takes 3 cycles instead of 2. Because of this, the timing reading bits was off from the spec.
Another impediment is that the 1-series no longer maps the general purpose registers into memory. The assembly assumes that if you set Y to 20, *Y is the contents of r20, but that's not the case. This was a tiny optimization in the code, and I worked around this by allocating an extra byte in SRAM, writing r20 to it, then setting Y to that address.
Now, my device is recognized by my laptop. I'll clean up the patch and create a pull request to this repository.
@vslinuxdotnet See #26 for the patch :-) Could you perhaps test it as well, and report back your results in the PR?
Hello, as soon as I have time, I will test it and report to you. Thank you.
@vslinuxdotnet See #26 for the patch :-) Could you perhaps test it as well, and report back your results in the PR?
Testing today, what fuses did you use, and what pins for D+ and D- did you test?
@vslinuxdotnet See #26 for the patch :-) Could you perhaps test it as well, and report back your results in the PR?
Testing today, what fuses did you use, and what pins for D+ and D- did you test?
Forget it, in #26 link :)
I can't compile it @sgielen I get:
main.c: In function 'usbFunctionSetup':
main.c:67:9: error: 'OSCCAL' undeclared (first use in this function); did you mean 'CCL'?
OSCCAL = rq->wValue.bytes[0];
^~~~~~
CCL
main.c:67:9: note: each undeclared identifier is reported only once for each function it appears in
main.c: In function 'main':
main.c:92:5: error: 'TCCR2' undeclared (first use in this function)
TCCR2 = 9 | (1 << COM20);
^~~~~
main.c:92:23: error: 'COM20' undeclared (first use in this function)
TCCR2 = 9 | (1 << COM20);
^~~~~
main.c:93:5: error: 'OCR2' undeclared (first use in this function); did you mean 'TCCR2'?
OCR2 = 3; /* should give F_CPU/8 clock */
^~~~
TCCR2
main.c:95:5: error: 'DDRB' undeclared (first use in this function); did you mean 'DD0'?
DDRB = (1 << 2) | (1 << 3);
^~~~
DD0
main.c:96:5: error: 'TCCR0' undeclared (first use in this function); did you mean 'TCCR2'?
TCCR0 = 3; /* 1/64 prescaler */
^~~~~
TCCR2
<built-in>: warning: function declared 'noreturn' has a 'return' statement
Makefile:134: recipe for target 'main.o' failed
make: *** [main.o] Error 1
@vslinuxdotnet Those errors are in a main.c
I didn't write... what are you trying to compile exactly?
@vslinuxdotnet Those errors are in a
main.c
I didn't write... what are you trying to compile exactly?
Compiling v-usb after apply your patch:
in usbconfig.h, setting:
#define USB_CFG_IOPORTNAME B
#define USB_CFG_DMINUS_BIT 1
#define USB_CFG_DPLUS_BIT 0
[...]
#define USB_INTR_CFG PORTB.PIN0CTRL
#define USB_INTR_CFG_SET PORT_ISC_FALLING_gc
#define USB_INTR_CFG_CLR (~PORT_ISC_FALLING_gc)
/* #define USB_INTR_ENABLE GIMSK /
/ #define USB_INTR_ENABLE_BIT INT0 */
#define USB_INTR_PENDING VPORTB_INTFLAGS
#define USB_INTR_PENDING_BIT VPORT_INT0_bm
#define USB_INTR_VECTOR __vector_4
applying this patch to v-usb:
diff --git a/usbdrv/usbdrv.c b/usbdrv/usbdrv.c
index 1d80ac6..1b0f866 100644
--- a/usbdrv/usbdrv.c
+++ b/usbdrv/usbdrv.c
@@ -621,7 +621,8 @@ USB_PUBLIC void usbInit(void)
#if USB_INTR_CFG_CLR != 0
USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
#endif
- USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
- // TODO: enable interrupts by setting Global Interrupt Enable bit in CPU.SREG?
- //USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
usbResetDataToggling();
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
usbTxLen1 = USBPID_NAK;
diff --git a/usbdrv/usbdrv.h b/usbdrv/usbdrv.h
index f094120..1bfb0cf 100644
--- a/usbdrv/usbdrv.h
+++ b/usbdrv/usbdrv.h
@@ -531,11 +531,12 @@ int usbDescriptorStringSerialNumber[];
/* ------------------------------------------------------------------------- */
#define USB_CONCAT(a, b) a ## b
+#define USB_CONCAT3(a, b, c) a ## b ## c
#define USB_CONCAT_EXPANDED(a, b) USB_CONCAT(a, b)
-#define USB_OUTPORT(name) USB_CONCAT(PORT, name)
-#define USB_INPORT(name) USB_CONCAT(PIN, name)
-#define USB_DDRPORT(name) USB_CONCAT(DDR, name)
+#define USB_OUTPORT(name) USB_CONCAT3(VPORT, name, _OUT)
+#define USB_INPORT(name) USB_CONCAT3(VPORT, name, _IN)
+#define USB_DDRPORT(name) USB_CONCAT3(VPORT, name, _DIR)
/* The double-define trick above lets us concatenate strings which are
- defined by macros.
*/
@vslinuxdotnet Oh, I didn't fix all of v-usb against attiny1614, just the usbdrv
. So indeed, main.c
in v-usb probably doesn't work, you'd have to compile usbdrv together with an existing attiny1614 application that you want to add USB support to.
@vslinuxdotnet Oh, I didn't fix all of v-usb against attiny1614, just the
usbdrv
. So indeed,main.c
in v-usb probably doesn't work, you'd have to compile usbdrv together with an existing attiny1614 application that you want to add USB support to.
That it, usbdrv compile, the main for vusb not.
Let's see if I can fix the errors.
Found the repo: https://github.com/12oclocker/V-USB_TinyAvr
lets try!