PIC10F322 AD Project in Assembly, RS232

(instructions, reset, WDT, specifications...) PIC10F2xx, PIC12F5xx, PIC16F5x

Re: PIC10F322 AD Project in Assembly, RS232

Postby MMcLaren » Wed Sep 03, 2014 4:51 pm

Thanks for the info', Olin.

Surprisingly, after all your complaining about wanting a fixed time wait minus some cycles, yours doesn't do that either.

It's interesting that you would perceive my query and assessment as a complaint. I simply asked if your WAIT macro was capable of a certain function and then determined it was not. Of course you pointed out, and I acknowledged, that you have other macros which will perform the function I asked about.

Your assessment of the in-line delay macro I posted and its ability to perform a fixed delay minus some cycles may have been a little hasty. I can assure you it performs that function quite well (while letting the assembler do all the work);

Code: Select all
;==================================================================
;  inDlyCy() in-line delay             Mike McLaren, K8LH, Jun'07
;
        radix dec
clock   equ     4               ; 4, 8, 12, 16, or 20 MHz
usecs   equ     clock/4         ; cycles/usec operand multiplier

inDlyCy macro   delay           ; 0..1027 cycles
        local   loop
     if delay > 3
        movlw   delay/4
loop    addlw   -1              ; 4 cycle loop (14 bit core)
        skpz                    ; done? yes, skip, else
        goto    loop            ; loop (do another 4 cycles)
     endif
     if delay&2                 ; delay%4 == 2 or delay%4 == 3
        goto    $+1             ; delay 2 additional cycles
     endif
     if delay&1                 ; delay%4 == 1 or delay%4 == 3
        nop                     ; delay 1 additional cycle
     endif
        endm
Code: Select all
;
;  example macro invocation
;
        inDlyCy(470*usecs-12)   ; delay 470-us minus 12 cycles



Note the new optional second parameter. That defaults to 1 cycle, so previous code using this macro without the second parameter should work identically.

Thank you. That's a very nice example of the ease at which you can modify one of your macros.

The MPASM macro facility is rather primitive. It can do some things, but other things are either difficult, awkward, or impossible. Your MPASM example wait macro does a lot less than my PREPIC macro, so it's apples versus oranges. Yours doesn't take a time value and compute the number of cycles, does no error checking for the wait time being too long (it will just silently produce the wrong delay), and couldn't emit a nice readable error message if it did.

Good points, thank you, but aren't there facilities in standard MPASM macros to do some of those things? I'll have to check but I think I may have used MPASM intrinsic macro features to check values and emit messages in the past. And I hope you can see from the example above that it's relatively easy to convert a time value to cycles. However, your points are well taken. There are plenty of things I wish I could do with MPASM macros which are impossible.

The MAPASM and ASM30 preprocessor is a executable called PREPIC. In my build environment, I write .ASPIC (and .DSPIC on 16 bit core parts) source files. These are translated by the preprocessor to produce the .ASM file for MPASM or the .AS file for ASM30, which are then translated with the Microchip assemblers as usual.

This may have been part of the reason why I dismissed your ASPIC macro language subsystem years ago. It was, and still is, difficult to justify adding components to my development environment which may have questionable value or performance and it's difficult to justify the time that would be required to vet the system. Then you have to consider if the investment is worth the return. Hopefully you realize these are practical considerations and not intended to be offensive.

Now I mostly just write PREPIC macros, whether they could have been written easily in native assembler or not.

Yes, I've noticed that over the years. <caution - attempt to inject humor> When Tom asked you to post something I screamed at the computer "No Tom! Please, don't ask him for that!" (lol).

On a more serious note. I wonder if your use of ASPIC macros is having the desired effect? That is, I realize they must have immense production value for you, but when you post a code snippet laced with ASPIC macros, would average people be inclined to spend time decrypting the code to see how it worked? Speaking for myself, I've looked at several of your snippets over the years. Often, after spending ten minutes just to realize that a couple ASM instructions could have been used instead of a cryptic macro, which would have made the code much more readable and comprehensible, I would move on to something more interesting. Don't get me wrong, I love studying code, but it just wasn't worth the effort and investment in time (for me) to study your version of something I had probably already mastered.

