EDIT: check the SetDigitalIO wiki page for the latest version
I tried to cover some of the odd-ball ones like those that have non-access bank registers and parts that have shared overlaying register addresses, but the list is far from complete. I didn't really change the standard F series parts.
There are two new macros... read_sfr() and write_sfr() that should allow this to work with the SE compiler even for registers that are located outside of Bank 0. If you're using the SE compiler, set '#option SWORDFISH_SE = true', either in this file or before including it.
I did this as a separate module, but you could always incorporate it into utils.bas (where the current one resides)
SetDigitalIO.bas (edited from original):
Code: Select all
{
****************************************************************************
* Name : SetAllDigital *
* Purpose : Switches device pins from analog to digital *
* Version : 1.6 *
* Notes : *
* : 1.6 - change 18FxxK22 (rickado) *
* : correct 18F1230/1330 comparator setting *
* : 1.5 - add 18F4xK22 (rickado) *
* : 1.4 - add write_sfr()/read_sfr() macros and add'tl devices *
* : add #option SWORDFISH_SE *
* : 1.3 - add fix for ADSHR shared SFR registers (certain J series)*
* : 1.2 - add 18FxxK20, K22, K50, K80, and K90 series *
* : 1.1 - add 18F46J50 *
****************************************************************************
}
module SetDigitalIO
// set this option true if building with the SE compiler
#option SWORDFISH_SE = false
//
// these macros are used to read and write SFR's that are located in the upper
// bank (bank 15), but are not part of the access bank
//
// since SE does not contain code to set the bank select register, setting
// #option SWORDFISH_SE true will enable the write_sfr()/read_sfr() macros to
// generate a MOVFF instruction so that setting the BSR is not required
//
public macro write_sfr(sfr, val)
#if (SWORDFISH_SE)
WREG = val
asm
movff wreg, sfr
end asm
#else
sfr = val
#endif
end macro
public macro read_sfr(sfr, bvar)
#if (SWORDFISH_SE)
asm
movff sfr, bvar
end asm
#else
bvar = sfr
#endif
end macro
//
// set all analog IO pins to digital function
//
public sub SetAllDigital()
dim ADSHR as WDTCON.4 // alternate register address bit present on certain devices
// devices are grouped by datasheet where appropriate
// 4 channels
#if _device in (18F1230, 18F1330)
ADCON1 = $00
CMCON = $00 // changed V1.6
// 5 channels, ANSEL...
#elseif _device in (18F2331, 18F2431)
ANSEL0 = $00
// 9 channels, ANSEL...
#elseif _device in (18F4331, 18F4431)
ANSEL0 = $00
ANSEL1.0 = 0
// 7 channels, bit field...
#elseif _device in (18F1220, 18F1320)
ADCON1 = $7F
// J10/J15 family...
#elseif _device in (18F65J10, 18F65J15, 18F66J10, 18F66J15, 18F67J10, 18F85J10, 18F85J15, 18F86J10, 18F86J15, 18F87J10)
ADCON1 = $0F
CMCON = 0
// J11 family...
#elseif _device in (18F63J11, 18F64J11, 18F65J11, 18F83J11, 18F84J11, 18F85J11)
ADCON1 = $0F
CMCON = 0
// J11 family... (shared SFR addresses)
#elseif _device in (18F66J11, 18F67J11, 18F86J11, 18F87J11)
// registers $0F5A - $0F5F are not part of the access bank
ADSHR = 1
ANCON0 = $FF
ANCON1 = $FF
ADSHR = 0
CM1CON = 0
CM2CON = 0
// J16 family... (shared SFR addresses)
#elseif _device in (18F66J16, 18F86J16)
// registers $0F5A - $0F5F are not part of the access bank
ADSHR = 1
ANCON0 = $FF
ANCON1 = $FF
ADSHR = 0
CM1CON = 0
CM2CON = 0
// J50 family... (shared SFR addresses)
#elseif _device in (18F65J50, 18F66J50, 18F67J50, 18F85J50, 18F86J50, 18F87J50)
// registers $0F40 - $0F5F are not part of the access bank
ADSHR = 1
ANCON0 = $FF
ANCON1 = $FF
ADSHR = 0
CM1CON = 0
CM2CON = 0
// J55 family... (shared SFR addresses)
#elseif _device in (18F66J55, 18F86J55)
// registers $0F40 - $0F5F are not part of the access bank
ADSHR = 1
ANCON0 = $FF
ANCON1 = $FF
ADSHR = 0
CM1CON = 0
CM2CON = 0
// J50 family...
#elseif _device in (18F24J50, 18F25J50, 18F26J50, 18F44J50, 18F45J50, 18F46J50)
// registers $0EC0 - $0F5F are not part of the access bank
write_sfr(ANCON0, $FF)
write_sfr(ANCON1, $1F)
CM1CON = 0
CM2CON = 0
// J53 family...
#elseif _device in (18F26J53, 18F27J53, 18F46J53, 18F47J53)
// registers $0EB0 - $0F5F are not part of the access bank
write_sfr(ANCON0, $FF)
write_sfr(ANCON1, $1F)
CM1CON = 0
CM2CON = 0
// 18FxxK20 family
#elseif _device in (18F23K20, 18F24K20, 18F25K20, 18F26K20, 18F43K20, 18F44K20, 18F45K20, 18F46K20)
ANSEL = $00
ANSELH = $00
CM1CON0 = 0
CM2CON0 = 0
// 18FxxK22 family
// 18F1xK22
#elseif _device in (18F13K22, 18F14K22)
// registers $0F53 - $0F5F are not part of the access bank
ANSEL = $00
ANSELH = $00
CM1CON0 = 0
CM2CON0 = 0
VREFCON1 = $00 // added V1.6
// 18F2xK22/18F4xK22
#elseif _device in (18F23K22, 18F24K22, 18F25K22, 18F26K22)
// registers $0F38 - $0F5F are not part of the access bank
write_sfr(ANSELA, $00)
write_sfr(ANSELB, $00)
write_sfr(ANSELC, $00)
CM1CON0 = %00001000 // changed V1.6
CM2CON0 = %00001000
VREFCON1 = $00 // added V1.6
#elseif _device in (18F43K22, 18F44K22, 18F45K22, 18F46K22) // added V1.5
// registers $0F38 - $0F5F are not part of the access bank
write_sfr(ANSELA, $00)
write_sfr(ANSELB, $00)
write_sfr(ANSELC, $00)
write_sfr(ANSELD, $00)
write_sfr(ANSELE, $00)
CM1CON0 = %00001000 // changed V1.6
CM2CON0 = %00001000
VREFCON1 = $00 // added V1.6
// 18F87K22 family
#elseif _device in (18F65K22, 18F66K22, 18F67K22, 18F85K22, 18F86K22, 18F87K22)
// registers $0F16 - $0F5F are not part of the access bank
write_sfr(ANCON0, $00)
write_sfr(ANCON1, $00)
write_sfr(ANCON2, $00)
CM1CON = 0
CM2CON = 0
CM3CON = 0
CVRCON = $00 // added V1.6
// 18FxxK50 family
#elseif _device in (18F13K50, 18F14K50)
// registers $0F53 - $0F5F are not part of the access bank
ANSEL = $00
ANSELH = $00
CM1CON0 = 0
CM2CON0 = 0
// 18FxxK80 family
#elseif _device in (18F25K80, 18F26K80, 18F45K80, 18F46K80, 18F65K80, 18F66K80)
// registers $0E41 - $0F5F are not part of the access bank
write_sfr(ANCON0, $00)
write_sfr(ANCON1, $00)
write_sfr(CM1CON, $00)
write_sfr(CM2CON, $00)
// 18FxxK90 family
#elseif _device in (18F65K90, 18F66K90, 18F67K90, 18F85K90, 18F86K90, 18F87K90)
// registers $0EF4 - $0F5F are not part of the access bank
write_sfr(ANCON0, $00)
write_sfr(ANCON1, $00)
write_sfr(ANCON2, $00)
write_sfr(CM1CON, $00)
write_sfr(CM2CON, $00)
write_sfr(CM3CON, $00)
// 8 - 13 channels - 0 comp
#elseif _comparator = 0
ADCON1 = $0F
// assume default is ok...
#else
ADCON1 = $0F
CMCON = $07
#endif
end sub
end module