Ik ben nu heel druk aan het programmeren (ik ben nu bezig met de command-line interface via een VT100 terminal), en ik kom wat vreemde zaken tegen bij het schrijven van assembler voor de AT90S8515 met de assembler van Atmel.

Het meest vreemde (waar ik ook langer dan een uur op heb zitten zoeken) is het volgende:


CommandTable:	;List of all commands
		;first byte is ID, last byte should be 0
		.db	1, "CLS", 0
		.db	2, "RESET", 0
		.db	3, "SYSTEM", 0, 0
		.db	5, "READF", 0
		.db	4, "READ", 0, 0
		.db	6, "HELP", 0, 0

CommandTableEnd: .db	0, 0, 0, 0, 0

Als ik bij de woorden met een even aantal letters de laatste 0 weghaal (zodat de entry een EVEN aantal bytes is), dan start de controller helemaal niet op. Na een reset gebeurt er dan helemaal niets meer.

Dat vind ik dus wel heel erg vreemd. Ik zou me nog kunnen voorstellen dat iedere entry een even aantal bytes moet zijn, omdat het programmageheugen bestaat uit 16-bits woorden. Maar dat ze oneven moeten zijn, dat slaat alles. En waarom start de controller dan niet op?

Wie weet er hoe dit in elkaar zit?

Ik kan wel zo het een en ander bedenken wat ten grondslag ligt aan jouw probleem.
Ook durf ik zo wel te zeggen dat jouw conclusie betreffende het zogenaamde oneven aantal benodigde bytes niet juist is.

Maar.... ik heb meer info nodig over je programma dan je tot nu toe heb gegeven. Want HOE gebruik je die CommandTable? Want enkel een "verkeerde" tabel weerhoudt in eerste instantie een controller niet om op te starten.

Dus gelieve de code waarin je de tabel aaroept cq gebruikt ook even te plaatsen.

Dit is alle data in Flash:


.cseg
.org $0

	rjmp 	InitAll
	rjmp	EXT_INT0		;IRQ 0
	rjmp	EXT_INT1		;IRQ 1 
	rjmp	TIM1_CAPT		;Timer 1 capture 
	rjmp	TIM1_COMPA		;Timer 1 compare A
	rjmp	TIM1_COMPB		;Timer 1 compare B
	rjmp	TIM1_OVF		;Timer 1 overflow
	rjmp	TIM0_OVF		;Timer 0 overflow
	rjmp	SPI_Handler		;Serial transfer complete
	rjmp	UART_RXC		;Uart RX complete
	rjmp	UART_DRE		;Uart data register empty
	rjmp	UART_TXC		;Uart TX complete
	rjmp	ANA_COMP		;Analog comparator



; **** GENERAL DATA

CRLFMsg:	.db	CR, LF, 0
InitMsg:	.db	"AVR test, (c) 2004 by Digital Guru", CR, LF, 0
RamTopMsg:	.db	"Top of internal Ram: $", 0
ExRamTopMsg:	.db	"Top of external Ram: $", 0
StackMsg:	.db	"End of stack:        $", 0
StackSizeMsg:	.db	"Max size of stack:   $", 0
HeapMsg:	.db	"Start of heap:       $", 0
TXStartMsg:	.db	"Start of TX buffer:  $", 0
TXSizeMsg:	.db	"Size of TX buffer:   $", 0
RXStartMsg:	.db	"Start of RX buffer:  $", 0
RXSizeMsg:	.db	"Size of RX buffer:   $", 0
HeapFreeMsg:	.db	"Start of free space: $", 0
MemFreeMsg:	.db	"Free memory:         $", 0
GetHelpMsg:	.db 	"HELP for a list of commands.", CR, LF, 0
HelpMsg:	.db 	"All numbers are in HEX, ex: $FF, $FFFF and $FFFF:FF.", CR, LF, 0
ReadyMsg:	.db 	"System ready.", CR, LF, 0
ErrorMsg:	.db 	"Unrecognized command.", CR, LF, 0
RMErrorMsg:	.db 	"Not a valid adress.", CR, LF, 0

CommandTable:	;List of all commands, 
		;first byte is ID, last byte should be 0
		.db	1, "CLS", 0
		.db	2, "RESET", 0
		.db	3, "SYSTEM", 0, 0
		.db	5, "READF", 0
		.db	4, "READ", 0, 0
		.db	6, "HELP", 0, 0

CommandTableEnd: .db	0, 0, 0, 0, 0

en dit is de functie:


;Returns ID of command that is in LineBuf in temp
FindCommand:
	push	i
	in	i, SREG
	push	i
	push	A
	push	ZL
	push	ZH
	push	YL
	push	YH
	ldi	ZL, low(CommandTable<<1)
	ldi	ZH, high(CommandTable<<1)
FindCommandThis:
	lds	YL, LineBuf
	lds	YH, LineBuf + 1
	lpm
	adiw	ZH:ZL, 1
	mov	temp, A
	tst	temp
	brne	FindCommandCont		;ID = 0, no command found
FindCommandSkip:
	lpm
	adiw	ZH:ZL, 1
	mov	temp, A
	tst	temp
	breq	FindCommandEnd		;ID = 0, no command found
FindCommandCont:
	ld	i, Y+			;first char of line
	lpm
	adiw	ZH:ZL, 1		;first char of command
	cp	i, A
	breq	FindCommandNext		;first letter matches
FindCommandNextID:
	lpm
	adiw	ZH:ZL, 1		
	tst	A
	brne	FindCommandNextID
	adiw	ZH:ZL, 1		
	rjmp	FindCommandThis	