Olin, thank you for taking valuable time away from your other duties to indulge my questions.

Cheerful regards, Mike
MMcLaren
 
Posts: 18
Joined: Sun Aug 31, 2014 10:08 pm
PIC experience: Experienced Hobbyist

Re: PIC10F322 AD Project in Assembly, RS232

Postby Olin Lathrop » Wed Sep 03, 2014 5:38 pm

MMcLaren wrote:Your assessment of the in-line delay macro I posted and its ability to perform a fixed delay minus some cycles may have been a little hasty. I can assure you it performs that function quite well (while letting the assembler do all the work);

I was referring to it taking a argument in units of cycles instead of units of time. It looks like you deal with that by multiplying time by the USEC constant in the macro invocation, but that's going to have trouble when there isn't a nice integer multiple of cycles in one microsecond. I guess that's valid for the 10Fs (12 bit core parts), as long as you don't make the instruction clock slower than 1 MHz.

This is a good example where floating point math at build time can be very useful.

but aren't there facilities in standard MPASM macros to do some of those things? I'll have to check but I think I may have used MPASM intrinsic macro features to check values and emit messages in the past.

MPASM isn't completely impotent, but there are some things that are difficult, awkward, or impossible. Emitting a message to standard output is one of the awkward ones. This can be done with the MESSG directive, but it imposes a lot of formatting on you and puts stuff around whatever message you try to emit. In contrast, my /SHOW command simply writes out whatever you give it.

And I hope you can see from the example above that it's relatively easy to convert a time value to cycles.

The assembler can only do math on 32 bit integers. You can usually get clever and arrange the representation of values so that you have enough resolution at the low end and still be able to express the maximum possible value. However, that can lead to awkwardness, and you have to think carefully about scaling when doing math. For example, you might need to express time values in nanoseconds to be able to deal with non-integer numbers of instructions in one microsecond. When you do that, you have to be careful of the order of multiplies and divides if you do math on such value. It generally can be done, but doing it in floating point is a whole lot easier and therefore less error-prone.

This may have been part of the reason why I dismissed your ASPIC macro language subsystem years ago. It was, and still is, difficult to justify adding components to my development environment which may have questionable value or performance and it's difficult to justify the time that would be required to vet the system. Then you have to consider if the investment is worth the return.

I had the advantage of evolving my build environment with PREPIC. Usually after adding a feature to PREPIC, life seems great, until something else starts bugging me. About every 6 months or so, it bugs me enough to add a new feature, then life is great again for another 6 months until I can't ignore the next thing bugging me. For example, I need a better way to create unique labels in macros, which is done with LOCAL in MPASM (LOCAL has its own problems, but that's another issue). Right now I use a global integer constant that is incremented each macro invocation, and glue the constant value to the end of label names. That works, but it's awkward, so eventually I'll build in a native means for creating unique labels.

On a more serious note. I wonder if your use of ASPIC macros is having the desired effect? That is, I realize they must have immense production value for you, but when you post a code snippet laced with ASPIC macros, would average people be inclined to spend time decrypting the code to see how it worked?

Generally you read the main code like you would MPASM code. PREPIC macros are deliberately invoked just like native macros, so don't look any different. Now if you want to understand the macros, then you have to know more about PREPIC. PREPIC is just another language, so no big deal if you really want to learn it.

The harder part is inserting PREPIC into your toolchain. I build everything externally from MPLAB by using a set of scripts. These allow automating builds, for one thing, which you can't do if you have to open a GUI and clickety-click to do a build. I haven't explored MPLABX yet, so maybe it has the ability to understand external tools to be run specified by a general rule. For example, to build a .ASPIC file, you run PREPIC to make a .ASM file, then you run MPASMWIN to make the binary file. I haven't look to see if MPLABX can do that. As far as I can tell, MPLAB 8 can't.

Speaking for myself, I've looked at several of your snippets over the years. Often, after spending ten minutes just to realize that a couple ASM instructions could have been used instead of a cryptic macro, which would have made the code much more readable and comprehensible,

