OT: MPLAB build dies (linker prob)

Here is part of the code: ORG 0x0B00 tab3: MOVLW High(tab3_data) ADDWF timhi,W MOVWF PCLATH MOVLW Low(tab3_data) ADDWF timlo,W BTFSC STATUS,C INCF PCLATH,F MOVWF PCL ; computed GOTO into data ; ------------------ tab3_data: ;; at 0x0B08 FILL 0x34F6, 0x0F07 - $ + 1 ; ---------------------------------------------- ORG 0x1000 ; PAGE 0-4095 allowed by assembler/linker tab4: MOVLW High(tab4_data) ADDWF timhi,W MOVWF PCLATH MOVLW Low(tab4_data) ADDWF timlo,W BTFSC STATUS,C INCF PCLATH,F MOVWF PCL ; computed GOTO into data ; ------------------ tab4_data: ;; at 0x1008 FILL 0x34F5, 0x1407 - $ + 1 ; ---------------------------------------------- ORG 0x1500 tab5: MOVLW High(tab5_data) ADDWF timhi,W MOVWF PCLATH MOVLW Low(tab5_data) ADDWF timlo,W BTFSC STATUS,C INCF PCLATH,F MOVWF PCL ; computed GOTO into data ; ------------------ tab5_data: ;; at 0x1508 FILL 0x34F5, 0x1907 - $ + 1 ; ---------------------------------------------- ; BALANCE DEFAULT 0x3FFF END

** The assembled code is OK, see NO errors. The only clue beyond the fact that the build barfs, is the *.map file: MPLINK 4.39, Linker Linker Error Map File - Created Fri Oct 23 20:25:02 2015

*Warning* - This is only a partial map file due to a link time error. Only sections which were allocated prior to the error are shown below.

CODEPAGES: Memory Start End Section Address Size(Bytes)

------- ------ ------ ------- ------- --------- page 0x0000 0x0fff .org_0 0x0000 0x0000 .org_1 0x0000 0x0008 .org_2 0x0010 0x0056 .org_3 0x0100 0x0810 .org_4 0x0600 0x0810 .org_5 0x0b00 0x0812

** END COPY

Therefore, there is a severe page range problem that needs fixing. How? (thanks in advance)

Reply to
Robert Baer
Loading thread data ...

ORG 0x0B00 tab3: MOVLW High(tab3_data) ADDWF timhi,W MOVWF PCLATH MOVLW Low(tab3_data) ADDWF timlo,W BTFSC STATUS,C INCF PCLATH,F MOVWF PCL ; computed GOTO into data ; ------------------ tab3_data: ;; at 0x0B08 FILL 0x34F6, 0x0F07 - $ + 1 ; ---------------------------------------------- ORG 0x1000 ; PAGE 0-4095 allowed by assembler/linker tab4: MOVLW High(tab4_data) ADDWF timhi,W MOVWF PCLATH MOVLW Low(tab4_data) ADDWF timlo,W BTFSC STATUS,C INCF PCLATH,F MOVWF PCL ; computed GOTO into data ; ------------------ tab4_data: ;; at 0x1008 FILL 0x34F5, 0x1407 - $ + 1 ; ---------------------------------------------- ORG 0x1500 tab5: MOVLW High(tab5_data) ADDWF timhi,W MOVWF PCLATH MOVLW Low(tab5_data) ADDWF timlo,W BTFSC STATUS,C INCF PCLATH,F MOVWF PCL ; computed GOTO into data ; ------------------ tab5_data: ;; at 0x1508 FILL 0x34F5, 0x1907 - $ + 1 ; ---------------------------------------------- ; BALANCE DEFAULT 0x3FFF END

**

CODEPAGES: Memory Start End Section Address Size(Bytes)

------- ------ ------ ------- ------- --------- page 0x0000 0x0fff .org_0 0x0000 0x0000 .org_1 0x0000 0x0008 .org_2 0x0010 0x0056 .org_3 0x0100 0x0810 .org_4 0x0600 0x0810 .org_5 0x0b00 0x0812

** END COPY
4.33.1 Syntax [label] fill expr,count 4.33.2 Description Generates count occurrences of the program word or byte (PIC18 devices), expr. If bounded by parentheses, expr can be an assembler instruction. 4.33.3 Usage This directive is used in the following types of code: absolute or relocatable. For information on types of code, see Section 1.6 ?Assembler Operation?. This directive is often used to force known data into unused program memory. This helps ensure that if code ever branches to an unused area at run time, a fail-safe condition occurs. For example, it is not uncommon to see this used with the watchdog timer (WDT) on a PIC16 device. Unused program memory would be filled with goto or branch instructions to prevent execution of the clrwdt instruction in code, which would cause the device to reset. See the device data sheet for more information on the WDT. 4.33.4 See Also data dw org 4.33.5 Simple Examples Example 1: PIC10/12/16 MCU?s fill 0x1009, 5 ; fill with a constant fill (GOTO RESET_VECTOR), NEXT_BLOCK-$

