The Jallib device files are generated by means of a Rexx script 'dev2jal'.
Its name as an abbreviation of 'MPLAB .dev to .jal' because it uses the .dev
files of the MPLAB-IDE to create the Jallib device files.
Notes:
The advantages of automated generation of device files are pretty obvious, such as:
The advantages of a consistent naming convention are also obvious:
This document gives some design information and some instructions for the use of these JalV2 device files. The sources of information are the xxxx.dev files and xxxx.lkr of MPLAB, supplemented and corrected with information from the datasheets.
With the design of the device files I had in mind a structure as shown below.
+----------+ +------------------+ | device | | general | | specific |---| include | | include | |chipdef_jallib.jal| +----------+ +------------------+ | +--------------+--------------+-------------+----------- | | | | +----------+ +----------+ +----------+ +----------+ | function | | function | | function | | function | | include | | include | | include | | include | etc | 'delay' | | 'jal' | |'adc.....'| |'pwm....' | +----------+ +----------+ +----------+ +----------+
These device files are now part of the central JalV2 library repository Jallib at GoogleCode, which uses the same structure.
The device files are the base for other include files and contain:
Including a device file doesn't change anything to the PIC. For example pins which are input after power-on or reset remain input, etc. Required changes are the responsibility of the application program or function libraries. For user convenience every device file contains a procedure to disable all analog modules of the PIC and to change all pins which are by default analog to digital I/O: enable_digital_io().
The defaults for the configuration bits may be slightly different than their specifications in the datasheet. You can find the default configuration bits settings in the top of the device file.
The file 'chipdef_jallib.jal' which comes with these device files replaces the file 'chipdef.jal' which comes with the compiler distribution. It is included by each of the device files and contains:
With the statement 'pragma target chip = .....' in every device file the compiler assigns a unique value to the variable 'target_chip'. The program may reference this variable with a symbolic name. This symbolic name consists of 'pic_' followed by the type of the PIC, which makes it possible to use the same source file to generate a hex file for different types of PICs, as the following example shows:
include 16f88 if (target_chip == PIC_16F88) then -- (not for 16f87) .... -- 16F88 unique code end if
By changing the include statement to 16f87 (or any other) the statements between 'if' and 'end if' will be skipped by the compiler.
The list of targets in chipdef_jallib.jal makes sure that every possible target name and the corresponding value of target_chip is known by the compiler.
Note: The original chipdef.jal file of the compiler package specifies a different value for 'target_chip' and not for all PIC types. Therefore it had to be replaced when using this set of device files.
Function specific include files offer facilities to ease the use of PIC peripherals (such as USART, ADC), external devices (such as LCDs, sensors), or extensions to the Jal language such as for data formatting, mathematical functions, etc.
Function specific include files should be included explicitly as required by the application program, this is not done by the device files.
In most cases the function include files require some statements to couple function specific registers and pins with the device. Read the comments in the library sources and the library documentation for instructions. Most libraries contain comments with user instructions in the header of include files and just ahead of the procedures and functions in these files.
We'll start with a very elementary sample program (blink-a-led) to show how device files make programming in JAL a piece of cake, followed by a description of other features of the device files which are aimed at writing device independent libraries.
The device files define static device (PICmicro) specific matter. This allows writing elementary programs, such as for a blinking led, which are almost device independent. Differences are mostly in the fuse settings.
The device files are also the base for extensions, such as libraries for more complicated functions like displaying text on an LCD display or handling analog devices.
Below a simple blink-a-led program (led on pin 1 of port A) for a PIC16F886 using a 20 MHz resonator. In addition to the device-specific information obtained from the include file '16f886.jal' some run-time information is needed, like the speed and type of the oscillator and some other 'environmental' variables. No extra function libraries are required.
-- ------ blink-a-led on pin_A1 of a PIC16F886 -------- include 16f886 -- target is a PIC16F886 -- Notes: - The extension .jal is -- added by the compiler! -- - No other includes needed. pragma target clock 20_000_000 -- oscillator frequency (in Hz) -- required for delays pragma target OSC HS -- high speed external oscillator pragma target WDT Disabled -- watchdog off pragma target MCLR External -- external chip reset pragma target LVP Disabled -- no low voltage programming enable_digital_io() -- set all pins to digital I/O alias led is pin_A1 -- declare alias for pin_A1 alias led_direction is pin_A1_direction -- and for its direction led_direction = output -- make led-pin output forever loop -- endless loop led = on -- there is light! _usec_delay(250000) -- spin 1/4 seconds led = off -- flip (on->off,off->on) _usec_delay(250000) -- spin 1/4 seconds end loopWhen loaded in a 16F886 with 20 MHz resonator or crystal a led connected (with series resistor!) to pin 3 (RA1) should blink twice a second.
Unfortunately MPLAB of Microchip is not particularly consistent in its choice of names! The datasheets and the various informational files in MPLAB not infrequently use different names for the same entity! As a rule the device files use the names as used by the datasheets. However the device files have been generated from the MPLAB information files, not from the datasheets! So it is possible that some names may not be conform to the datasheet. When you find such a deviation not mentioned in this document, please report to the Jallib team, and most likely the next release will contain the corrected name.
For all registers of the chip a name is declared and where appropriate
also the individual bits or groups of bits are declared.
Subfields of registers have the name of the register as prefix, like
var volatile bit INTCON_GIE at INTCON : 7Some aliases are declared for easy migration or conversion of existing JalV2 libraries and programs to the Jallib environment.
There are exceptions to the rules above.
The aim of 'normalization' (using a consistent naming) is:
For all ports and port pins a device independent alias is declared and a similar direction declaration, as the following examples show:
var volatile byte PORTA at <addr> var volatile byte TRISA at <addr> var volatile byte PORTA_direction at TRISA var volatile bit pin_A0 at PORTA : 0 var volatile bit pin_A0_direction at TRISA : 0etc. (for all other existing pins and ports)
Although the smaller PICs have no 'official' PORTA and TRISA registers, the device files contain aliases for these. So even with the smaller PICs you can use the names PORTA, pin_A0, etc.
var volatile byte GPIO at <addr> var volatile byte PORTA at GPIO var volatile byte TRISIO at <addr> var volatile byte TRISA at TRISIO var volatile byte PORTA_direction at TRISIO var volatile bit pin_A0 at GPIO : 0 var volatile bit pin_A0_direction at TRISIO : 0etc. (for all other existing pins)
Pins which can be input-only may have no corresponding _direction variable, for example pin_E3 of the 18F4550.
Because the upper and lower 4 bits ('nibble') of a port are used frequently as a unit, these are declared as pseudo variables.
PORTx_low - bits 0..3 (low order bits) PORTx_high - bits 4..7 (high order bits) PORTx_low_direction PORTx_high_directionThis allows nibbles to be used as a regular variables, and can also be used to set pin directions by 4 at a time:
PORTA_high = "7" -- low nibble remains unchanged PORTA_low_direction = all_output -- direction upper nibble unchangedSeveral function libraries in the Jallib collection use this facility.
Note: Nibbles are always declared even if the register doesn't have the nibble fully populated, or even not populated at all!
When a pin is multiplexed (has a different function depending on
control registers or configuration bit settings), aliases are declared
to make the pin accessible by a more functional name.
For example: of the 16F88 pin_B6 is usable as analog input for the ADC
module as channel 5 and therefore pin_B6 has been given an alias name
pin_AN5.
You can find the 'AN5' name with the pin layout pictures and tables in the
datasheet.
Of course also for the pin_B6_direction an alias is declared and
called similarly pin_AN5_direction!
Libraries (for this example the ADC library) will use the alias
names in stead of the physical pin names.
Another PIC may have pin_AN5 associated with a different physical pin,
but by using the alias name the ADC library becomes indenpent of the
physical pin configuration
and and makes it to a large extent device independent.
If you want to use another name for a port, nibble or individual pin you can also specify an alias in your program. For example when you have a red led connected to pin 0 of PortA, you could specify:
alias led_red is pin_A0and use 'led_red = on' or 'led_red = off' assignments in your program.
Pin aliases in the device files are declared in this
way and therefore also make use of the port shadowing provided by
the device files.
This way of aliasing - using the keyword 'alias' - is only
available since JalV2 compiler version 2.4n.
You should avoid direct pin and I/O port manipulation, because it will be overruled by the automatic shadowing mechanism (see the chapter about Shadowing). For example do not specify:
var bit led_red at portA : 0With this specification a 'led-red = on' will have the desired result, but it will not update the shadow register. Any next operation which uses the shadowing mechanism will override the previous direct control operation.
Some pin alias names are not acceptable for the JalV2 compiler, in which case a special name is used. For example PICs with USB support have a D+ and D- pin. These are declared (for the 18F4550) as:
alias pin_D_POS is pin_C5 alias pin_D_NEG is pin_C4
Some function pins can be on one or another pin of a PIC, controlled by a register or a configuration bit setting. In these cases the name has to be suffixed to prevent duplicate names. The 16F737 for example can have the CCP2 bit on pin_B3 or pin_C1, controlled by a configuration bit (fuse_def CCP2MUX).
alias pin_CCP2_RB3 is pin_B3 alias pin_CCP2_RC1 is pin_C1The program or library has to detect the actual use of the CCP2 pin.
Some high end 18Fs have an even more complex multiplexing mode. With the 18F8310 for example the multiplexing depends also on the processor mode. One position of CCP2 is pin_C1, the alternate pin is pin_E7 (in Microcontroller mode) or pin_B3 (in Microprocessor, Extended Microcontroller and Microcontroller with Boot Block modes). This variant is not always available in the current device files!
Some PICs, mainly in the baseline series are missing some addressable ('memory mapped') Special Function Registers (SFRs). For example the 12-bit core PICs (10Fs, 12F5x, etc) have no memory mapped TRISx registers, in stead these PICs have a TRISx instruction to set the direction of ports or pins. This would make it impossible for function libraries and application programs to use statements like:
PORTA_direction = all_outputTo make this possible the device files contain pseudo variables which mimic the existence of memory mapped registers.
For example even though a 16F59 has no addressable TRISC register, you can still specify:
pin_C5_direction = output
Some PICs of the 18F series have SFRs which are only accessible when
the ADSHR bit in WDTCON is set (when not set a different SFR is accessed).
For example with the 18F65J50 ADCON0 and ANCON1 share address FC2h.
When the ADSHR bit of WDTCON is reset (0) ADCON0 is accessed,
when the ADSHR bit is set (1) ANCON1 is accessed.
The device files will do this automatically with the help of pseudo
variables.
For example when ANCON1 is used in a JALV2 statement the ADSHR bit is set
automatically (and reset afterwards).
Names of registers of MSSP modules have been normalized as follows:
SSPADD SSPBUF SSPCON -- first or only control register SSPCON2 -- second control register (if present) SSPSTAT
SSP1ADD SSP1BUF SSP1CON -- first or only control register SSP1CON2 -- second control register (if present) SSP1MASK SSP1STAT
SSP2ADD SSP2BUF SSP2CON -- control register second module SSP2CON2 -- second control register (if present) SSP2STAT
In many cases the first SSP module (SSP1) of the 18Fs can be used in the same way as the SSP module of a midrange PIC. For this purpose the following aliases are declared for registers of the first SSP module in the devicefiles of the 18F PICs:
field | alias | remarks |
---|---|---|
SSP1CON | SSPCON | |
SSP1CON2 | SSPCON2 | when present |
SSP1STAT | SSPSTAT | |
SSP1BUF | SSPBUF | |
SSP1MSK | SSPMSK | when present |
All subfields of these registers have a similar alias (the register prefix is changed, the subfield name kept asis).
There are CCP modules and Enhanced CCP modules. The first is also called 'legacy' CPP modules in this document and elsewhere. Most legacy CCP modules have registers names starting with CCP, most registers of enhanced CCP modules start with ECCP. The same is true for subfields of these registers. However there are many deviations from these rules and contradictions between MPLAB .dev files and the datasheets!
Enhanced CCP modules can be used as legacy CCP modules, in particular for PWM operations. For this purpose a number aliases are added to the device files which allow access of enhanced CCP registers and subfields with legacy names. An example of this is the pwm_hardware library.
The following aliases for enhanced CCP modules are declared:
field | alias | remarks |
---|---|---|
ECCPxCON | CCPxCON | x in range 1..10 |
ECCPxCON_EDCxB | CCPxCON_DCxB | bits*2 |
ECCPxCON_ECCPxM | CCPxCON_CCPxM | bits*4 |
ECCPRx | CCPRx | |
ECCPRxH | CCPRxH | |
ECCPRxL | CCPRxL |
Extended midrange PICs (12/16F18/19xx) have only enhanced CCP modules which have 'legacy' names. Therefore no special naming is needed to use these as legacy CCP modules.
For PICs with both an CCP1CON and a ECCP1CON register (18f448,4480,458,4580,4585,4680,4682,4685) to allow the enhanced CCP module to be used as second legacy CCP module the following aliases are declared:
field | alias | remarks |
---|---|---|
ECCP1CON | CCP2CON | |
ECCP1CON_EDC1B | CCP2CON_DC2B | |
ECCP1CON_ECCP1M | CCP2CON_CCP2M | |
ECCPR1 | CCPR2 | |
ECCPR1H | CCPR2H | |
ECCPR1L | CCPR2L |
Some PICs (16F91x,946, 18F2321,2480,2580,4321,4480,4580) have the CCPxCON 2-bits subfield DCxB defined as 2 separate bits CCPxX and CCPxY, other PICs (16F88x) have this field enumerated and defined as DCxB1 and DCxB0. For compatibility with most other PICs a 2 bits field CCPxCON_DCxB has been added in the device files for these cases.
For the control of the ADC channel the ADC library has to set the appropriate pin(s) to analog (input). There are generally 3 methods used by the different PICs:
The first two methods as covered by the ADC libraries, this section is about the third method with ANSEL register(s). There are a couple of issues with this method:
The first item is no problem when always referring to the logical pin
name pin_ANx (an alias of the physical pin name).
A solution for the second item has been found by declaring aliases for the
channel selection bits in ANSEL registers (name normalization).
In stead of enumerating the bits of all ANSELx registers individually, a
number of bit aliases 'JANSEL_ANSx' is declared, in which 'x' represents
the ADC channel and which point to the appropriate AN-pin.
For example the declaration of the JANSEL bits of a 16F722 looks like:
var volatile byte ANSELA at { 0x185 } var volatile bit JANSEL_ANS4 at ANSELA : 5 -- pin_AN4 = pin_A5 var volatile bit JANSEL_ANS3 at ANSELA : 3 -- pin_AN3 = pin_A3 var volatile bit JANSEL_ANS2 at ANSELA : 2 -- pin_AN2 = pin_A2 var volatile bit JANSEL_ANS1 at ANSELA : 1 -- pin_AN1 = pin_A1 var volatile bit JANSEL_ANS0 at ANSELA : 0 -- pin_AN0 = pin_A0 -- ------------------------------------------------- var volatile byte ANSELB at { 0x186 } var volatile bit JANSEL_ANS13 at ANSELB : 5 -- pin_AN13 = pin_B5 var volatile bit JANSEL_ANS11 at ANSELB : 4 -- pin_AN11 = pin_B4 var volatile bit JANSEL_ANS9 at ANSELB : 3 -- pin_AN9 = pin_B3 var volatile bit JANSEL_ANS8 at ANSELB : 2 -- pin_AN8 = pin_B2 var volatile bit JANSEL_ANS10 at ANSELB : 1 -- pin_AN10 = pin_B1 var volatile bit JANSEL_ANS12 at ANSELB : 0 -- pin_AN12 = pin_B0As you can see the JANSEL_ANSx numbering is not restricted to bits 0..7 of the first ANSEL register (whatever its name), it is also used for channel numbers higher than 7 controlled by another ANSEL register. Note further that:
Other PICs, like for example the 18F43K22, have 28 ADC channels spread over 5 ANSEL registers, also largely irregularly numbered. For example pin_AN5..7 are controlled by ANSELE. The declaration of JANSEL_ANS0..27 hides all these irregularities from the ADC library.
Another example, now for the 10F222:
var volatile byte ADCON0 at { 0x7 } var volatile bit JANSEL_ANS1 at ADCON0 : 7 var volatile bit JANSEL_ANS0 at ADCON0 : 6In this case the channel selection bits are in register ADCON0 (the 10Fs have no ANSEL register), but the ADC library doesn't need to know when it uses the JANSEL_ANSx alias.
Names of registers and subfields of ADC modules have been normalized as follows:
When the ADCONx_VCFG subfield is a multi-bit field it is declared both as a multi-bit field ADCONx_VCFG and as enumerated bits (ADCONx_VCFG0 and ADCONx_VCFG1).
While most PICS with more than 8 ADC channels have a 4-bits subfield ADCONx_CHS, some PICs have the channel selection bits scattered over more than 1 subfield. For example the 16F7x7s have a 3-bits CHS field plus a single CHS3 bit to be able to support channel 8 and up. In this and similar cases a pseudo variable ADCONx_CHS has been declared which takes care of the scattering of channel selection bits. So an ADC library can always address the variable ADCONx_CHS as multibit 'binary' field, regardless if the bits are scattered over the register or not.
PICs can have zero, one or two USART modules, of which zero, one or both can be 'extended' (EUSART) modules. Compared to a 'legacy' USART an 'extended' USART has a BAUDCON register and can use a 16 bits in stead of an 8-bits value for the baudrate divisor, allowing a more accurate baudrate setting, especially at high speeds.
The names of USART related registers and -subfields are not particular constent in the MPLAB .dev files, so it is desired to normalize these. And it would be convenient if serial libraries supporting a single serial interface could be used one of both USARTs of PICs with two USARTs. These are the primary reasons for the following naming convention in the Jallib device files:
Application of these rules results in the following list of names:
single USART | first of 2 USARTs | second of 2 USARTs |
---|---|---|
BAUDCON | BAUDCON1 BAUDCON (alias) | BAUDCON2 |
BAUDCTL | BAUDCTL1 BAUDCTL (alias) | BAUDCTL2 |
RCREG | RCREG1 RCREG (alias) | RCREG2 |
RCSTA | RCSTA1 RCSTA (alias) | RCSTA2 |
SPBRG | SPBRG1 SPBRG (alias) | SPBRG2 |
SPBRGH | SPBRGH1 SPBRGH (alias) | SPBRGH2 |
TXREG | TXREG1 TXREG (alias) | TXREG2 |
TXSTA | TXSTA1 TXSTA (alias) | TXSTA2 |
PIE1_RCIE | PIE1_RC1IE PIE1_RCIE (alias) | PIE3_RC2IE |
PIE1_TXIE | PIE1_TX1IE PIE1_TXIE (alias) | PIE3_TX2IE |
PIR1_RCIF | PIR1_RC1IF PIR1_RCIF (alias) | PIR3_RC2IF |
PIR1_TXIF | PIR1_TX1IF PIR1_TXIF (alias) | PIR3_TX2IF |
Notes:
With these names serial libaries or application programs supporting only a single serial interface can use the register and field names without suffix for the only USART or the first of two USARTs. Libraries supporting two serial interfaces will preferrably use the qualified names (with suffix).
Some register subfields of timer control registers have inconsistent names in the MPLAB .dev files.
For these subfields the following naming convention has been chosen:
For consistency with the ALRMCFG register and since the RTCPTR1 - and RTCPTR0 bits of the RTCCFG register could be used as 2-bits binary field - an additional field is declared:
var volatile bit*2 RTCCFG_RTCPTR at RTCCFG : 0Same for the RTSECSEL1 and RTSECSEL0 bits of PADCFG1:
var volatile bit*2 PADCFG1_RTSECSEL at PADCFG1 : 1For consistency the 2-bits ALRMCFG_ALRMPRT field has been enumerated:
var volatile bit ALRMCFG_ALRMPTR1 at ALRMCFG : 1 var volatile bit ALRMCFG_ALRMPTR0 at ALRMCFG : 0
The shadow of the STATUS register (in the extended midrange PICs) has its bits named like in the STATUS register:
STATUS_SHAD_Z STATUS_SHAD_DC STATUS_SHAD_C
Port shadowing is a technique to prevent the Read-Modify-Write ('RMW') problem with I/O ports of PICmicro's. This is a problem related to its hardware design. Search the Internet for "PIC" and "read-modify-read" and you'll get many hits to more or less interesting articles! None of the explanations are repeated here. And you don't absolutely need to understand the problem, since by using the Jallib device files you won't face the problem when you follow some simple rules and avoid a few pitfalls.
With port shadowing for the baseline and midrange PICs (10F, 12F, 16F) a RAM location is used as replacement for the port for output.
The 18F series have a special register for this purpose (LATx). Although the techniques are slightly different, the general rules are: reading is done from the port directly while writing is done to the shadow register of which the contents is subsequently passed to the real port.
With the Jallib device files shadowing is automatic, as long as you use the following names:
PORTx -- all bits of port x PORTx_low -- low order nibble of port x (bits 3..0) PORTx_high -- high order nibble of port x (bits 7..4) pin_xy -- single bit 'y' of port 'x'(in which 'x' is a port-letter and 'y' a bit number).
Note: The value for both Portx_low and Portx_high is passed with reading from (and must be passed with writing to) in the lower nibble (bits 3..0) of a constant or variable. Portx_low is read from or written to bits 3..0 of Portx, Portx_high is read from or written to bits 7..4 of Portx.
A number of low end PICS have a reserved word in high memory, provided by the manufacturer, which contains information for calibration of the internal oscillator. When your PIC application needs the frequency of the internal oscillator to be accurate the OSCCAL register should be loaded with the provided value. This is not done automatically by compiler or device files. You may want to insert the following statements into the beginning of your program:
assembler page call <end-of-memory> bank movwf OSCCAL end assemblerIn which you have to specify for <end-of-memory> the offset of the highest program memory word (see the appropriate dataset). For example when your PIC has 1K words of program memory you should specify 0x3FF.
When the factory value is not correct or has been accidentally erased by a PIC programmer, you may also move your own value into OSCCAL, for example:
OSCCAL = <value>See the datasheet for acceptable values: frequently the low order bits should be zero.
The MPLAB .dev files contain a keyword for every configuration bit or group of bits, and a description of the possible bit settings. Unfortunately not always the same keyword is used for essentially the same configuration bit or bit-field, and the keyword is sometimes different from the keyword in the datasheet, or is simply spelled wrongly! The descriptions have an even larger variation and are sometimes very long.
For use with Jal, in particular for the 'pragma fuse_def' declarations, a consistent keyword (in JalV2 called 'opt') and single-word symbolic values (in JalV2 called 'tag') are desired. The Jallib 'standard' is described below.
For all pragma fuse_defs a keyword and a number of symbolic values are declared in the device files. This section deals with the keywords, the next section with symbolic values.
Every configuration word or byte is preceeded with a comment line
indicating its address in memory.
The meaning of configuration bits can in most cases be found in the
DataSheet of the specific chip, in the section 'Special Features of the
CPU'.
This info can also be found in the Programming Specifications of the chip.
For convenience the MicroChip document numbers of the specific PIC are
mentioned in the heading of its device file.
To minimize misunderstanding and confusion the description for every keyword as found in the MPLAB .dev file is appended as comment on the 'pragma fuse_def' line. The combination of memory address and description should unambiguously identify which configuration bits are controlled by the keyword, even though the name might be different from that in the datasheet.
Where convenient and intuitive enough the keywords found in the MPLAB .dev files are used. But synonyms are eliminated and some apparent misspellings are corrected. Sometimes an arbitrary keyword is chosen.
The list below shows examples of most deviations of keywords from MPLAB .dev files:
keyword | replaces synonym(s) and typo(s) |
---|---|
BBSIZ | BBSIZ0 |
BROWNOUT | BODEN, BOREN, DSBOREN |
CCPxMUX | CCPxMX |
CPD | CPDF, CPSW |
CPx | CP_x |
DEBUG | BACKBUG, BKBUG |
EBTRx | EBTR_x, EBRTx (typo) |
ECCPMUX | ECCPMX |
EXCLKMUX | EXCLKMX |
FLTAMUX | FLTAMX |
OSC | FOSC |
IOSCFS | IOFSCS (typo) |
MCLR | MCLRE |
MSSPMASK | MSSP7B_EN, MSSPMSK |
PMODE | PM |
PMPMUX | PMPMX |
PWM4MUX | PWM4MX |
PWRTE | PUT, PWRT, PWRTEN, NPWRTE, NPWRTEN |
RTCOSC | RTCSOSC |
SOSCSEL | SOSCEL |
SSPMUX | SSPMX |
STVR | STVREN |
T1OSCMUX | T1OSCMX |
T3CMUX | T3CMX |
VOLTAGE | BODENV, BOR4V, BORV |
WDT | WDTEN |
WRT | WRT_ENABLE |
WRTx | WRT_x |
As mentioned above the MPLAB .dev files contain frequently long and descriptions with many variations of the same story. Only for the oscillator specification alone the MPLAB .dev files contains about 200 different descriptions! But often the description is a single word like DISABLED or ACTIVE. Multi-word descriptions have been reduced to a single word or at least a single string (multiple words coupled by underscore characters).
Like for the keywords also for the symbolic values many synonyms can be found in the MPLAB .dev files. These synonyms are eliminated to a large extent. For example 'ENABLE' is often used even when the datasheet or MPLAB .dev file specifies 'ON' or 'ACTIVE'.
Below a set of 'normalized' pragma fuse_def:
B10 -- 10 bits B12 -- 12 bits B.. -- other number of bits
B8 -- 8 bits B16 -- 16 bits B.. -- other number of bits
W256 -- 256 words W512 -- 512 words W1K -- 1024 words (1K words) W2K -- 2048 words (2K words) W... -- any other number of words
ADJUST_NEG -- negative adjustment ADJUST_POS -- positive adjustment ... -- other
ENABLED -- BOD enabled, SBOREN disabled RUNONLY -- BOD enabled in run, disabled in sleep CONTROL -- SBOREN controls BOR function DISABLED -- BOD and SBOREN disabledBROWNOUT is also used for Deep Sleep BrownOut (DSBOREN).
B8 -- 8 bits B16 -- 16 bits B.. -- other number of bits
pin_xy -- assigned to pin y of PORTx pin_.. -- any other
ENABLED -- Code memory read protection on DISABLED -- Code mewmory read protection off
ENABLED -- Data (EEPROM) memory read protection on DISABLED -- Data (EEPROM) memory read protection off
P2 -- divide by 2 P.. -- etc P6 -- device by 6
INTOSC -- internal oscillator OSC -- oscillator determined by OSC fuse_def
P2G -- 1 : 2G (2 * 1073741824) P... P2M -- 1 : 2M (2 * 1048576) P... P2K -- 1 : 2K (2 * 1024) P.. P2 -- 1 : 2
ENABLED -- boot block table read protected DISABLED -- boot block may be table read
pin_xy -- pin y of portx is used
B12 -- 12 bits B16 -- 16 bits B20 -- 20 bit DISABLED -- disabled
ENABLED -- Ethernet LED enabled DISABLED -- Ethernet LED disabled
pin_xy -- Clock input assigned to pin y of portx
pin_xy -- pin y of portx is used
INTOSC -- Internal oscillator OSC -- Clock selected by OSC setting
ENABLED -- enable DISABLED -- disabled
F4MHZ -- 4 MHz F8MHZ -- 8 MHz
LOW_POWER -- low power, low noise immunity HIGH_POWER -- high power high noise immunity
ENABLED -- LVP on DISABLED -- LVP off
EXTERNAL -- /MCLR pin enabled INTERNAL -- /MCLR pin is digital I/O
LP -- Low Power crystal on OSC1,OSC2 XT -- Crystal or Resonator on OSC1,OSC2 HS -- High Speed Crystal or Resonator on OSC1,OSC2 HS_PLL -- HS with (hardware) PLL active EC_CLKOUT -- External Clock (TTL) signal on OSC1, ClockOut on OSC2 EC_NOCLKOUT -- External Clock (TTL) signal on OSC1, OSC2 is I/O EC_CLKOUT_PLL -- EC_CLKOUT with PLL active EC_NOCLKOUT_PLL -- EC_NOCLKOUT with PLL active ECH_NOCLKOUT -- external clock, high power mode ECL_NOCLKOUT -- external clock, low power mode ECM_NOCLKOUT -- external clock, medium power mode RC_CLKOUT -- (external) Resistor/Capacitor oscillator on OSC1, ClockOut on OSC2 RC_NOCLKOUT -- (external) Resistor/Capacitor oscillator on OSC1, OSC2 is I/O INTOSC_CLKOUT -- Internal oscillator, OSC1 is I/O, ClockOut on OSC2 INTOSC_NOCLKOUT -- Internal oscillator, OSC1 and OSC2 are I/OThe first or only part is the oscillator type, the [optional] second part indicates a related subfunction. For example it may indicate if the OSC2 pin is CLKOUT or I/O, or if PLL is active. Several other keywords are possible, for example:
P1 -- 1 : 1 P.. -- etc P12 -- 1 : 12
P1 -- 1 : 1 P4 -- 4 : 1 F500KHZ -- freq 500 KHz F16MHZ -- freq 16 MHz
pin_xy -- PWM4 assigned to pin_y of portx
B12 -- extended microcontroller 12-bit B16 -- extended microcontroller 16-bit B20 -- extended microcontroller 20-bit EXT -- extended microcontroller MICROCONTROLLER -- microcontroller MICROPROCESSOR -- microprocessor MICROPROCESSOR_BOOT -- microprocessor with boot block
PORTx -- PMP on PORTx and other ports
ENABLED -- Power up timer enabled DISABLED -- Power Up timer disabled
INTOSC -- Internal oscillator T1OSC -- Timer 1 oscillator
NOT_CONDUCATED AREA_COMPLETE
pin_xy -- SPI active on pin y of portx DISABLED -- SPI not assigned
pin_A6_A7 -- pin_A6 and pin_A7 are used pin_B2_B3 -- pin_B2 and pin_B3 are used
P1 -- no divide P2 -- divide by 2
F48MHZ -- from 96MHZ PLL / 2 OSC -- from Oscillator
DISABLED pin_A0 ... etc (other pins which could be assigned
V20 -- 2.0 Volt V27 -- 2.7 Volt V42 -- 4.0 Volt V45 -- 4.5 Volt ... etc (whatever voltages are applicable)
ENABLED -- synchronous DISABLED -- asynchronous
ENABLED -- Watchdog enabled DISABLED -- Watchdog disabled CONTROL -- Software controlled (SWDTEN) RUNNING -- Enabled while running, disabled in Sleep.
STANDARD LOW_POWER
P0_WPFP -- from page 0 to write protect page PWPFD_END -- from write protect page to end of memory
P0 -- Write protect flash page 0 P1 -- Write protect flash page 1 P.. -- etc P127 -- Write protect flash page 127
NO_PROTECTION -- All program memory writable ALL_PROTECTED -- Writing of program memory prohibited Rxxxx_yyyy -- Protected memory range -- (only specific ranges can be write protected)Notes:
pragma target CP R0F00_0FFF
When you find the specification of fuse_def inconvenient or you want to specify the bits one-by-one by yourself, the compiler allows you to do so. For example for the PIC16F690 the following group of statements:
pragma target OSC HS pragma target WDT Disabled pragma target PWRTE Enabled pragma target MCLR External pragma target CP Disabled pragma target CPD Disabled pragma target BROWNOUT Enabled pragma target IESO Disabled pragma target FCMEN Disabledis equivalent with:
pragma target fuses 0b11_0011_1110_0010
PICs with 16-bits core (the 18F series) have such a large set and variety of configuration bits that explicit specification is probably the best way to make sure all configuration bits are set correctly for your program. As an example see the following list for a simple blink-a-led program with an 18F242.
pragma target fuses 0 0b0000_0000 -- (n/a) pragma target fuses 1 0b0010_0010 -- not switchable, HS osc, no PLL pragma target fuses 2 0b0000_0001 -- BOR disabled, PWTR disabled pragma target fuses 3 0b0000_0000 -- watchdog disabled pragma target fuses 4 0b0000_0000 -- (n/a) pragma target fuses 5 0b0000_0001 -- CCP2 on RC1 pragma target fuses 6 0b1000_0001 -- no bg debug, no LVP, STVREN pragma target fuses 7 0b0000_0000 -- (n/a) pragma target fuses 8 0b0000_1111 -- no code protection pragma target fuses 9 0b1100_0000 -- no data protection pragma target fuses 10 0b0000_1111 -- no code write protection pragma target fuses 11 0b1110_0000 -- no other write protection pragma target fuses 12 0b0000_1111 -- no table read protection pragma target fuses 13 0b0100_0000 -- no boot block write protect(n/a) means not applicable to this specific PIC, but may be specified (as all zeroes).
Notes:
The compiler - at the moment of this writing version 2.4n - has a number of requirements for device specifications. The most important from a user perspective are the following:
The device files specify the amounts of available data memory for variables in bytes.
There is a distinction between 'shared' and 'unshared' memory. For the compiler 'shared' means:
The compiler allocates memory for regular ('user') variables in unshared memory.
The compiler needs some memory for internal use. These variables are named _pic_accum and _pic_isr_w, and must be allocated in shared memory. Each device files contains the declarations for these.
Most PICS have both shared and unshared RAM and then there is no issue, neither is there an issue with PICs with only 1 memory bank. But some midrange PICs have only shared memory while some others have no shared memory at all. This complication is handled by the device files as follows:
(to be done)
These device files are part of the central JalV2 repository 'Jallib' (http://jallib.googlecode.com). Other libraries of Jallib have been or are being converted to use the names in these device files. You are strongly recommended to use only this combination of include files. Using these device files in combination with other libraries may cause problems, especially with libraries for the old (pre JalV2) compiler.
The device files are generated by transforming MPLAB files with a script 'dev2jal.cmd' in the /Jallib/tools directory. The script is developed and executed with 'classic' Rexx as standardly delivered with eComStation (OS/2). To run it:
Notes:
The dev2jal script can be executed on other systems (Linux, Windows) when a compatible Rexx interpreter is installed. The free 'Regina Rexx' has proven to do fine for this script (tested under Windows XP). For more information about Regina Rexx see:
Download and install the package (latest version 3.5) when you want to run the script on a non-eComStation system. Probably the easiest way to run the script is:
When generating Jallib device files after a fresh install of MPLAB the following corrections have to be made by 'manual' editing of the MPLAB .dev files of the indicated PICs:
When there are new device files which are not in Jallib yet then before running the dev2jal script:
When all is satisfactory SVN-add the device files of new PICs and commit all device files and changed files in tools and wiki directory.