More readable is subjective and debatable. Each macro does something the native instructions don't do. In a few cases they are just synonims to make understanding easier, but not most of the time. For example, my SKIP_WLE macro is just a synonim for BTFSS STATUS,C. While the native instruction tells you the detail of what exactly it is doing, SKIP_WLE tells you the higher level intent, which is to skip the next instruction if W was less than or equal to the other value in a SUBWF or SUBLW instruction. It also avoids having to do the mental gymnastics each time to keep track of which quantity was actually subtracted from which, what a borrow then means, and then remember that C is the complement of borrow.

In other cases, there is probably more going on than you realize, usually having to do with portability accross PICs, automatically adjusting to the instruction frequency in use, automatically emitting code that has to play nice with a compiler or do it the efficient way depending on configuration, etc. Show me some macros you think are superfluous, and I can probably show you a good reason for them.
User avatar
Olin Lathrop
Verified identity
 
Posts: 48
Joined: Fri May 30, 2014 3:38 pm
Location: Littleton, MA USA
PIC experience: Professional 5+ years with MCHP products

Re: PIC10F322 AD Project in Assembly, RS232

Postby MMcLaren » Thu Sep 04, 2014 12:43 am

Well, I have no doubt PREPIC is a nice system but it's gotta' be a "hard sell". I can't imagine very many people are willing to install a non-Microchip add-on just to be able to study and simulate your code, and that's a shame. A very reputable and well respected gentleman by the name of Scott Dattalo has been sharing wonderful magical esoteric concepts and algorithms for decades now using pure asm (my hero).

Cheerful regards, Mike
MMcLaren
 
Posts: 18
Joined: Sun Aug 31, 2014 10:08 pm
PIC experience: Experienced Hobbyist

Re: PIC10F322 AD Project in Assembly, RS232

Postby MMcLaren » Thu Sep 04, 2014 1:38 am

Hey guys,

I haven't come across a compelling or authoritative premise to support a conclusion that CBLOCK shouldn't be used in non-relocatable programs.

