Jump to content

using assembler in C - question about _ in front of macro names


ilmenator

Recommended Posts

Hello,

I am currently trying to use some assembler code snippets described in this thread (http://www.midibox.org/forum/index.php?topic=4140.0) to access an SRAM chip connected to J15 of the core module within my C application. Basically I know how to use assembler code in C, but it seems like I do not fully understand how variables names are used in the assembler to C mechanism.

Here come the errors I get when I try to compile my code.

Assembling MIOS SDCC wrapper
==========================================================================
Compiling pic18f452.c
Processor: 18F452
==========================================================================
Compiling main.c
Processor: 18F452
In file included from main.c:17:
sram.c:83:3: warning: "/*" within comment
sram.c:123:3: warning: "/*" within comment
sram.c:185:3: warning: "/*" within comment
_output\main.asm:506:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:506:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:507:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:507:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:508:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:508:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:509:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:509:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:510:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:510:Error [113] Symbol not previously defined (TRISA).
_output\main.asm:512:Error [113] Symbol not previously defined (PORTA).
_output\main.asm:512:Error [113] Symbol not previously defined (PORTA).
_output\main.asm:513:Error [113] Symbol not previously defined (PORTA).
_output\main.asm:513:Error [113] Symbol not previously defined (PORTA).
_output\main.asm:514:Error [113] Symbol not previously defined (PORTA).
_output\main.asm:514:Error [113] Symbol not previously defined (PORTA).
_output\main.asm:515:Error [113] Symbol not previously defined (PORTA).
_output\main.asm:515:Error [113] Symbol not previously defined (PORTA).
_output\main.asm:516:Error [113] Symbol not previously defined (PORTA).
_output\main.asm:516:Error [113] Symbol not previously defined (PORTA).
ERROR!
Now, this is the section that the errors originally refer to:
void SRAM_Init(void) __wparam
{
	__asm
	;; disable the ADC which allocates the analog pins
	;; only needed if controls pins are connected to port A
	movlw	0x07
	movwf	_ADCON1

	; put PortA in output mode
	bcf		SRAM_TRIS_LATCH1_LE, SRAM_PIN_LATCH1_LE
	bcf		SRAM_TRIS_LATCH2_LE, SRAM_PIN_LATCH2_LE
	bcf		SRAM_TRIS_CS, SRAM_PIN_CS
	bcf		SRAM_TRIS_WE, SRAM_PIN_WE
	bcf		SRAM_TRIS_OE, SRAM_PIN_OE
	; set control lines
	bsf		SRAM_PORT_OE, SRAM_PIN_OE
	bsf		SRAM_PORT_WE, SRAM_PIN_WE
	bsf		SRAM_PORT_CS, SRAM_PIN_CS
	bcf		SRAM_PORT_LATCH1_LE, SRAM_PIN_LATCH1_LE
	bcf		SRAM_PORT_LATCH2_LE, SRAM_PIN_LATCH2_LE

	; put PortE in output mode
	bcf		_TRISE, 0
	bcf		_TRISE, 1
	bcf		_TRISE, 2
	__endasm;

	return;
}
I know this because before adding an underscore in front of [tt]ADCON1[/tt], I got the same '_output\main.asm:506:Error [113] Symbol not previously defined (ADCON1)' error message as I get them for the TRISA now. The problem is that there is a macro
#define SRAM_TRIS_LATCH1_LE     TRISA
in a header file included from the main.c that defines TRISA, but if I add the underscore in front of TRISA there I still get the same error message. When I look at the main.asm file in the \output folder, I can see that the macro gets translated to
; ; Starting pCode block
S_main__SRAM_Init	code
_SRAM_Init:
	;; disable the ADC which allocates the analog pins
	;; only needed if controls pins are connected to port A
	movlw 0x07
	movwf _ADCON1
	; put PortA in output mode
	bcf TRISA, 0
	;bcf TRISA, 1
	;bcf TRISA, 2
	;bcf TRISA, 3
	;bcf TRISA, 5
	; set control lines
	bsf PORTA, 5
	bsf PORTA, 3
	bsf PORTA, 2
	bcf PORTA, 0
	bcf PORTA, 1
	; put PortE in output mode
	bcf _TRISE, 0
	bcf _TRISE, 1
	bcf _TRISE, 2

So how does that underscore thing work and what do I need to do in order to make it work in macros, too? Or how do I need to modify my code for direct access to the TRISA register from C ?  ???  :-[

Thanks for reading, ilmenator

Link to comment
Share on other sites

Hi Ilmenator,

so long you've included the pic18f452.h header file into the >> C << code:

#include "pic18f452.h"

you have access to the SFRs in this simple way:

  ADCON = 0x07;

  TRISAbits.TRISA0 = 0;

  TRISAbits.TRISA1 = 0;

  TRISAbits.TRISA2 = 0;

  ...

The structures are described in pic18f452.h - note that they are also valid for pic18f4620, no special header file is required here

So far I remember, once you include it, the SFRs will also be accessible within inline assembly code, when you add the underscore

Best Regards, Thorsten.

Link to comment
Share on other sites

Thanks TK,

I've been doing some more digging and I have learned quite a lot.  :)

I have managed to compile large parts of the SRAM code mentioned above within my C application, among others doing things like replacing

lfsr    FSR1, SRAM_MAP
by
movff	_FSR1L, SRAM_MAP_L
. It was mentioned somewhere in another post. Still unsolved are things like
movff 	POSTINC1, _PORTB
which are really out of scope for me at the moment. Also, by looking at the [tt]main.asm[/tt] file in [tt]/output[/tt] I found out about the underscore thing - most of the time it seems to work like this, the strange thing is that I can leave out the underscore for [tt]TMP1[/tt], see this example ??
void SRAM_Read_Page_Loop(void){
	_asm
        ; first latch
        movff 	TMP1, _PORTB
	bsf 	_LATA, SRAM_PIN_LATCH1_LE
	bcf 	_LATA, SRAM_PIN_LATCH1_LE

	; enable port read mode
	setf	_TRISB
	bcf 	_LATA, SRAM_PIN_CS
	bcf 	_LATA, SRAM_PIN_OE
	nop
	; read data into PIC memory
	movff 	_PORTB, _POSTINC1
	bsf 	_LATA, SRAM_PIN_OE
	bsf 	_LATA, SRAM_PIN_CS
	; disable port read mode
	clrf	_TRISB
	incf    TMP1, F
	cpfseq  TMP1
	bra     _SRAM_Read_Page_Loop
	__endasm;

	return;
}
I also took a deep look at the [tt]mios_wrapper.asm[/tt], there I am not sure why some of the MIOS functions have additional instructions and onthers not? Is it because the others are not implemented yet, or because there is no need for additional code instructions? Eg I am trying to use [tt]MIOS_HLP_GetBitORMask[/tt] without success, looking at the wrapper I see
;; --------------------------------------------------------------------------
.MIOS_HLP_GetBitORMask code MIOS_HLP_GetBitORMask
_MIOS_HLP_GetBitORMask
	global	_MIOS_HLP_GetBitORMask

, so it is there and I thought I just have to add the underscore... but no joy  :(

Maybe I should just drop the SRAM assembler code snippets and do it all from scratch in pure C?

Thanks for any input, ilmenator

Link to comment
Share on other sites

Take care when handling with FSR pointers - the fix2asm.pl script swaps all FSR1 related registers by FSR0 (which means: also POSTINCx, POSTDECx, ... see tools/fixasm.pl) and vice versa to avoid a conflict with register resources. These addresses are directly defined by SDCC within the generated assembly code (unfortunately!!!) and therefore don't need an underscore. Sometimes, if the compiler doesn't need these pointer access registers, it doesn't define them, therefore you won't see the names.

I think the only proper solution how to handle this is not to use inline assembly code here, but to define the functions in a seperate .asm file. Examples are available at mios download page (C based sm_examples, or midi_router project)

I also took a deep look at the mios_wrapper.asm, there I am not sure why some of the MIOS functions have additional instructions and onthers not? Is it because the others are not implemented yet, or because there is no need for additional code instructions?

they don't need additional code, because they expect none or a single parameter in WREG and/or return a single parameter in WREG

Maybe I should just drop the SRAM assembler code snippets and do it all from scratch in pure C?

My proposal: always try C first, and if the generated code doesn't look performant enough, then you can think about an assembly based version.

Best Regards, Thorsten.

Link to comment
Share on other sites

Thanks,

I looked at the C based sm_examples. Now I wonder how the [tt]sm_simple.asm[/tt] is "included" into the C code? Is it only done by creating [tt]sm_simple.o[/tt] in the makefile and everything else happens automagically? I cannot find any include instructions in the rest of the code??

Best regards, ilmenator

Link to comment
Share on other sites

Sorry for trying to answer my own post...

I think it is just the other way round:

#include "mios_wrapper/mios.h"
#include "mios_wrapper/mios_vectors.inc"
#include "macros.inc"

get included in [tt]sm_simple.asm[/tt] and the labels are kind of "exported" to the C code?? Therefore [tt]sm_simple.asm[/tt] needs to be compiled before [tt]main.c[/tt]?

Still a bit confused about this, I have to admit. Is there any recommended reading?

Thanks, ilmenator

Link to comment
Share on other sites

within the assembly file, you should add an underscore to the labels which should be visible from C, and make them global (search for "global" in the sm_simple.asm file)

Then you need a special header file with extern statements, which will be included into the C program in order to import the lables (see sm_simple.h)

I cannot recomment any book which describes such methods sufficiently, I just know them since years from different magazines.

Best Regards, Thorsten.

Link to comment
Share on other sites

Thanks stryd!

Actually I am trying to read one of those Korg RAM cards made for the M line of synthesizers. I have the connector set up and ready, and the SRAM Test v1.1 by TL does its job as expected - although sometimes the RAM address changes unexpectedly when moving one of the other encoders. Anyway, this does not matter to me because I only wanted to make sure that my wiring is okay.

Now I have to design my own code, and seeing that there might still be a bug in TL's code I am even more motivated to go the C way. If you have any ready-made code for that, it is most welcome, but I think I should manage. You will surely see more questions arise, though... :)

Best regards, ilmenator

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...