LGT 最小系统板测评
本帖最后由 xwkm 于 2013-7-12 22:47 编辑在两天前我向LGT工作人员申请了样品和工具。现在依然在试用和编程中。
今天搞完了内置32MHz的R/C振荡器V-USB。顺带靠测量D-脉冲写了个R/C振荡器自动校准程序。
不过依然有bug。而且不是完美解决。
上板图
关于这个板子的各种开发我会陆续公布在这个帖子上。
明天争取解决振荡器校准的问题/ 不知道楼主有时间能不能测一下vusb跑在32m的速度{:lol:}
附件里是个测试工程上位机有c的和delphi的 本帖最后由 xwkm 于 2013-7-13 00:04 编辑
goodcode 发表于 2013-7-12 23:40 static/image/common/back.gif
不知道楼主有时间能不能测一下vusb跑在32m的速度
附件里是个测试工程上位机有c的和delphi的 ...
暂时还没有自己移植个32M的打算。内部RC不算特别稳定。
现在在内振上跑的2分频。
LGT8F88A进中断的时序貌似发生了一些改变。所以12M的驱动估计得大改了。
当然我要试试移植个24M的V-USB。
不过目前最棘手的问题就是88A的OSCCAL自动校准问题。我得找个最好的解决方案来解决。
不过其实不解决也不是不可以。因为现在的8F88A都已经校准过。没啥大问题。
我写这个校准算法主要是想提高稳定性。并且想在8F08A上无外振V-USB…… 本帖最后由 xwkm 于 2013-7-13 00:08 编辑
不过说实话等到最后的校准算法出来后估计USBasp会更省料了。晶振都可以省掉了。
另外就是以前的in + sbrs指令可以直接换成nop + sbis了。LGT8F88A没有了IO同步的问题。
关于Bootloader的制作我是想好好省下料。最好做到不用接任何器件。只要VCC D+ D- GND接了就可以连接电脑下载。
这样开发板成本可以大幅降低。毕竟现在LGT时钟准了不少。不好好利用下也不是咱作风啊。
PS:实验板是公版V-USB的设计.所以如果以后要给实验板开发V-USB程序可以不用改IO部分. 奇怪了,我十几年没撸了,怎么看东西还有重影啊?肯定是肾亏了。 楼上对不起。相机没有防抖功能. LGT跟AVR那样皮实不? 90999 发表于 2013-7-13 00:05 static/image/common/back.gif
奇怪了,我十几年没撸了,怎么看东西还有重影啊?肯定是肾亏了。
你太幽默了{:lol:} danju 发表于 2013-7-13 00:11 static/image/common/back.gif
LGT跟AVR那样皮实不?
目前我还没坏过一片…… 顶楼主为大伙造福。 楼主辛苦了!! danju 发表于 2013-7-13 00:11 static/image/common/back.gif
LGT跟AVR那样皮实不?
楼上可以整几片LGT8F88A测试下, 看是不是和AVR一样皮实!:) /* Name: usbdrvasm12.inc
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2004-12-29
* Tabsize: 4
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id$
*/
/* Do not link this file! Link usbdrvasm.S instead, which includes the
* appropriate implementation!
*/
/*
General Description:
This file is the 12 MHz version of the asssembler part of the USB driver. It
requires a 12 MHz crystal (not a ceramic resonator and not a calibrated RC
oscillator).
See usbdrv.h for a description of the entire driver.
Since almost all of this code is timing critical, don't change unless you
really know what you are doing! Many parts require not only a maximum number
of CPU cycles, but even an exact number of cycles!
Timing constraints according to spec (in bit times):
timing subject min max CPUcycles
---------------------------------------------------------------------------
EOP of OUT/SETUP to sync pattern of DATA0 (both rx) 2 16 16-128
EOP of IN to sync pattern of DATA0 (rx, then tx) 2 7.5 16-60
DATAx (rx) to ACK/NAK/STALL (tx) 2 7.5 16-60
*/
#if USB_CFG_CLOCK_KHZ == 12000
#define nop8
#elif USB_CFG_CLOCK_KHZ == 24000
#define nop8 rcall delay8
#else
#error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!"
#endif
;Software-receiver engine. Strict timing! Don't change unless you can preserve timing!
;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled
;max allowable interrupt latency: 34 cycles -> max 25 cycles interrupt disable
;max stack usage: = 11 bytes
;Numbers in brackets are maximum cycles since SOF.
USB_INTR_VECTOR:
;order of registers pushed: YL, SREG , YH, shift, x1, x2, x3, cnt
push YL ;2 push only what is necessary to sync with edge ASAP
in YL, SREG ;1
push YL ;2
push x5 ; //新增加寄存器变量
;----------------------------------------------------------------------------
; Synchronize with sync pattern:
;----------------------------------------------------------------------------
;sync byte (D-) pattern LSb to MSb: 01010100
;sync up with J to K edge during sync pattern -- use fastest possible loops
;The first part waits at most 1 bit long since we must be in sync pattern.
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
;waitForJ, ensure that this prerequisite is met.
;原始LGT 移植代码 此处可能会引起错误当开启USB_COUNT_SOF, USB_SOF_HOOK或者电平错误时将导致死循环或不执行代码
;通过增加新寄存器变量修正
waitForJ:
inc YL
in x5, USBIN
sbrs x5, USBMINUS
brne waitForJ ; just make sure we have ANY timeout
waitForK:
;The following code results in a sampling window of 1/4 bit which meets the spec.
in x5, USBIN
sbrs x5, USBMINUS
rjmp foundK
in x5, USBIN
sbrs x5, USBMINUS
rjmp foundK
in x5, USBIN
sbrs x5, USBMINUS
rjmp foundK
in x5, USBIN
sbrs x5, USBMINUS
rjmp foundK
in x5, USBIN
sbrs x5, USBMINUS
rjmp foundK
#if USB_CFG_CLOCK_KHZ == 24000
in x5, USBIN
sbrs x5, USBMINUS
rjmp foundK
in x5, USBIN
sbrs x5, USBMINUS
rjmp foundK
in x5, USBIN
sbrs x5, USBMINUS
rjmp foundK
#endif
#if USB_COUNT_SOF
lds YL, usbSofCount
inc YL
sts usbSofCount, YL
#endif/* USB_COUNT_SOF */
#ifdef USB_SOF_HOOK
USB_SOF_HOOK
#endif
rjmp sofError
foundK:
;{3, 5} after falling D- edge, average delay: 4 cycles
;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
;are cycles from center of first sync (double K) bit after the instruction
push YH ;1
nop
lds YL, usbInputBufOffset ;2
clr YH ;1
subi YL, lo8(-(usbRxBuf)) ;1
sbci YH, hi8(-(usbRxBuf)) ;1
in x5, USBIN ;1
sbrs x5, USBMINUS ;1
;sbis USBIN, USBMINUS ;1 we want two bits K
rjmp haveTwoBitsK ;1
pop YH ;1 undo the push from before
rjmp waitForK ;1 this was not the end of sync, retry
haveTwoBitsK:
;----------------------------------------------------------------------------
; push more registers and initialize values while we sample the first bits:
;----------------------------------------------------------------------------
push shift ;1 ;2
push x1 ;1 ;2
push x2 ;1 ;2
;原始LGT 移植代码 此处引起关键错误 可能因为上面读寄存器引起的时序偏差导致读bit 0后移
;未使用逻辑分析仪跟踪分析 上面只是推测减少两个时钟的延迟就无错误数据出现 说明读取bit 0
;向后移了很多
;nop2 ;2
;nop ;1
;新代码
nop
in x1, USBIN ;1 <-- sample bit 0
ldi shift, 0xff ;1
bst x1, USBMINUS ;1
bld shift, 0 ;1
push x3 ;1 ;2
push cnt ;1 ;2
nop2 ;2
in x2, USBIN ;1 <-- sample bit 1
ser x3 ;1
eor x1, x2 ;1
bst x1, USBMINUS ;1
bld shift, 1 ;1
ldi cnt, USB_BUFSIZE;1
nop ;1
rjmp rxbit2 ;1 ;2
;----------------------------------------------------------------------------
; Receiver loop (numbers in brackets are cycles within byte after instr)
;----------------------------------------------------------------------------
unstuff0: ;1 (branch taken)
andi x3, ~0x01 ;1
mov x1, x2 ;1 x2 contains last sampled (stuffed) bit
in x2, USBIN ;1 <-- sample bit 1 again
ori shift, 0x01 ;1
nop ;1
rjmp didUnstuff0 ;1 ;2
unstuff1: ;1 (branch taken)
mov x2, x1 ;1 x1 contains last sampled (stuffed) bit
andi x3, ~0x02 ;1
ori shift, 0x02 ;1
nop ;1
in x1, USBIN ;1 <-- sample bit 2 again
nop ;1
rjmp didUnstuff1 ;1 ;2
unstuff2: ;1 (branch taken)
andi x3, ~0x04 ;1
ori shift, 0x04 ;1
mov x1, x2 ;1 x2 contains last sampled (stuffed) bit
nop ;1
in x2, USBIN ;1 <-- sample bit 3
nop ;1
rjmp didUnstuff2 ;1 ;2
unstuff3: ;1 (branch taken)
in x2, USBIN ;1 <-- sample stuffed bit 3
andi x3, ~0x08 ;1
ori shift, 0x08 ;1
nop ;1
rjmp didUnstuff3 ;1 ;2
unstuff4: ;1 (branch taken)
andi x3, ~0x10 ;1
in x1, USBIN ;1 <-- sample stuffed bit 4
ori shift, 0x10 ;1
nop ;1
rjmp didUnstuff4 ;1 ;2
unstuff5: ;1 (branch taken)
andi x3, ~0x20 ;1
in x2, USBIN ;1 <-- sample stuffed bit 5
ori shift, 0x20 ;1
nop ;1
rjmp didUnstuff5 ;1 ;2
unstuff6: ;1 (branch taken)
andi x3, ~0x40 ;1
in x1, USBIN ;1 <-- sample stuffed bit 6
ori shift, 0x40 ;1
nop ;1
rjmp didUnstuff6 ;1 ;2
; extra jobs done during bit interval:
; bit 0: store, clear
; bit 1: se0 check
; bit 2: overflow check
; bit 3: recovery from delay
; bit 4: none
; bit 5: none
; bit 6: none
; bit 7: jump, eor
rxLoop:
eor x3, shift ;1 reconstruct: x3 is 0 at bit locations we changed, 1 at others
in x1, USBIN ;1 <-- sample bit 0
nop ;1
st y+, x3 ;1 ;2 store data
ser x3 ;1
nop ;1
eor x2, x1 ;1
bst x2, USBMINUS;1
bld shift, 0 ;1
in x2, USBIN ;1 <-- sample bit 1 (or possibly bit 0 stuffed)
andi x2, USBMASK ;1
breq se0 ;1 SE0 check for bit 1
andi shift, 0xf9 ;1
didUnstuff0:
breq unstuff0 ;1
eor x1, x2 ;1
bst x1, USBMINUS;1
bld shift, 1 ;1
rxbit2:
in x1, USBIN ;1 <-- sample bit 2 (or possibly bit 1 stuffed)
andi shift, 0xf3 ;1
breq unstuff1 ;1 do remaining work for bit 1
didUnstuff1:
subi cnt, 1 ;1
brcs overflow ;1 loop control
eor x2, x1 ;1
bst x2, USBMINUS;1
bld shift, 2 ;1
in x2, USBIN ;1 <-- sample bit 3 (or possibly bit 2 stuffed)
andi shift, 0xe7 ;1
breq unstuff2 ;1
didUnstuff2:
eor x1, x2 ;1
bst x1, USBMINUS;1
bld shift, 3 ;1
didUnstuff3:
andi shift, 0xcf ;1
breq unstuff3 ;1
in x1, USBIN ;1 <-- sample bit 4
eor x2, x1 ;1
bst x2, USBMINUS;1
bld shift, 4 ;1
didUnstuff4:
andi shift, 0x9f ;1
breq unstuff4 ;1
nop2 ;2
in x2, USBIN ;1 <-- sample bit 5
eor x1, x2 ;1
bst x1, USBMINUS;1
bld shift, 5 ;1
didUnstuff5:
andi shift, 0x3f ;1
breq unstuff5 ;1
nop2 ;2
in x1, USBIN ;1 <-- sample bit 6
eor x2, x1 ;1
bst x2, USBMINUS;1
bld shift, 6 ;1
didUnstuff6:
cpi shift, 0x02 ;1
brlo unstuff6 ;1
nop2 ;2
in x2, USBIN ;1 <-- sample bit 7
eor x1, x2 ;1
bst x1, USBMINUS;1
bld shift, 7 ;1
didUnstuff7:
cpi shift, 0x04 ;1
brsh rxLoop ;2 loop control
unstuff7:
andi x3, ~0x80 ;1
ori shift, 0x80 ;1
in x2, USBIN ;1 <-- sample stuffed bit 7
nop2 ;2 ;1
rjmp didUnstuff7 ;1 ;2
macro POP_STANDARD ; 12 cycles
pop cnt
pop x3
pop x2
pop x1
pop shift
pop YH
endm
macro POP_RETI ; 5 cycles
pop x5
pop YL
out SREG, YL
pop YL
endm
#include "asmcommon.inc"
;----------------------------------------------------------------------------
; Transmitting data
;----------------------------------------------------------------------------
txByteLoop:
txBitloop:
stuffN1Delay: ;
ror shift ;[-5]
brcc doExorN1 ;[-4]
subi x4, 1 ;[-3]
brne commonN1 ;[-2]
lsl shift ;[-1] compensate ror after rjmp stuffDelay
nop ; stuffing consists of just waiting 8 cycles
nop
rjmp stuffN1Delay ; after ror, C bit is reliably clear
sendNakAndReti: ;0 [-19] 19 cycles until SOP
ldi x3, USBPID_NAK ;1 [-18]
nop ;1 [-17]
rjmp usbSendX3 ;1;[-16];2 [-16]
sendAckAndReti: ;0 [-19] 19 cycles until SOP
ldi x3, USBPID_ACK ;1 [-18]
nop ;1 [-17]
rjmp usbSendX3 ;1 [-16];2 [-16]
sendCntAndReti: ;0 [-17] 17 cycles until SOP
nop
mov x3, cnt ;1 [-16]
usbSendX3: ;0 [-16]
ldi YL, 20 ;1 [-15] 'x3' is R20
ldi YH, 0 ;1 [-14]
ldi cnt, 2 ;1 [-13]
; rjmp usbSendAndReti fallthrough
; USB spec says:
; idle = J
; J = (D+ = 0), (D- = 1) or USBOUT = 0x01
; K = (D+ = 1), (D- = 0) or USBOUT = 0x02
; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles)
;usbSend:
;pointer to data in 'Y'
;number of bytes in 'cnt' -- including sync byte
;uses: x1...x2, x4, shift, cnt, Y
;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction)
usbSendAndReti:
in x2, USBDDR ;[-12] 12 cycles until SOP
ori x2, USBMASK ;[-11]
sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
nop ;[-9]
out USBDDR, x2 ;[-8] <--- acquire bus
in x1, USBOUT ;[-7] port mirror for tx loop
ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror)
ldi x2, USBMASK ;[-5]
push x4 ;[-4]
nop ;[-3]
doExorN1:
eor x1, x2 ;[-2]
ldi x4, 6 ;[-1]
commonN1:
stuffN2Delay:
out USBOUT, x1 ; <--- set bit
ror shift ;
brcc doExorN2 ;
subi x4, 1 ;
brne commonN2 ;
lsl shift ; compensate ror after rjmp stuffDelay
nop ;
rjmp stuffN2Delay ;; after ror, C bit is reliably clear
doExorN2:
eor x1, x2 ;
ldi x4, 6 ;
commonN2:
nop ;
subi cnt, 171 ; trick: (3 * 171) & 0xff = 1
out USBOUT, x1 ; <--- set bit
brcs txBitloop ;
stuff6Delay:
ror shift ;
brcc doExor6 ;
subi x4, 1 ;
brne common6 ;
lsl shift ; compensate ror after rjmp stuffDelay
nop2 ; stuffing consists of just waiting 8 cycles
rjmp stuff6Delay ; after ror, C bit is reliably clear
doExor6:
eor x1, x2 ;
ldi x4, 6 ;
common6:
stuff7Delay:
ror shift ;
out USBOUT, x1 ; <--- set bit
brcc doExor7 ;
subi x4, 1 ;
brne common7 ;
lsl shift ; compensate ror after rjmp stuffDelay
nop
rjmp stuff7Delay ; after ror, C bit is reliably clear
doExor7:
eor x1, x2 ;
ldi x4, 6 ;
common7:
ld shift, y+ ;
nop ;
tst cnt ;;
out USBOUT, x1 ;; <--- set bit
;brne txByteLoop ;
breq makeSE0 ;
rjmp txByteLoop ;
makeSE0:
;make SE0:
cbr x1, USBMASK ; prepare SE0
lds x2, usbNewDeviceAddr;
lsl x2 ; we compare with left shifted address
subi YL, 2 + 20 ; Only assign address on data packets, not ACK/NAK in x3
out USBOUT, x1 ; <-- out SE0 -- from now 2 bits = 16 cycles until bus idle
sbci YH, 0 ;
;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
breq skipAddrAssign ;
sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer
skipAddrAssign:
;end of usbDeviceAddress transfer
ldi x2, 1<<USB_INTR_PENDING_BIT; int0 occurred during TX -- clear pending flag
USB_STORE_PENDING(x2) ;
ori x1, USBIDLE ;
in x2, USBDDR ;
cbr x2, USBMASK ; set both pins to input
mov x3, x1 ;
cbr x3, USBMASK ; configure no pullup on both pins
pop x4 ;
nop2 ;
nop2 ;
out USBOUT, x1 ; <-- out J (idle) -- end of SE0 (EOP signal)
out USBDDR, x2 ; <-- release bus now
out USBOUT, x3 ; <-- ensure no pull-up resistors are active
rjmp doReturn
;延时8个时钟周期从调用到返回
;rcall delay8 ;
;xxx ;
#if USB_CFG_CLOCK_KHZ == 24000
delay8:
nop ;
nop ;
nop ;
nop ;
nop ;
ret ;
#endif
只为测速度这个也许还能用
不过跑32m用这种代码有些浪费了, 最好从usbdrvasm18-crc.inc类似的文件移植
之前测试内部rc在常温下还是很稳定的 不过温度如果变化大些就会出问题
我的想法刚好相反用PL2303+LGT完成编程器, 波特率到5000kbps或1mbps 这个速度是vusb不能比的
目前用上面这种方案使用swim协议读stm8 8kflash只要500多ms swim还是跑在低速位格式{:lol:} goodcode 发表于 2013-7-13 11:57 static/image/common/back.gif
只为测速度这个也许还能用
不过跑32m用这种代码有些浪费了, 最好从usbdrvasm18-crc.inc类似的文件移植
之前 ...
没错。确实V-USB速度快不了。不过PL-2303焊接有点难度。当然在linux下兼容性不错。win下就不知道了……
另外就是我没有移植32M的。用的16M分频而已。我尽量弄个原生32M CRC的。
LGT8F88A貌似进中断比标准AVR和08A慢一点。所以你的12M代码不能用。应该这个:/* Name: usbdrvasm12.inc
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2004-12-29
* Tabsize: 4
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id$
*/
/* Do not link this file! Link usbdrvasm.S instead, which includes the
* appropriate implementation!
*/
/*
General Description:
This file is the 12 MHz version of the asssembler part of the USB driver. It
requires a 12 MHz crystal (not a ceramic resonator and not a calibrated RC
oscillator).
See usbdrv.h for a description of the entire driver.
Since almost all of this code is timing critical, don't change unless you
really know what you are doing! Many parts require not only a maximum number
of CPU cycles, but even an exact number of cycles!
Timing constraints according to spec (in bit times):
timing subject min max CPUcycles
---------------------------------------------------------------------------
EOP of OUT/SETUP to sync pattern of DATA0 (both rx) 2 16 16-128
EOP of IN to sync pattern of DATA0 (rx, then tx) 2 7.5 16-60
DATAx (rx) to ACK/NAK/STALL (tx) 2 7.5 16-60
*/
;Software-receiver engine. Strict timing! Don't change unless you can preserve timing!
;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled
;max allowable interrupt latency: 34 cycles -> max 25 cycles interrupt disable
;max stack usage: = 11 bytes
;Numbers in brackets are maximum cycles since SOF.
USB_INTR_VECTOR:
nop
;order of registers pushed: YL, SREG , YH, shift, x1, x2, x3, cnt
push YL ;2 push only what is necessary to sync with edge ASAP
in YL, SREG ;1
push YL ;2
;----------------------------------------------------------------------------
; Synchronize with sync pattern:
;----------------------------------------------------------------------------
;sync byte (D-) pattern LSb to MSb: 01010100
;sync up with J to K edge during sync pattern -- use fastest possible loops
;The first part waits at most 1 bit long since we must be in sync pattern.
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
;waitForJ, ensure that this prerequisite is met.
waitForJ:
inc YL
//in YL, USBIN
sbis USBIN, USBMINUS
brne waitForJ ; just make sure we have ANY timeout
waitForK:
;The following code results in a sampling window of 1/4 bit which meets the spec.
//in YL, USBIN
sbis USBIN, USBMINUS
rjmp foundK
//in YL, USBIN
sbis USBIN, USBMINUS
rjmp foundK
//in YL, USBIN
sbis USBIN, USBMINUS
rjmp foundK
//in YL, USBIN
sbis USBIN, USBMINUS
rjmp foundK
//in YL, USBIN
sbis USBIN, USBMINUS
rjmp foundK
#if USB_COUNT_SOF
lds YL, usbSofCount
inc YL
sts usbSofCount, YL
#endif/* USB_COUNT_SOF */
#ifdef USB_SOF_HOOK
USB_SOF_HOOK
#endif
rjmp sofError
foundK:
;{3, 5} after falling D- edge, average delay: 4 cycles
;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
;are cycles from center of first sync (double K) bit after the instruction
push YH ;1
push x1 ;1
lds YL, usbInputBufOffset ;2
clr YH ;1
subi YL, lo8(-(usbRxBuf)) ;1
sbci YH, hi8(-(usbRxBuf)) ;1
in x1, USBIN ;1
sbrs x1, USBMINUS ;1
;sbis USBIN, USBMINUS ;1 we want two bits K
rjmp haveTwoBitsK ;1
pop x1
pop YH ;1 undo the push from before
rjmp waitForK ;1 this was not the end of sync, retry
haveTwoBitsK:
;----------------------------------------------------------------------------
; push more registers and initialize values while we sample the first bits:
;----------------------------------------------------------------------------
pop x1 ;1
push shift ;1 ;2
push x1 ;1 ;2
push x2 ;1 ;2
nop ;2
nop
nop ;1
in x1, USBIN ;1 <-- sample bit 0
ldi shift, 0xff ;1
bst x1, USBMINUS ;1
bld shift, 0 ;1
push x3 ;1 ;2
push cnt ;1 ;2
nop ;2
nop
in x2, USBIN ;1 <-- sample bit 1
ser x3 ;1
eor x1, x2 ;1
bst x1, USBMINUS ;1
bld shift, 1 ;1
ldi cnt, USB_BUFSIZE;1
nop ;1
rjmp rxbit2 ;1 ;2
;----------------------------------------------------------------------------
; Receiver loop (numbers in brackets are cycles within byte after instr)
;----------------------------------------------------------------------------
unstuff0: ;1 (branch taken)
andi x3, ~0x01 ;1
mov x1, x2 ;1 x2 contains last sampled (stuffed) bit
in x2, USBIN ;1 <-- sample bit 1 again
ori shift, 0x01 ;1
nop ;1
rjmp didUnstuff0 ;1 ;2
unstuff1: ;1 (branch taken)
mov x2, x1 ;1 x1 contains last sampled (stuffed) bit
andi x3, ~0x02 ;1
ori shift, 0x02 ;1
nop ;1
in x1, USBIN ;1 <-- sample bit 2 again
nop ;1
rjmp didUnstuff1 ;1 ;2
unstuff2: ;1 (branch taken)
andi x3, ~0x04 ;1
ori shift, 0x04 ;1
mov x1, x2 ;1 x2 contains last sampled (stuffed) bit
nop ;1
in x2, USBIN ;1 <-- sample bit 3
nop ;1
rjmp didUnstuff2 ;1 ;2
unstuff3: ;1 (branch taken)
in x2, USBIN ;1 <-- sample stuffed bit 3
andi x3, ~0x08 ;1
ori shift, 0x08 ;1
nop ;1
rjmp didUnstuff3 ;1 ;2
unstuff4: ;1 (branch taken)
andi x3, ~0x10 ;1
in x1, USBIN ;1 <-- sample stuffed bit 4
ori shift, 0x10 ;1
nop ;1
rjmp didUnstuff4 ;1 ;2
unstuff5: ;1 (branch taken)
andi x3, ~0x20 ;1
in x2, USBIN ;1 <-- sample stuffed bit 5
ori shift, 0x20 ;1
nop ;1
rjmp didUnstuff5 ;1 ;2
unstuff6: ;1 (branch taken)
andi x3, ~0x40 ;1
in x1, USBIN ;1 <-- sample stuffed bit 6
ori shift, 0x40 ;1
nop ;1
rjmp didUnstuff6 ;1 ;2
; extra jobs done during bit interval:
; bit 0: store, clear
; bit 1: se0 check
; bit 2: overflow check
; bit 3: recovery from delay
; bit 4: none
; bit 5: none
; bit 6: none
; bit 7: jump, eor
rxLoop:
eor x3, shift ;1 reconstruct: x3 is 0 at bit locations we changed, 1 at others
in x1, USBIN ;1 <-- sample bit 0
nop ;1
st y+, x3 ;1 ;2 store data
ser x3 ;1
nop ;1
eor x2, x1 ;1
bst x2, USBMINUS;1
bld shift, 0 ;1
in x2, USBIN ;1 <-- sample bit 1 (or possibly bit 0 stuffed)
andi x2, USBMASK ;1
breq se0 ;1 SE0 check for bit 1
andi shift, 0xf9 ;1
didUnstuff0:
breq unstuff0 ;1
eor x1, x2 ;1
bst x1, USBMINUS;1
bld shift, 1 ;1
rxbit2:
in x1, USBIN ;1 <-- sample bit 2 (or possibly bit 1 stuffed)
andi shift, 0xf3 ;1
breq unstuff1 ;1 do remaining work for bit 1
didUnstuff1:
subi cnt, 1 ;1
brcs overflow ;1 loop control
eor x2, x1 ;1
bst x2, USBMINUS;1
bld shift, 2 ;1
in x2, USBIN ;1 <-- sample bit 3 (or possibly bit 2 stuffed)
andi shift, 0xe7 ;1
breq unstuff2 ;1
didUnstuff2:
eor x1, x2 ;1
bst x1, USBMINUS;1
bld shift, 3 ;1
didUnstuff3:
andi shift, 0xcf ;1
breq unstuff3 ;1
in x1, USBIN ;1 <-- sample bit 4
eor x2, x1 ;1
bst x2, USBMINUS;1
bld shift, 4 ;1
didUnstuff4:
andi shift, 0x9f ;1
breq unstuff4 ;1
nop ;2
nop
in x2, USBIN ;1 <-- sample bit 5
eor x1, x2 ;1
bst x1, USBMINUS;1
bld shift, 5 ;1
didUnstuff5:
andi shift, 0x3f ;1
breq unstuff5 ;1
nop ;2
nop
in x1, USBIN ;1 <-- sample bit 6
eor x2, x1 ;1
bst x2, USBMINUS;1
bld shift, 6 ;1
didUnstuff6:
cpi shift, 0x02 ;1
brlo unstuff6 ;1
nop ;2
nop
in x2, USBIN ;1 <-- sample bit 7
eor x1, x2 ;1
bst x1, USBMINUS;1
bld shift, 7 ;1
didUnstuff7:
cpi shift, 0x04 ;1
brsh rxLoop ;2 loop control
unstuff7:
andi x3, ~0x80 ;1
ori shift, 0x80 ;1
in x2, USBIN ;1 <-- sample stuffed bit 7
nop ;2 ;1
nop
rjmp didUnstuff7 ;1 ;2
macro POP_STANDARD ; 12 cycles
pop cnt
pop x3
pop x2
pop x1
pop shift
pop YH
endm
macro POP_RETI ; 5 cycles
pop YL
out SREG, YL
pop YL
endm
#include "asmcommon.inc"
;----------------------------------------------------------------------------
; Transmitting data
;----------------------------------------------------------------------------
txByteLoop:
txBitloop:
stuffN1Delay: ;
ror shift ;[-5]
brcc doExorN1 ;[-4]
subi x4, 1 ;[-3]
brne commonN1 ;[-2]
lsl shift ;[-1] compensate ror after rjmp stuffDelay
nop ; stuffing consists of just waiting 8 cycles
rjmp stuffN1Delay ; after ror, C bit is reliably clear
sendNakAndReti: ;0 [-19] 19 cycles until SOP
ldi x3, USBPID_NAK ;1 [-18]
nop ;1 [-17]
rjmp usbSendX3 ;1;[-16];2 [-16]
sendAckAndReti: ;0 [-19] 19 cycles until SOP
ldi x3, USBPID_ACK ;1 [-18]
nop ;1 [-17]
rjmp usbSendX3 ;1 [-16];2 [-16]
sendCntAndReti: ;0 [-17] 17 cycles until SOP
mov x3, cnt ;1 [-16]
usbSendX3: ;0 [-16]
ldi YL, 20 ;1 [-15] 'x3' is R20
ldi YH, 0 ;1 [-14]
ldi cnt, 2 ;1 [-13]
; rjmp usbSendAndReti fallthrough
; USB spec says:
; idle = J
; J = (D+ = 0), (D- = 1) or USBOUT = 0x01
; K = (D+ = 1), (D- = 0) or USBOUT = 0x02
; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles)
;usbSend:
;pointer to data in 'Y'
;number of bytes in 'cnt' -- including sync byte
;uses: x1...x2, x4, shift, cnt, Y
;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction)
usbSendAndReti:
in x2, USBDDR ;[-12] 12 cycles until SOP
ori x2, USBMASK ;[-11]
sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
nop ;[-9]
out USBDDR, x2 ;[-8] <--- acquire bus
in x1, USBOUT ;[-7] port mirror for tx loop
ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror)
ldi x2, USBMASK ;[-5]
push x4 ;[-4]
nop ;[-3]
doExorN1:
eor x1, x2 ;[-2]
ldi x4, 6 ;[-1]
commonN1:
stuffN2Delay:
out USBOUT, x1 ; <--- set bit
ror shift ;
brcc doExorN2 ;
subi x4, 1 ;
brne commonN2 ;
lsl shift ; compensate ror after rjmp stuffDelay
nop ;
rjmp stuffN2Delay ;; after ror, C bit is reliably clear
doExorN2:
eor x1, x2 ;
ldi x4, 6 ;
commonN2:
nop ;
subi cnt, 171 ; trick: (3 * 171) & 0xff = 1
out USBOUT, x1 ; <--- set bit
brcs txBitloop ;
stuff6Delay:
ror shift ;
brcc doExor6 ;
subi x4, 1 ;
brne common6 ;
lsl shift ; compensate ror after rjmp stuffDelay
nop ; stuffing consists of just waiting 8 cycles
nop
rjmp stuff6Delay ; after ror, C bit is reliably clear
doExor6:
eor x1, x2 ;
ldi x4, 6 ;
common6:
stuff7Delay:
ror shift ;
out USBOUT, x1 ; <--- set bit
brcc doExor7 ;
subi x4, 1 ;
brne common7 ;
lsl shift ; compensate ror after rjmp stuffDelay
rjmp stuff7Delay ; after ror, C bit is reliably clear
doExor7:
eor x1, x2 ;
ldi x4, 6 ;
common7:
ld shift, y+ ;
nop ;
tst cnt ;;
out USBOUT, x1 ;; <--- set bit
;brne txByteLoop ;
breq makeSE0 ;
rjmp txByteLoop ;
makeSE0:
;make SE0:
cbr x1, USBMASK ; prepare SE0
lds x2, usbNewDeviceAddr;
lsl x2 ; we compare with left shifted address
subi YL, 2 + 20 ; Only assign address on data packets, not ACK/NAK in x3
out USBOUT, x1 ; <-- out SE0 -- from now 2 bits = 16 cycles until bus idle
sbci YH, 0 ;
;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
breq skipAddrAssign ;
sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer
skipAddrAssign:
;end of usbDeviceAddress transfer
ldi x2, 1<<USB_INTR_PENDING_BIT; int0 occurred during TX -- clear pending flag
USB_STORE_PENDING(x2) ;
ori x1, USBIDLE ;
in x2, USBDDR ;
cbr x2, USBMASK ; set both pins to input
mov x3, x1 ;
cbr x3, USBMASK ; configure no pullup on both pins
pop x4 ;
nop ;
nop
nop ;
nop
out USBOUT, x1 ; <-- out J (idle) -- end of SE0 (EOP signal)
out USBDDR, x2 ; <-- release bus now
out USBOUT, x3 ; <-- ensure no pull-up resistors are active
rjmp doReturn
本帖最后由 xwkm 于 2013-7-13 12:42 编辑
现在sbic/sbis指令可以正确使用了。
但是IRC能够成功起来custom的设备。作为HID或者传输大量数据就傻眼了。无法枚举成功。 xwkm 发表于 2013-7-13 12:25 static/image/common/back.gif
现在sbic/sbis指令可以正确使用了。
但是IRC能够成功起来custom的设备。作为HID或者传输大量数据就傻眼了。 ...
1. 大量数据传输用外部晶振就OK了, 内部的话只有直接上32M RC测试下。
2. 与08A相比, 中断并没有什么变化, 主要是读PORT值和08A不同, 因为88A本身做了同步,可以直接用SBIC/SBIS,
而用之前08A的先读到R里面,然后SBRC/SBRS, 每一个就要比08A慢1.5个周期了。 所以直接改成SBIC/SBIS就通过了。
汇编啊………………………… LGT 发表于 2013-7-13 13:12 static/image/common/back.gif
1. 大量数据传输用外部晶振就OK了, 内部的话只有直接上32M RC测试下。
2. 与08A相比, 中断并没有什么 ...
我还想用IRC做Bootloader呢。 xwkm 发表于 2013-7-13 12:25 static/image/common/back.gif
现在sbic/sbis指令可以正确使用了。
但是IRC能够成功起来custom的设备。作为HID或者传输大量数据就傻眼了。 ...
大量数据出错应该就是时序读取还是有问题的
usb转串口芯片好像就那个最便宜了 windows xp下用windows api进行操作还没问题 win7就不知道了
期待楼主和lgt官方的与08a芯片的区别 这样用88A的时候很快就能上手了 本帖最后由 xwkm 于 2013-7-13 15:27 编辑
goodcode 发表于 2013-7-13 14:59 static/image/common/back.gif
大量数据出错应该就是时序读取还是有问题的
usb转串口芯片好像就那个最便宜了 windows xp下用windows api ...
出错问题找到了:16M的文件少同步了一次。修复了。
区别有:
sbis/sbic指令可以用了。
进中断慢一个周期。
工程片5V触摸有点问题。
切换外振的时候注意操作时序,先使能PMCE后再去操作。保证周期限制。
现在正在用烙铁和冰块测IRC稳定性。就是烙铁靠近然后试USB传输稳定。
另外就是中断切换终于有了。现在做bootloader就要简单和稳定不少了,不过手册有一处描述错误。应该是对齐到512字节。
问过官方,他们说切换后偏移地址不会变。 xwkm 发表于 2013-7-13 15:26 static/image/common/back.gif
出错问题找到了:16M的文件少同步了一次。修复了。
区别有:
sbis/sbic指令可以用了。
进中断慢一个周期。 是不是中断向量表中rjmp编程jmp了
现在正在用烙铁和冰块测IRC稳定性。就是烙铁靠近然后试USB传输稳定。 我也用这种方式测试 太山寨了 哈哈
还没去细看手册 能切换中断向量表真是太方便了
谢谢楼主分享 goodcode 发表于 2013-7-13 16:21 static/image/common/back.gif
进中断慢一个周期。 是不是中断向量表中rjmp编程jmp了
现在正在用烙铁和冰块测IRC稳定性。就是烙铁靠近然 ...
不是。是中断处理哪里为了稳定多同步了一次。 xwkm 发表于 2013-7-13 00:37 static/image/common/back.gif
目前我还没坏过一片……
好消息,谢谢啊 LGT 发表于 2013-7-13 10:11 static/image/common/back.gif
楼上可以整几片LGT8F88A测试下, 看是不是和AVR一样皮实!:)
嗯,看来是要找个机会试一试 楼主是正在读高一的高中生,这个就算是你的暑假作业了?
好好努力,没考上大学直接就来我们公司上班。 logicgreen 发表于 2013-7-13 19:50 static/image/common/back.gif
楼主是正在读高一的高中生,这个就算是你的暑假作业了?
好好努力,没考上大学直接就来我们公司上班。 ...
当然不是啦。我前十天一直在写作业。后面几天当然要好好休息下…… 不知道现在的作业量多少, 我上学的时候十来天就糊弄完了{:lol:} 那玩意交了就行 根本没人看 呵呵
这个年龄,这样的主动性,如果环境好会是前途无量的{:lol:} 还是得写个32M的RC专门针对的汇编出来。自从被我烙铁处理后貌似频率调不准了。看来只能靠软件滑动补偿咯。 本帖最后由 xwkm 于 2013-7-15 15:12 编辑
goodcode 发表于 2013-7-13 21:06 static/image/common/back.gif
不知道现在的作业量多少, 我上学的时候十来天就糊弄完了 那玩意交了就行 根本没人看 呵呵
这个年龄, ...
to goodcode。如果你有LGT8F88A的话。这个程序帮我测试下。我发现内置rc usb误码率有点高。
现在我在做兼容usbasp的bootloader。 90999 发表于 2013-7-13 00:05 static/image/common/back.gif
奇怪了,我十几年没撸了,怎么看东西还有重影啊?肯定是肾亏了。
不能同意的更多了。。。。 xwkm 发表于 2013-7-15 15:10 static/image/common/back.gif
to goodcode。如果你有LGT8F88A的话。这个程序帮我测试下。我发现内置rc usb误码率有点高。
现在我在做 ...
我还没申请这个芯片... 你试试串口加上奇偶效验在高高波特率下有没有问题. goodcode 发表于 2013-7-15 19:34 static/image/common/back.gif
我还没申请这个芯片... 你试试串口加上奇偶效验在高高波特率下有没有问题. ...
串行口还好。出厂已经OSCCAL校准过了。现在的问题就是V-USB在内置rc下误码率比较高。
可能bootloader得换种方式实现。 串口室温下没问题证明内部rc还是稳定的 goodcode 发表于 2013-7-16 00:10 static/image/common/back.gif
串口室温下没问题证明内部rc还是稳定的
不过在循环里翻转IO口的话。会出现这种状况。4MHz偶尔出现几个3.7MHz或者4.2MHz的波形。
这个串行口要求又没usb那么高。如果写usb boot不依赖晶振的话。必须做校验处理。 xwkm 发表于 2013-7-16 00:13 static/image/common/back.gif
不过在循环里翻转IO口的话。会出现这种状况。4MHz偶尔出现几个3.7MHz或者4.2MHz的波形。
这个串行口要求 ...
建议你用PWM测试内部RC的频率, 用I/O翻转要保证程序不会被中断。
校准过后的RC频率是非常稳定的, 我测试了一些芯片, 都是非常稳定的。 不过在循环里翻转IO口的话。会出现这种状况。4MHz偶尔出现几个3.7MHz或者4.2MHz的波形。{:sweat:} 不会这么不稳定吧
08a的工程样片也没这样啊 我一直用08a的内部rc测试vusb 因为工程样片的外部晶振有问题 调试麻烦{:lol:} goodcode 发表于 2013-7-16 10:35 static/image/common/back.gif
不过在循环里翻转IO口的话。会出现这种状况。4MHz偶尔出现几个3.7MHz或者4.2MHz的波形。 不会这么 ...
08A的16M IRC还能带起来USB?我没一次成功过。
至于那个问题可能是线太长。寄生振荡了吧。 我手里用过的08a的芯片 OSCCAL = 0x08; 跑vusb就可以了 室温20~30多度都没问题
如果rc没问题, 可以在*.inc分块插一些没用的io翻转用逻辑分析仪辅助查看usb的时序和内部代码处理到什么地方是慢了还是快了
说起来简单 调试起来挺麻烦的一个活 goodcode 发表于 2013-7-16 13:19 static/image/common/back.gif
我手里用过的08a的芯片 OSCCAL = 0x08; 跑vusb就可以了 室温20~30多度都没问题
如果rc没问题, 可以在*.inc ...
08A的我自己写过用信标校准的程序。也用外振校准内部rc。但是死活V-USB就没起来过。 xwkm 发表于 2013-7-16 23:18 static/image/common/back.gif
08A的我自己写过用信标校准的程序。也用外振校准内部rc。但是死活V-USB就没起来过。 ...
我测的5,6片都ok{:sweat:} RP不高。Bootloader custom协议完成。现在可以只接usb。外部一个 1.5k 电阻就能够通讯了。
页:
[1]