My 2 cents (I'm not an expert)...

Cheerful regards, Mike
MMcLaren
 
Posts: 18
Joined: Sun Aug 31, 2014 10:08 pm
PIC experience: Experienced Hobbyist

Re: PIC10F322 AD Project in Assembly, RS232

Postby Olin Lathrop » Thu Sep 04, 2014 2:52 pm

MMcLaren wrote:I haven't come across a compelling or authoritative premise to support a conclusion that CBLOCK shouldn't be used in non-relocatable programs.

There are several issues here. There is nothing wrong with CBLOCK if used to create constants with sequential values. That can be useful and is what it's for.

The problem is when this facility of creating constants with sequential values is abused to make constants that are intended to be the addresses of memory locations. The assembler has no idea you will use the constants as if they represent "variables". Worse, those doing it often think they are "allocating variables". That's simply not true, and can lead to misunderstandings and other problems.

A common bug we see resulting from abuse of CBLOCK results from moving code to another chip even in the same general family. Many small PIC 16 start arbitrary RAM at address 20h, but the larger ones usually don't. Defining variable symbols with CBLOCK starting at the fixed value of 20h appears to work on the small chip, but then breaks without any error or warning on a related PIC.

Since CBLOCK doesn't actually allocate anything, there is no built-in mechanism to keep separate CBLOCKs from producing symbols with overlapping values. There is no way to say "give me 5 bytes in bank 1" inside a separate module, for example.

Since the assembler doesn't link CBLOCK constants to memory locations (why should it? That's not what it's there for), there is no mechanism to warn you when a bank is overflowed, you're stepping on SFRs, unimplemented memory, etc.

The only way in all of MPASM to actually allocate memory is by using the RES directive. All the problems I mentioned above go away. The assembler passes enough information to the linker so that any attempt to allocate the same location more than once results in a error. You can allocate variables at hard fixed locations if you really need to, you can allocate variables somewhere in a specific bank, or anywhere, depending on what you care about. If any of this results in overlaps or overflows of a bank or stepping on SFRs, you'll get a hard error. Multiple modules can each allocate variables without having to know where the last variable allocated by another module is. Again, overlaps and overflows are detected and result in errors.

Most of the time you use RES to allocate anywhere within a specific bank, or anywhere the linker can find space. It can be useful to know the bank of a variable at build time, but very rarely is there any advantage to knowing the exact address. If you are declaring a array that will be accessed only thru pointer registers, like the FSRs on a PIC 18, then you may not even care what bank it ends up in. You can communicate all these restrictions, or lack of restrictions, in the code, which alows the linker to optimize memory usage.

Long long ago (late 1990s if I remember right), there was no RES and linker. Really old code had no alternative but to use EQU or CBLOCK to define variable symbols. However, that hasn't been the case for at least 15 years, so there really is no excuse today.
User avatar
Olin Lathrop
Verified identity
 
Posts: 48
Joined: Fri May 30, 2014 3:38 pm
Location: Littleton, MA USA
PIC experience: Professional 5+ years with MCHP products

Re: PIC10F322 AD Project in Assembly, RS232

Postby drh » Thu Sep 04, 2014 3:32 pm

Tom,
I wasn't aware that this forum was for social engineering. I thought it was for PIC engineering. Wouldn't it be more appropriate for you to discuss YOUR problem with Olin via PMs?
User avatar
drh
Verified identity
 
Posts: 61
Joined: Tue May 27, 2014 3:31 pm
Location: Hemet, Calif.
PIC experience: Professional 5+ years with MCHP products

Re: PIC10F322 AD Project in Assembly, RS232

Postby Tom Maier » Thu Sep 04, 2014 3:53 pm

Public misbehavior directed at me gets a public reply.

The reason I tore into "dimebag" was because he was jerking ric around.

I hope this does come back to civil conversation. I didn't create this thread with the intention of it being used as a springboard for bad behavior.

I like reading what Olin is posting now. Things seem to have calmed down.

I have some residual "teacher" in me that wants to swat misbehavior. Must learn to accept that things can go to hell and it's not my problem. Just leave...
User avatar
Tom Maier
Verified identity
 
Posts: 179
Joined: Mon May 26, 2014 2:37 pm
PIC experience: Professional 5+ years with MCHP products

Re: PIC10F322 AD Project in Assembly, RS232

Postby MMcLaren » Sat Sep 06, 2014 11:13 am

Olin Lathrop wrote:
MMcLaren wrote:I haven't come across a compelling or authoritative premise to support a conclusion that CBLOCK shouldn't be used in non-relocatable programs.

The problem is when this facility of creating constants with sequential values is abused to make constants that are intended to be the addresses of memory locations. The assembler has no idea you will use the constants as if they represent "variables". Worse, those doing it often think they are "allocating variables". That's simply not true, and can lead to misunderstandings and other problems.

Basing a conclusion on a premise that suggests a feature or facility can be abused is a stretch. Asserting that those doing it think they are "allocating variables" pretty much dooms it. Suggesting that the assembler needs to know how you're using a constant in a non-relocatable (absolute) program is absurd (the assembler simply needs to know it's a constant).

A common bug we see resulting from abuse of CBLOCK results from moving code to another chip even in the same general family. Many small PIC 16 start arbitrary RAM at address 20h, but the larger ones usually don't. Defining variable symbols with CBLOCK starting at the fixed value of 20h appears to work on the small chip, but then breaks without any error or warning on a related PIC.

Gosh, how common is this bug? Do three out of four people fall victim to it? Or four out of five? Determining the location of data memory space is one of the first things I check when working with a new device. If this is a "common bug", am I an outlier (statistically speaking)? Of course your assertion is too vague and can neither be proven or assumed to be true.

Since CBLOCK doesn't actually allocate anything, there is no built-in mechanism to keep separate CBLOCKs from producing symbols with overlapping values. There is no way to say "give me 5 bytes in bank 1" inside a separate module, for example.

What's your point? If you need those capabilities you should use the RES directive and relocatable programs. Since we're discussing your criticism of the use of CBLOCK in non-relocatable (absolute) programs, this premise lacks context.

