V-USB for TinyAvr0 TinyAvr1 Series

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I ported V-USB to TinyAvr0 TinyAvr1 Series. This is a full port. All XTL frequencies ported, all internal oscillator methods ported, all features ported. I tested outputs with logic analyzer to confirm timing is correct too. I also wrote example oscal methods since that is also different with this chip series. I will release this on GitHub this week and edit this post with the link to the GitHub source... compile scripts and example tools are linux based, I dont use windows, no big deal for most I'm sure.

I also wrote a UPDI programmer tool similar to AvrDude but solely for UPDI, and added that to the source upload as well.

TinyAvr0 TinyAvr1 series has some architectural differences which caused incompatibility with orginal V-USB source, most notably...
ISR do not clear flags and must be manually cleared.
VPORT must be used for bit manipulation.
Memory mapping is different, even with registers.
Opcodes use different number of cycles.

here is the link to the github commit.. https://github.com/12oclocker/V-...

Last Edited: Sun. Oct 18, 2020 - 08:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cool.  I've been wondering how difficult it would be to do this!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, you have been busy!

 

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 Interesting, I wrote a chip to chip bootloader/programmer to load my t1616 with an m328P through UPDI... testing soon. I'd like to see your PC side interface/programmer. I am assuming this will be in C with asm for the critical bits?  Quite an endeavor !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Niceyes

 

If your UPDI programmer works with R-PI GPIO ports, I sense it will make many people happy.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It does work with raspberry pi.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

before releasing the code their is a couple things bothering me in the original VUSB code that I noticed today when proof-reading everything, maybe bugs in VUSB and I want to fix them beforehand....

see the below code, this is the usbdrvasm15.inc file... something looks wrong at se0Delay, it is going to delay 9 cycles, not 6 as the code documents.

"ldi  x4, 3" I think should actually be "ldi x4, 2" (currently I think I will fix the loop delay before releasing)

makeSE0:
    cbr     x1, USBMASK     	;1 [06] 	prepare SE0 [spec says EOP may be 19 to 23 cycles]
    lds     x2, usbNewDeviceAddr;2 [07+08]
    lsl     x2                  ;1 [09] we compare with left shifted address
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
;set address only after data packet was sent, not after handshake
    out     USBOUT, x1      	;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle
    subi    YL, 20 + 2          ;1 [01] Only assign address on data packets, not ACK/NAK in x3
    sbci    YH, 0           	;1 [02]
    breq    skipAddrAssign  	;1 [03]
    sts     usbDeviceAddr, x2	;2 [04+05] if not skipped: SE0 is one cycle longer
;----------------------------------------------------------------------------
;end of usbDeviceAddress transfer
skipAddrAssign:				;- [03/04]
    ldi     x2, 1<<USB_INTR_PENDING_BIT	;1 [05] int0 occurred during TX -- clear pending flag
    USB_STORE_PENDING(x2)           ;1 [06]
    ori     x1, USBIDLE     		;1 [07]
    in      x2, USBDDR      		;1 [08]
    cbr     x2, USBMASK     		;1 [09] set both pins to input
    mov     x3, x1          		;1 [10]
    cbr     x3, USBMASK     		;1 [11] configure no pullup on both pins
    ldi     x4, 3           		;1 [12]
se0Delay:				;- [12] [15]
    dec     x4              		;1 [13] [16]
    brne    se0Delay        		;1 [14] [17]
    nop2				;2      [18+19]
    out     USBOUT, x1      		;1      [20] <--out J (idle) -- end of SE0 (EOP sig.)
    out     USBDDR, x2      		;1      [21] <--release bus now
    out     USBOUT, x3      		;1      [22] <--ensure no pull-up resistors are active
    rjmp    doReturn			;1	[23]

Another thing bothering me, below is the code from usbdrvasm20.inc... The "st" operation "st y+, shift" uses 2 cycles, NOT 1 cycle, but the code below is written assuming st uses 2 cycles. The driver still works, but I assume the timing is not exactly as intended because of that, or maybe it was just a documentation error. I am investigating. (currently I think this will have no ill effect, and will probably release as is)

 

;----------------------------------------------------------------------------
; Process bit7. However, bit 6 still may need unstuffing.
;----------------------------------------------------------------------------

b6checkUnstuff:
    dec     bitcnt              ;[9]
    breq    unstuff6            ;[10]