See:

formatting link

I only use assembler for really small programs, or for special cases where I need to absolutely control the code location and implementation. It's really much easier to use C, and there are some low-cost compilers you can use.

Paul

Reply to
P E Schoen

tab5_data: ;; at 0x1508 FILL 0x34F5, 0x1907 - $ + 1 ; ---------------------------------------------- ; BALANCE DEFAULT 0x3FFF END

If you are still using the PIC16F648A you have only 4k or 4096 words (14 bits) of flash memory, which ends at 0xfff. Your last tab5 data starts beyond the physical memory at 0x1508 and extends an additional 0x1907 to an end address of 2E0F. A memory with addresses to 3FFF would be 16k.

Again, please let us know what you are trying to do.

HTH

Paul

Reply to
P E Schoen

It seems to me that he's attempting to push the fifth elephant into a VW Beetle. He's been predestined to use a PIC which is far too small for teh waveforms he's trying to generate.

--

-TV
Reply to
Tauno Voipio

NOPE:

1) Note linker states "page 0x0000 0x0fff" 2) Note all other FILLs before ORG 0X1000 work properly with linker. 3) Delete all lines after the ORG 0x1000 and add only one code/data line, then END. SAME barf problem.
Reply to
Robert Baer

Did you include the correct linker file in MPLAB? There are usually two for each device, one debug and one release. You normally set the ram pages not rom pages.

But you are declaring large tables that excede the rom size.

Cheers

Reply to
Martin Riddle

Would like to have 5 tables filled with 1K RETLW . To linearly access using a pointer from 0 to 1023, one needs at least

8 instructions for a call (or equivalent after a call to them).

I guess, after subtracting out necessary code space from 4096 locations, i might have 3840 locations or so. That would leave me 768 data points per table,which is better than a kick in the head.

If i assume i can have 3900 locations for data, that gives me 780 data points per data table; add 8 each for code in the tables would take

3940 leaving 156 locations for other support code.

Possible...

Reply to
Robert Baer

Consider the fact that you have only 8 bits for waveform amplitude, so only

256 possible values. For a sine table, the values for 85 degrees to 95 degrees are 0.996 to 1.000, which vary only from 254 to 255. So, assuming that the table will be used for a repeating pattern, you would need at most 256 data points. You could construct a two-element table with one value for degrees and the other for amplitude. This could be done with 3*256 = 768 bytes, like this:

Table: movlw 0 ;0 degrees movwf deg ;degrees retlw 0 ;Sin (0) movlw 1 ;1 degrees movwf deg ;degrees retlw 4 ;Sin (1) ... movlw 85 ;85 degrees movwf deg retlw d'254' movlw 90 ;90 degrees movwf deg retlw d'255'

Notice that the lower part of the table shows a significant difference in value for the minimum angle of 1 degree. But at 85 degrees, the next significant change is at 90. Thus, for a sine table, where you really need only values from 0 to 90, you can implement the look-up in less than

90*3=270 bytes. And you could probably do the full 360 degrees by converting the angle to an 8 bit value where 360 = 0xff and 0x01 is actually 360/255= 1.41 degrees which happens to have a sine of 0.024 or an 8 bit representation of 0x06.

The problem with a table like this is that you must first search for the angle by successive approximation, and then choose an angle that is closest to what you seek. And you must increment the call location by 3 for each table entry.

If the waveform you are trying to approximate is fairly smooth, you might get by with an ordinary look-up table for every five degrees, and use linear interpolation between data points. For a sine table, suppose you want the value at 3 degrees. The sin(0) is 0x00 and sin(5) is 0.087 or d'22'. The interpolated value for sin(3) is (3/5)*(22-0) or 13, which corresponds to

0.0510, while the actual sin(3) = 0.0523. The error is less than 1 bit for an 8 bit amplitude value.

HTH,

Paul

Reply to
P E Schoen

Do you need all 12bits in each word? if not, you could condense the table space by bit stuffing. You would need to calculate the index of course to get the correct starting index word and bit group with in that word, that would give you more space.

Just a thought really...

Jamie

Reply to
M Philbrook

Thanks for the doc reference.