Since the assembler doesn't link CBLOCK constants to memory locations (why should it? That's not what it's there for), there is no mechanism to warn you when a bank is overflowed, you're stepping on SFRs, unimplemented memory, etc.

The Linker isn't used in non-relocatable (absolute) programs so why would anyone expect the assembler to link CBLOCK constants to memory locations and provide memory guard warnings. This is a stupid assertion.

The only way in all of MPASM to actually allocate memory is by using the RES directive. All the problems I mentioned above go away. The assembler passes enough information to the linker so that any attempt to allocate the same location more than once results in a error. You can allocate variables at hard fixed locations if you really need to, you can allocate variables somewhere in a specific bank, or anywhere, depending on what you care about. If any of this results in overlaps or overflows of a bank or stepping on SFRs, you'll get a hard error. Multiple modules can each allocate variables without having to know where the last variable allocated by another module is. Again, overlaps and overflows are detected and result in errors.

Surely you're not suggesting that the use of RES in non-relocatable (absolute) programs provides all these features without the Linker? That's impossible.

MMcLaren wrote:I haven't come across a compelling or authoritative premise to support a conclusion that CBLOCK shouldn't be used in non-relocatable programs.


I stand by my statement. Your premises are either out of context or lack anything more substantive than opinion. The use of CBLOCK in non-relocatable (absolute) programs is endorsed by Microchip as a perfectly acceptable method for associating labels with data memory addresses. Sure, it's not perfect, but suggesting the use of RES in a non-relocatable (absolute) program is idiotic. When using RES in a non-relocatable program the label is assumed to be a program memory address and none of the features you've described are available.
MMcLaren
 
Posts: 18
Joined: Sun Aug 31, 2014 10:08 pm
PIC experience: Experienced Hobbyist

Re: PIC10F322 AD Project in Assembly, RS232

Postby Olin Lathrop » Sat Sep 06, 2014 8:00 pm

MMcLaren wrote:The use of CBLOCK in non-relocatable (absolute) programs ...

But you shouldn't be using absolute mode either. Yes, if you use one archaic mode, then you're forced to use another archaic feature. The obvious answer is "so don't do that". As I said before, the linker has been around for at least 15 years. Back then, all you could do was use absolute mode and either EQU or CBLOCK to define symbols that you intended to use as variables. Today there is no excuse. Relocatable mode is a superset of absolute mode, so there is nothing you're giving up and a great deal to gain.

Your only argument against the advantages I listed for RES is that it doesn't work in absolute mode. Right, so don't use absolute mode, obviously. That is just as irresponsible as using CBLOCK to define symbols for variables, in part because then you can't use RES. Absolute mode is a ancient relic from a bygone era, and has no place today in responsibly written PIC code. In addition to giving you access to RES, relocatable mode also lets you write separate modules each with their own namespace for local symbols, guarantees that sections (basically modules) won't cross page boundaries, and doesn't make you manually allocate code to particular pages (unless you want to) with no warning when a page boundary is accidentally crossed.
User avatar
Olin Lathrop
Verified identity
 
Posts: 48
Joined: Fri May 30, 2014 3:38 pm
Location: Littleton, MA USA
PIC experience: Professional 5+ years with MCHP products

Re: PIC10F322 AD Project in Assembly, RS232

Postby MMcLaren » Sat Sep 06, 2014 9:22 pm

You're welcome to try again if you'd like, Olin. Here's the original post that I assumed you were trying to argue;

MMcLaren wrote:I haven't come across a compelling or authoritative premise to support a conclusion that CBLOCK shouldn't be used in non-relocatable programs.


If you're trying to argue something in a context other than that in the statement above, I'm not interested, thank you.
Last edited by MMcLaren on Sat Sep 06, 2014 9:24 pm, edited 1 time in total.
MMcLaren
 
Posts: 18
Joined: Sun Aug 31, 2014 10:08 pm
PIC experience: Experienced Hobbyist

PreviousNext

Return to 12-Bit Core

Who is online

Users browsing this forum: No registered users and 4 guests

cron