bit7:
    subi    cnt, 1              ;[11] cannot use dec becaus it does not affect the carry flag
    brcs    overflow            ;[12] Too many bytes received. Ignore packet
    in      x1, USBIN           ;[0] sample line state
    andi    x1, USBMASK         ;[1] filter only D+ and D- bits
    cpse    x1, x2              ;[2] when previous line state equals current line state, handle "1"
    rjmp    b7handle0           ;[3] when line state differs, handle "0"
    sec                         ;[4]
    ror     shift               ;[5] shift "1" into the data
    st      y+, shift           ;[6] store the data into the buffer
    ldi     shift, 0x40         ;[7] reset data for receiving the next byte
    subi    leap, 0x55          ;[9] trick to introduce a leap cycle every 3 bytes
    brcc    nextInst            ;[10 or 11] it will fail after 85 bytes. However low speed can only receive 11
    dec     bitcnt              ;[11 or 12]
    brne    bit0                ;[12 or 13]
    ldi     x1, 1               ;[13 or 14] unstuffing bit 7
    in      bitcnt, USBIN       ;[0] sample stuff bit
    rjmp    unstuff             ;[1]

 

Last Edited: Tue. Oct 13, 2020 - 09:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

12oclocker wrote:
I ported V-USB to TinyAvr0 TinyAvr1 Series. This is a full port. All XTL frequencies ported, all internal oscillator methods ported, all features ported. I tested outputs with logic analyzer to confirm timing is correct too. I also wrote example oscal methods since that is also different with this chip series. I will release this on GitHub this week and edit this post with the link to the GitHub source... compile scripts and example tools are linux based, I dont use windows, no big deal for most I'm sure. I also wrote a bitbang UPDI programmer tool similar to AvrDude but solely for UPDI, will probably get that uploaded as well. TinyAvr0 TinyAvr1 series has some architectural differences which caused incompatibility with orginal V-USB source, most notably... ISR do not clear flags and must be manually cleared. VPORT must be used for bit manipulation. Memory mapping is different, even with registers. Opcodes use different number of cycles.

 

That's an impressive accomplishment.  Since the bit-bang code for different clock rates was written by different people, there are different styles used.  The most annoying is that some of the comments about timing refer to the clock cycle at the end of the current instruction, while others use the more sensible beginning of instruction timing.

 

I recently wrote a new osccal tuner for MicroNucleus that you may be able to use as well.

https://github.com/nerdralph/mic...

 

The version that Tim had written only worked if the frames used for timing didn't contain any data packets.  My version ignores data packets, and is smaller too.

 

I also improved the sync code.  vUSB's receive timing was accurate to a 2-cycle window.  I modified waitForK: ... rjmp waitForK look so it is 15 cycles instead of 16.  So on the 1st JK transition it synchronizes within 2 cycles like the original vUSB code, and on the 2nd JK transition it narrows that down to a 1-cycle window.

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Very interesting.., and I also noticed the cycle count documentation being different was kind of odd... I did write an oscal tuner for the TinyAvr0/1 series that will be included with the source, as well as an HID working example. It works for both 12.8 and 16.5 Mhz. The TinyAvr0/1 internal oscillators are different, but a welcome change as they are more accurate and more stable. very reliable for V-USB so far during my testing. And have no issue reaching 12.8 or 16.5 MHz. The oscal tuner can solve oscal for 16.5Mhz in about 3 loop iterations.

Last Edited: Tue. Oct 13, 2020 - 10:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

12oclocker wrote:
The "st" operation "st y+, shift" uses 2 cycles, NOT 1 cycle

 

Be mindful that ST takes 1 or 2 cycles depending on the exact AVR architecture flavour.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Standard avr 2 cycles (attiny, atmega as vusb was originally written for). TinyAvr0/1 is 1 cycle... from the file I described above, only the 20 megahertz oscillator file has the discrepancy. I am mindful of cycles per architecture that's how I found the discrepancy during the code port to TinyAvr0/1. The discrepancy or bug seems inconsequential to the functionality but is bothersome to me.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:

Cool.  I've been wondering how difficult it would be to do this!

 

 

Very easy.....you didn't have to write a single line of code. ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you find any material bugs while doing the porting work?  I think I found one with the sync code.  Since vUSB can start reading mid-packet, if it reads the sequence 000011, it would be mistaken as a sync.  It's a low probability event, but I don't see any checks in the code for this situation.

I've started writing smaller, more limited bit-bang usb "kernel" that runs at 10.5Mhz (7 cycles/bit).  The USB stack code controls the main loop, and the user code will only be run through callbacks.

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BTW, did you try this on Mega0 chips?  My impression is that they should work the same.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

ralphd wrote:

Did you find any material bugs while doing the porting work?  I think I found one with the sync code.  Since vUSB can start reading mid-packet, if it reads the sequence 000011, it would be mistaken as a sync.  It's a low probability event, but I don't see any checks in the code for this situation.

I've started writing smaller, more limited bit-bang usb "kernel" that runs at 10.5Mhz (7 cycles/bit).  The USB stack code controls the main loop, and the user code will only be run through callbacks.

Interesting... I suspect the PID and EOP would be off if that happened, and the packet would be ignored and a retry of sync would begin again. I would have to examine further to see what would happen.

 

westfw wrote:

BTW, did you try this on Mega0 chips?  My impression is that they should work the same.

I have not yet, if you can post a link to your favorite Mega0 chip, I will check the opcodes, also I just uploaded the source to github