FindCommandNext:
	ld	i, Y+			;next char of line
	lpm
	adiw	ZH:ZL, 1		;next char of command
	tst	A
	breq	FindCommandEnd		;found it
	cp	i, A
	breq	FindCommandNext		;next letter matches
	rjmp	FindCommandNextID
FindCommandEnd:
	pop	YH
	pop	YL
	pop	ZH
	pop	ZL
	pop	A
	pop	i
	out	SREG, i
	pop	i
	ret

Maar als ik die nullen achter die entries weghaal, dan start de controller niet meer op. Ook niet als ik die routine weghaal. Hij komt daar niet meer. Hij komt dan zelfs niet meer bij de code waar hij bij een reset naartoe springt.

Hier staat de hele code.

Ik zou het geweldig vinden als je me zou kunnen uitleggen wat er fout gaat!

Ehm, hoe heb je bepaald dat je controller niet opstart?

Je bent vergeten dat er voor je strings ook nog een ID nummer staat, dat moet je wel meerekenen. Als je dus een even aantal karakters in je string hebt heb je een oneven aantal bytes in je entry want -> even karakt + ID = oneven bytes dus moet er een enkele afsluitnul bij om het even te maken, NU heb je juist met deze code dat je een "verkeerd" aantal bytes hebt gevult in zijn geheugen.

Welke assembler gebruik je om je code van asm naar hex te converteren? Want de meeste zetten er zelf een 0 achter als jij een ruimte niet juist hebt gevult met even bytes.

Als je kijkt naar een stukje van je listing:


       .db	6, "HELP", 0
000100 4806
000101 4c45
000102 0050

Dan zie je dat het zo hoort. Op adres 000100 staat de 06 van je 6 als ID en de 48 van de H. Dan komt de 45 van je E, de 4c van je L en tot slot de 50 van je P (dat zijn de hex waardes van je ascii karakters). Om die plek "af te sluiten" was die ene nul dus nodig want anders blijft de plek voor die 50 op adres 000102 open, dus er wordt afgesloten met een enkele 0 die je ook ziet op adres 100102

[Bericht gewijzigd door Bastiaan op ]

Ja, dat is dus precies hetgene dat ik niet begrijp! Want als ID + string + afsluitnul een even aantal bytes is, gaat het fout. Is het oneven, dan plakt de assembler er nog een extra 0 achter (dus maximaal 3 ipv. 1) en dan gaat het dus wel goed.

Met 'niet opstarten' bedoel ik, dat zelfs als ik bij InitAll alles uitrem behalve het zetten van de stack op RAMEND en het initialiseren van de UART, buffers en interrupts, er geen text op de terminal verschijnt. En dan reageert hij nergens meer op. Ik heb niet geprobeerd een ledje te laten knipperen op een vrij pootje.

Je kunt het programma volgens mij ook op een controller draaien zonder extern SRAM als je de TXbufSize en RXbufSize klein zet (als je een string schrijft die niet past gaat het goed maar moet je wachten), als je ".org RAMEND + 1" wijzigt in ".org RAMFREE" en de SRAMloop uitremt.

Als je een ander kristal dan 6 Mhz gebruikt, moet je ook de waarde van baud96 aanpassen.

Ik kan eventueel ook zelf de aanpassingen maken en een versie posten die zonder aanpassingen werkt op een kale AT90S8515.

Ik gebruik trouwens de assembler van Atmel.

Edit: ik heb zelfs geprobeert alles in InitAll uit te remmen en rechtstreeks een char naar de UART te schrijven, met hetzelfde resultaat. Maar er zijn dan natuurlijk nog steeds een heleboel andere dingen die toch invloed kunnen hebben. Het is lastig de zaak te debuggen als de terminal niet werkt, ik heb nog niet kunnen ontdekken hoe ik in AVRstudio extern SRAM kan aanmelden als ik hem niet ook laat programmeren (ik gebruik de programmer van deze site met PonyProg).

[Bericht gewijzigd door DiGuru op ]

Ok. Ik heb de source aangepast. Het draait nu ook op een AT90S8515 zonder extern geheugen (en waarschijnlijk op de meeste andere AVR's met minimaal 256 bytes RAM), je moet nog wel de waarde van "baud96" aanpassen aan de waarde van je kristal: 25 voor 4Mhz of 51 voor 8Mhz.

[Bericht gewijzigd door DiGuru op ]

Vaag verhaal, DiGuru.. Of eigenlijk een duidelijk verhaal, maar een vaag gebeuren.

Ik heb op diverse controllers en uPs in assembly gewerkt en inderdaad, de assembler moet (indien nodig) extra 0-en toevoegen. Daar is het ding voor, anders kan ik net zo goed direct zelf m'n hexfiletje tikken...

Echter... Ik heb ook al meerdere compilers / assemblers gevonden waar fouten in zitten. Ik zou als ik jou was die zelfde code eens door een andere assembler heen trekken en eens kijken wat voor hex file je dan hebt. Heb hier ook nog wel ergens AVR studio, al is het ruim een jaar geleden dat ik er voor het laatst wat mee gedaan heb.

Groet
Marco

Ja, ik verwacht zelf ook dat het een bug is in de assembler. Ik kwam een mailinglist tegen waar nog wat meer foutjes naar voren werden gebracht, waarna een ontwikkelaar van de assembler reageerde dat er inderdaad wat slordigheidjes inzaten.

Nou ja, ik weet waar ik op moet letten.