Has erroneous info. See page 82 (PDF P.90) 4.33.2 "If bounded by parentheses, expr can be an assembler instruction.". Does not work as one would like: FILL (RETLW 0xA5), 7 only emits the RETLW and noting more, treating the 0xA5 as a blank (count is OK). Try variants and get nowhere; gotta use the hex code for it all: 0x34A5.

Reply to
Robert Baer

Well, for sin/cos one needs only the first 22.5 degrees; all else in the circle can easily be derived from that.

And we are going to use arbitrary waveforms; the sin/triangle/square were for test purposes.

Reply to
Robert Baer

Yes, but.. How would one go about reading one or two "random" locations?

Reply to
Robert Baer

Seems like you are using the wrong choice of chip then since your lookup table is already larger than available program memory.

Choices are either 3x 1024 or a different PIC with more code space.

You need to have one routine to access the table(s) efficiently and possibly a routine to return the next sample very efficiently.

You shouldn't be reading random locations if you are doing an arbirary waveform generator - the next sample is deterministic.

--
Regards, 
Martin Brown
Reply to
Martin Brown

That is very true. The processor that has been for some reason pre-chosen does not have the ability to read its own code space, so a table look-up is the only way to do it. The calling routine can increment the address to get sequential reads of 8 bit waveform data which presumably would wrap around at some number of samples to produce a recurrent pattern, or perhaps this is meant only to produce a burst of a certain period of time.

The calling routine gets the amplitude value in the W register, and then there must be some way to produce an analog signal from this value. The most common method for a PIC is PWM, and the 16F648A has a 10 bit PWM module, although only 8 bits are available. Depending on the frequency of the generated waveform (or time between transitions), there needs to be a carrier PWM frequency selected which might further limit the resolution to less than 8 bits. The PWM output will need to be filtered to remove most of the carrier frequency components but also allow faithful reproduction of the waveform transitions.

A better way to implement an arbitrary waveform generator may be by means of an EEPROM and a DAC, as well as a binary counter to select sequential addresses for the waveform. The processor can supply the clock signal to determine the frequency, and a reset line to adjust the phase.

Paul

Reply to
P E Schoen

For one thing, the PIC16F648A has 4096 words of 14 bits, or 57344 bits. It would be possible to format the first word with 8 bits + 6 of the next, and the second word would have the 2 remaining bits, plus 8, plus 4 of the next. Thus the raw memory could hold 7168 8-bit bytes of data, and each of the four blocks of 1024 words could hold 1792 bytes. But the PIC has no internal mechanism to read any more than 8 bits of each word, and it can do so only by means of the RETLW operation.

The PIC16F1829, also 20 pins, has 8k words, and tables in ROM can also be read by using the FSR and INDF registers, but still only the lower 8 bits, so nothing is gained. However, this device has the capability of reading from and writing to flash memory, accessing all 14 bits. So you could transfer data one or more blocks at a time into RAM space, and use that for fast sequential access of waveform data. But Flash and EEPROM data access is a slow process, so it might mess up the continuity of waveform generation unless you have a means of direct memory access (DMA).

It may be advantageous to use SPI or I2C with a MicroSIM card where megabytes and even gigabytes of waveform data can be stored, and easily swapped out and programmed on a PC or other external device.

Paul

Reply to
P E Schoen

There's nothing random about it.

Lets assume for the moment you have 1024 WORDS of 12 bits each. with your aprouch you only get to use 1024 bytes, this is assuming that you are using byte size values.

THat leaves you with 4 bits per WORD not being used.

you can achieve 50% more bytes if you were to make use of the extra 4 bits per WORD.

TotalBits = 1024 * 12 = 12288 bits.

Because the PIC is a rather underpowered chip to do the math a larger one can do, you need to take a different step in using those extra 4 bits per WORD and not take lots of clock time to do it.

So, the first 1024 can be handled as a direct index however, anything over 1024 you would subtract the base "1024" take the remainder*2. This index puts you on a WORD where you extract the MSBits (4 of them) and step forward once to also get the upper MSBits to form a Byte. You would need to preformat the data table of course to do this, which could be done in a simple PC tool spread sheet etc..

Jamie

Reply to
M Philbrook

I have not worked with an older PiC in years, I was only throwing some number theories out there, since I've done such coding elsewhere..

I know about the 8 bit thing but I thought there was a shift function to move the upper bits down ?

I anycase, the idea was to read the table from ROM not memory, but you claim that is a slow process? I seem to remember something like that once that needed a coefficient table and I don't remember having issues reading from ROM during program run.

Jamie

Reply to
M Philbrook

I'm curious why you post this here rather than in the comp.arch.embedded group. I'd bet there are a lot more users there than here.

--

Rick
Reply to
rickman

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.