jal 2.4m (compiled Dec 26 2009)
generating p-code
0 errors, 0 warnings
3536 tokens, 448485 chars; 12293 lines; 22 files
generating PIC code pass 1
Then the compiler crashes...
example
>>compile results window
Compilation started at :14/04/2010 18:43:38
jal 2.4m (compiled Dec 26 2009)
Compiler CommandLine: C:\JALPack\compiler\jalv2.exe "J:\Projects
\CatPad67J50\catpatv3.jal" -s "C:\JALPack\lib" -temp-reduce -pcode
>> compiler popup
jal 2.4m (compiled Dec 26 2009)
generating p-code
0 errors, 0 warnings
3536 tokens, 446996 chars; 12257 lines; 22 files
generating PIC code pass 1
** Crashes.
>>compile results window
Code : 0/100 Data 0/100
Hardware Stack: 0/100 Software Stack 0
The only code I changed was fuses/pragma as below and the eeprom
storage program (at end)
I have been looking at the differences for initial "PRAGMA":
1) No power up timer or brownout config bits, the HW pin selecting
internal regulator enables it and Brownout
2) I can't see the code protection stuff anywhere
3) ZERO user EEPROM. You are meant to emulate any size you want by
table read/ table write on the Program Flash. Is there a library for
this or will I port the microchip example to emulate internal eeprom?
4) No USB reg pin enable. I guess since Vdd is 3.3V it has not got a
USB regulator
5) No MLCLR/RE3 config
Subtle differences in clock config, but "mostly" similar. Especially
for external crystal + PLL + HS-USB
I'm puzzled by this on the 18F4550
pragma target USBPLL F48MHZ -- CLOCK_SRC_FROM_96MHZ_PLL_2
I'm not sure how it relates to the datasheet. The usage of 4MHz to
40MHz crystal divided by 1 to 10 to get 4MHz, and lock 96MHz / 2 = 48
MHz and setup for High Speed USB etc seem the same on both data sheets
apart from location of the CPDIV or CPUDIV bits to divide 96MHz by 2
to 48MHz.
Page 36 onward in 18F87j50 pdf and page 26 onward in
18F2455-2550-4455-4550 pdf
18F4550
-- Symbolic Fuse definitions
-- -------------------------
--
-- CONFIG1L (0x300000)
--
pragma fuse_def PLLDIV:0 0x7 { -- 96mhz pll prescaler
P12 = 0x7 -- divide by 12 (48mhz
input)
P10 = 0x6 -- divide by 10 (40mhz
input)
P6 = 0x5 -- divide by 6 (24mhz
input)
P5 = 0x4 -- divide by 5 (20mhz
input)
P4 = 0x3 -- divide by 4 (16mhz
input)
P3 = 0x2 -- divide by 3 (12mhz
input)
P2 = 0x1 -- divide by 2 (8mhz input)
P1 = 0x0 -- no divide (4mhz input)
}
pragma fuse_def CPUDIV:0 0x18 { -- cpu system clock
postscaler
P6 = 0x18 -- [osc1/osc2 src: /4]
[96mhz pll src: /6]
P4 = 0x10 -- [osc1/osc2 src: /3]
[96mhz pll src: /4]
P3 = 0x8 -- [osc1/osc2 src: /2]
[96mhz pll src: /3]
P2 = 0x0 -- [osc1/osc2 src: /1]
[96mhz pll src: /2]
}
pragma fuse_def USBPLL:0 0x20 { -- full-speed usb clock
source selection
F48MHZ = 0x20 -- clock src from 96mhz pll/
2
OSC = 0x0 -- clock src from osc1/osc2
}
--
-- CONFIG1H (0x300001)
--
pragma fuse_def OSC:1 0xF { -- oscillator
HS_PLL = 0xE -- hs: hs+pll, usb-hs
HS = 0xC -- hs: usb-hs
INTOSC_NOCLKOUT_USB_HS = 0xB -- intosc: usb-hs
INTOSC_NOCLKOUT_USB_XT = 0xA -- intosc: usb-xt
INTOSC_CLKOUT = 0x9 -- intosc: intosc
+clk0{ra6}, usb-ec
EC_CLKOUT_PLL = 0x7 -- ec: ec+pll, ec+pll
+clko{ra6}, usb-ec
EC_NOCLKOUT_PLL = 0x6 -- ec: ec+pll, ec+pll+ra6,
usb-ec
EC_CLKOUT = 0x5 -- ec: ec+clko{ra6}, usb-ec
EC_NOCLKOUT = 0x4 -- ec: ec+ra6, usb-ec
XT_PLL = 0x2 -- xt: xt+pll, usb-xt
XT = 0x0 -- xt: usb-xt
}
pragma fuse_def FCMEN:1 0x40 { -- fail-safe clock monitor
enable
DISABLED = 0x0 -- disabled
ENABLED = 0x40 -- enabled
}
pragma fuse_def IESO:1 0x80 { -- internal external switch
over mode
DISABLED = 0x0 -- disabled
ENABLED = 0x80 -- enabled
}
--
and
18F67J50
-- Symbolic Fuse definitions
-- -------------------------
--
-- CONFIG1L (0x1FFF8)
--
pragma fuse_def WDT:0 0x1 { -- watchdog timer
ENABLED = 0x1 -- enabled
DISABLED = 0x0 -- disabled-controlled by
swdten bit
}
pragma fuse_def PLLDIV:0 0xE { -- pll div
P1 = 0xE -- no divide (4mhz input)
P2 = 0xC -- divide by 2 (8mhz input)
P3 = 0xA -- divide by 3 (12mhz
input)
P4 = 0x8 -- divide by 4 (16mhz
input)
P5 = 0x6 -- divide by 5 (20mhz
input)
P6 = 0x4 -- divide by 6 (24mhz
input)
P10 = 0x2 -- divide by 10 (40mhz
input)
P12 = 0x0 -- divide by 12 (48mhz
input)
}
pragma fuse_def STVR:0 0x20 { -- stack overflow reset
ENABLED = 0x20 -- enabled
DISABLED = 0x0 -- disabled
}
pragma fuse_def XINST:0 0x40 { -- extended instruction set
enable bit
ENABLED = 0x40 -- enabled
DISABLED = 0x0 -- disabled
}
pragma fuse_def DEBUG:0 0x80 { -- background debug
DISABLED = 0x80 -- disabled
ENABLED = 0x0 -- enabled
}
--
-- CONFIG1H (0x1FFF9)
--
pragma fuse_def CPUDIV:1 0x3 { -- cpu div
P1 = 0x3 -- no cpu system clock
divide
P2 = 0x2 -- cpu system clock divide
by 2
P3 = 0x1 -- cpu system clock divide
by 3
P6 = 0x0 -- cpu system clock divide
by 6
}
pragma fuse_def CP0:1 0x4 { -- code protect
000000-01fff7
DISABLED = 0x4 -- disabled
ENABLED = 0x0 -- enabled
}
pragma fuse_def SIGN:1 0x8 { -- config word signature
bit
NOT_CONDUCATED = 0x8 -- bulk erase of memory not
conducated
AREA_COMPLETE = 0x0 -- bulk erase of memory
area complete
}
--
-- CONFIG2L (0x1FFFA)
--
pragma fuse_def OSC:2 0x7 { -- oscillator
EC_CLKOUT_PLL = 0x7 -- ec+pll(clko-ra6),usb-ec
+pll
EC_CLKOUT = 0x6 -- ec(clko-ra6),usb-ec
HS_PLL = 0x5 -- hs+pll,usb-hs+pll
HS = 0x4 -- hs,usb-hs
INTOSC_CLKOUT_PLL = 0x3 -- intoscpllo(clko-ra6)
INTOSC_NOCLKOUT_PLL = 0x2 -- intoscpll
INTOSC_CLKOUT = 0x1 -- intosco(clko-ra6)
}
pragma fuse_def FCMEN:2 0x40 { -- fail-safe clock monitor
enable
DISABLED = 0x0 -- disabled
ENABLED = 0x40 -- enabled
}
pragma fuse_def IESO:2 0x80 { -- internal external switch
over mode
DISABLED = 0x0 -- disabled
ENABLED = 0x80 -- enabled
}
--
The folllowing is what I changed my "fuses"
include 18F67J50
-- was 18f4550
-- even though the external crystal is 20 MHz, the configuration is
such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2),
therefore set
-- target frequency to 48 MHz
pragma target clock 48_000_000
-- fuses
pragma target PLLDIV P5 -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV P2 --
OSC1_OSC2_SRC_1_96MHZ_PLL_SRC_2
--next is for 18F4550 disable for 18F67J50
-- pragma target USBPLL F48MHZ --
CLOCK_SRC_FROM_96MHZ_PLL_2 ??
-- pragma target PWRTE ENABLED -- power up timer
(always on 18F67J50)
-- pragma target VOLTAGE V20 -- brown out voltage
-- pragma target BROWNOUT DISABLED -- no brownout
detection
-- on 18F67J50 Brownout is set by selecting internal regulator,
ENVREG pin = VDD
-- pragma target VREGEN ENABLED -- USB voltage
regulator
-- on 18FxxJxx family the VDD is 3.3V, so this is not needed.
-- pragma target PBADEN DIGITAL -- digital input
port<0..4>
-- pragma target LPT1OSC LOW_POWER -- low power timer 1
-- pragma target MCLR EXTERNAL -- master reset on RE3
-- pragma target LVP DISABLED -- no low-voltage
programming
--pragma target CP0 DISABLED -- code block 0 not
protected
--pragma target CP1 DISABLED -- code block 1 not
protected
--pragma target CP2 DISABLED -- code block 2 not
protected
--pragma target CP3 DISABLED -- code block 3 not
protected
--pragma target CPB DISABLED -- bootblock code not write
protected
--pragma target CPD DISABLED -- eeprom code not write
protected
--pragma target WRT0 DISABLED -- table writeblock 0 not
protected
--pragma target WRT1 DISABLED -- table write block 1 not
protected
--pragma target WRT2 DISABLED -- table write block 2 not
protected
--pragma target WRT3 DISABLED -- table write block 3 not
protected
--pragma target WRTB DISABLED -- bootblock not write
protected
--pragma target WRTD DISABLED -- eeprom not write
protected
--pragma target WRTC DISABLED -- config not write
protected
--pragma target EBTR0 DISABLED -- table read block 0 not
protected
--pragma target EBTR1 DISABLED -- table read block 1 not
protected
--pragma target EBTR2 DISABLED -- table read block 2 not
protected
--pragma target EBTR3 DISABLED -- table read block 3 not
protected
--pragma target EBTRB DISABLED -- boot block not protected
pragma target OSC HS_PLL
pragma target FCMEN DISABLED
pragma target IESO DISABLED
pragma target WDTPS P32K -- watch dog saler setting
pragma target WDT DISABLED -- no watchdog
pragma target CCP2MUX pin_C1 -- CCP2 pin
pragma target STVR DISABLED -- reset on stack over/under
flow
pragma target XINST ENABLED -- extended instruction set
pragma target DEBUG DISABLED -- background debugging
Revised storage.jal
--
-- ------------------------------------------------------------
-- Internal EEPROM on PIC
-- ------------------------------------------------------------
-- 18FxxJxx series has zero eeprom
if (defined(_eeprom) == TRUE) then
function EepromIntCount() return dword is
pragma inline
return(COUNT(_eeprom))
end function
--
------------------------------------------------------------------------
-- Set memory region bits in EECON1 and load offset register(s)
-- Wait (spin) until any previous write completed before
proceeding.
--
------------------------------------------------------------------------
procedure _prepare_eeprom_access(word in offset) is
-- pragma inline
var byte tempoffset[2] at offset -- type cast
while EECON1_WR loop -- allow any
previous
-- spin as long as any previous write is not completed
end loop -- before this
write
if (defined(EEADR) == TRUE) then
EEADR = tempoffset[0] -- low order byte
of offset
elsif (defined(EEADRL) == TRUE) then
EEADRL = tempoffset[0] -- low order byte
of offset
end if
if (defined(EEADRH) == TRUE) then -- PIC with large
EEPROM
EEADRH = tempoffset[1] -- high order byte
of offset
end if
if (defined(EECON1_CFGS) == TRUE) then -- config memory
supported
EECON1_CFGS = FALSE -- deselect config
region
end if
if (defined(EECON1_EEPGD) == TRUE) then -- code memory
supported
EECON1_EEPGD = FALSE -- deselect code
region
end if
end procedure
--
------------------------------------------------------------------------
-- Read byte from datab EEPROM at given offset
--
------------------------------------------------------------------------
function EepromIntByte'get(word in offset)return byte is
var byte datab
if (offset < EepromIntCount()) then
_prepare_eeprom_access(offset) -- make ready
for rea
if (defined( EECON1_RD) == TRUE) then
EECON1_RD = TRUE --
initiate read operation
end if
if (defined(EEDATA) == TRUE) then
datab = EEDATA -- obtain
byte
elsif (defined(EEDAT) == TRUE) then
datab = EEDAT -- obtain
byte
elsif (defined(EEDATL) == TRUE) then
datab = EEDATL -- obtain
byte
end if
else
datab = 0xFF
end if
return (datab)
end function
--
------------------------------------------------------------------------
-- Write byte to datab EEPROM at given offset
--
------------------------------------------------------------------------
procedure EepromIntByte'put(word in offset, byte in datab) is
var bit gie_old -- GIE state
if (offset < EepromIntCount()) then
_prepare_eeprom_access(offset) -- make ready
for write
if (defined(EEDATA) == TRUE) then
EEDATA = datab -- store byte
elsif (defined(EEDAT) == TRUE) then
EEDAT = datab -- store byte
elsif (defined(EEDATL) == TRUE) then
EEDATL = datab -- store byte
end if
EECON1_WREN = TRUE -- write
enable
gie_old = INTCON_GIE -- save GIE
state
INTCON_GIE = FALSE -- disable
interrupts
EECON2 = 0x55 -- \ required
sequence
EECON2 = 0xAA -- /
EECON1_WR = TRUE -- initiate
write operation
INTCON_GIE = gie_old -- restore
interrupt status
EECON1_WREN = FALSE -- disable
further writing
end if
end procedure
--
------------------------------------------------------------------------
-- Read word from datab eeprom at given offset
-- Result is stored in the passed in-argument
--
------------------------------------------------------------------------
function EepromIntWord'get(word in offset)return word is
var word datas
var byte tempbyte[2] at datas
tempbyte[0]= EepromIntByte[offset]
tempbyte[1]= EepromIntByte[offset+1]
return(datas)
end function
--
------------------------------------------------------------------------
-- Write word to datab eeprom at given offset
--
------------------------------------------------------------------------
procedure EepromIntWord'put(word in offset, word in datab) is
var byte tempbyte[2] at datab -- type cast
EepromIntByte[offset] = tempbyte[0]
EepromIntByte[offset+1] = tempbyte[1]
end procedure
else
-- ******** To Do : Emulate eeprom with Flash Program Memory
********
function EepromIntCount() return dword is
pragma inline
return(0)
end function
function EepromIntByte'get(word in offset)return byte is
var byte datab
datab = 0xFF
return (datab)
end function
procedure EepromIntByte'put(word in offset, byte in datab) is
-- use Program flash?
end procedure
function EepromIntWord'get(word in offset)return word is
var word datas = 0xFFFF
var byte tempbyte[2] at datas
return(datas)
end function
procedure EepromIntWord'put(word in offset, word in datab) is
var byte tempbyte[2] at datab -- type cast
end procedure
end if
-- defaults are for 1 x 24LC512 with A0, A1 and A2 pins = 0V
const _EEPROM_ERROR_NONE = 0
const _EEPROM_ERROR_TX = 1
const _EEPROM_ERROR_RX = 2
const _EEPROM_ERROR_BOUNDS = 3
const _EEPROM_WAIT_FOR_BUS_INIT = 10_000_000 -- 10 seconds
var dword _EepromExtArraySize = 65536
var byte _EepromExtBaseAddress = 0
var byte _EepromExtChipAddressBits = 16
var word _EepromExtPageSize = 128
var byte _EepromExtControl = 0b1010_0000
var byte _EepromExtLastError = 0
-- All eeproms must be contigious addressed and same size
-- only need to call if not 1 x 24LC512 with A0, A1 and A2 pins = 0V
-- lower four bits of "control" are ignored
function EepromExtByteInit(byte in numChips, byte in baseAddress, byte
in chipAddressBits, word in pageSize, byte in control) return byte
is
var byte controlUpper
controlUpper = numChips + baseAddress
if controlUpper > 7 then
return (controlUpper -7)
else
_EepromExtBaseAddress = baseAddress
_EepromExtChipAddressBits = chipAddressBits
_EepromExtPageSize = pageSize
_EepromExtArraySize = dword(1)<< dword(chipAddressBits) *
dword(numChips)
_EepromExtControl = control & byte(0b1111_0000) -- addres is
zero
_EepromExtLastError = _EEPROM_ERROR_NONE
end if
return(0)
end function
-- ------------------------------------------------------------
-- External EEPROM via I2C
-- ------------------------------------------------------------
function EepromExtCount() return dword is
return(_EepromExtArraySize)
end function
function EepromExtPageSize() return word is
return(_EepromExtPageSize)
end function
function EepromExtByte'get(dword in address) return byte is
var volatile bit commOK
var byte datab
var byte controlDevice, addressLow, addressHigh
var byte addressBytes[3] at address -- split the memory address
var dword timeout = _EEPROM_WAIT_FOR_BUS_INIT
var byte ch, id
datab = 255
if address < _EepromExtArraySize then
controlDevice = _EepromExtControl -- address zero & read
-- now add in the 3 bit address only
controlDevice = controlDevice | ((addressBytes[2]<1) &
byte(0b0000_1110))
addressHigh = addressBytes[1]
addressLow = addressBytes[0]
if _EepromExtChipAddressBits < 16 then
-- fixup addressHigh and ControlDevice
end if -- else all of AddressHigh is used
if _EepromExtBaseAddress > 0 then
-- fixup controlDevice
end if -- else controlDevice is either 3rd byte of address or
part of 2nd byte
--commOK =
while ! i2c_Seize(400_000_000, true) & ( timeout > 0) loop
timeout = timeout -1
_usec_delay(1)
end loop
if timeout > 0 then i2c_start() -- send
start bit
commOK = i2c_transmit_byte(controlDevice) --
transmit datab & wait for ack
commOK = i2c_transmit_byte(addressHigh) -- transmit
datab & wait for ack
commOK = i2c_transmit_byte(addressLow) -- transmit
datab & wait for ack
i2c_start() -- send start bit
commOK = i2c_transmit_byte(controlDevice + 1) --
transmit datab & wait for ack
datab = i2c_receive_byte(0) -- nack (no
ack)
i2c_stop() -- send stop
bit
i2c_Release()
_EepromExtLastError = _EEPROM_ERROR_NONE
else
_EepromExtLastError = _EEPROM_ERROR_RX
end if
else
_EepromExtLastError = _EEPROM_ERROR_BOUNDS
end if
return (datab)
end function
--------------------------------------------------------------------------------
-- write byte to Eeprom at device+ 16 bit adress
-- if less big than a 24LC512, address map has holes
-- multiple 24LC512 will look like one big array.
--------------------------------------------------------------------------------
procedure EepromExtByte'put(dword in address, byte in datab) is
var volatile bit commOK
var byte controlDevice, addressLow, addressHigh
var byte addressBytes[3] at address -- split the memory address
var dword timeout = _EEPROM_WAIT_FOR_BUS_INIT
var byte ch, id
if address < _EepromExtArraySize then
controlDevice = _EepromExtControl -- address zero & read
-- now add in the 3 bit address only
controlDevice = controlDevice | ((addressBytes[2]<1) &
byte(0b0000_1110))
addressHigh = addressBytes[1]
addressLow = addressBytes[0]
if _EepromExtChipAddressBits < 16 then
-- fixup addressHigh and ControlDevice
end if -- else all of AddressHigh is used
if _EepromExtBaseAddress > 0 then
-- fixup controlDevice
end if -- else controlDevice is either 3rd byte of address or
part of 2nd byte
while ! i2c_Seize(400_000_000, true) & ( timeout > 0) loop
timeout = timeout -1
_usec_delay(1)
end loop
if timeout > 0 then
i2c_start() -- send start bit
commOK = i2c_transmit_byte(controlDevice) -- transmit
datab & wait for ack
commOK = i2c_transmit_byte(addressHigh) -- transmit datab &
wait for ack
commOK = i2c_transmit_byte(addressLow) -- transmit datab &
wait for ack
commOK = i2c_transmit_byte(datab) -- transmit datab
& wait for ack
i2c_stop -- send stop bit
-- change to a timer driving a signal
_usec_delay(5_000) -- datasheet says
writes take 5ms
i2c_Release()
_EepromExtLastError = _EEPROM_ERROR_NONE
else
_EepromExtLastError = _EEPROM_ERROR_TX
end if
else
_EepromExtLastError = _EEPROM_ERROR_BOUNDS
end if
end procedure
function EepromExtWord'get(dword in address) return word is
var volatile bit commOK
var byte datab[2]
var word datas at datab
var byte controlDevice, addressLow, addressHigh
var byte addressBytes[3] at address -- split the memory address
var dword timeout = _EEPROM_WAIT_FOR_BUS_INIT
var byte ch, id
datas = 65535
if ((address+1) < _EepromExtArraySize) then
controlDevice = _EepromExtControl -- address zero & read
-- now add in the 3 bit address only
controlDevice = controlDevice | ((addressBytes[2]<1) &
byte(0b0000_1110))
addressHigh = addressBytes[1]
addressLow = addressBytes[0]
if _EepromExtChipAddressBits < 16 then
-- fixup addressHigh and ControlDevice
end if -- else all of AddressHigh is used
if _EepromExtBaseAddress > 0 then
-- fixup controlDevice
end if -- else controlDevice is either 3rd byte of address or
part of 2nd byte
--commOK =
while ! i2c_Seize(400_000_000, true) & ( timeout > 0) loop
timeout = timeout -1
_usec_delay(1)
end loop
if timeout > 0 then i2c_start() -- send
start bit
commOK = i2c_transmit_byte(controlDevice) --
transmit datab & wait for ack
commOK = i2c_transmit_byte(addressHigh) -- transmit
datab & wait for ack
commOK = i2c_transmit_byte(addressLow) -- transmit
datab & wait for ack
i2c_start() -- send start bit
commOK = i2c_transmit_byte(controlDevice + 1) --
transmit datab & wait for ack
datab[0] = i2c_receive_byte(1) -- ack
(no ack)
datab[1] = i2c_receive_byte(0) -- nack
(no ack)
i2c_stop() -- send stop
bit
i2c_Release()
_EepromExtLastError = _EEPROM_ERROR_NONE
else
_EepromExtLastError = _EEPROM_ERROR_RX
end if
else
_EepromExtLastError = _EEPROM_ERROR_BOUNDS
end if
return (datas)
end function
--------------------------------------------------------------------------------
-- write byte to Eeprom at device+ 16 bit adress
-- if less big than a 24LC512, address map has holes
-- multiple 24LC512 will look like one big array.
--------------------------------------------------------------------------------
procedure EepromExtWord'put(dword in address, word in datas) is
var volatile bit commOK
var byte datab[2] at datas
var byte controlDevice, addressLow, addressHigh
var byte addressBytes[3] at address -- split the memory address
var dword timeout = _EEPROM_WAIT_FOR_BUS_INIT
var byte ch, id
if ((address +1) < _EepromExtArraySize) then
controlDevice = _EepromExtControl -- address zero & read
-- now add in the 3 bit address only
controlDevice = controlDevice | ((addressBytes[2]<1) &
byte(0b0000_1110))
addressHigh = addressBytes[1]
addressLow = addressBytes[0]
if _EepromExtChipAddressBits < 16 then
-- fixup addressHigh and ControlDevice
end if -- else all of AddressHigh is used
if _EepromExtBaseAddress > 0 then
-- fixup controlDevice
end if -- else controlDevice is either 3rd byte of address or
part of 2nd byte
while ! i2c_Seize(400_000_000, true) & ( timeout > 0) loop
timeout = timeout -1
_usec_delay(1)
end loop
if timeout > 0 then
i2c_start() -- send start bit
commOK = i2c_transmit_byte(controlDevice) -- transmit
datab & wait for ack
commOK = i2c_transmit_byte(addressHigh) -- transmit datab &
wait for ack
commOK = i2c_transmit_byte(addressLow) -- transmit datab &
wait for ack
commOK = i2c_transmit_byte(datab[0]) -- transmit
datab & wait for ack
commOK = i2c_transmit_byte(datab[1])
i2c_stop -- send stop bit
-- change to a timer driving a signal
_usec_delay(5_000) -- datasheet says
writes take 5ms
i2c_Release()
_EepromExtLastError = _EEPROM_ERROR_NONE
else
_EepromExtLastError = _EEPROM_ERROR_TX
end if
else
_EepromExtLastError = _EEPROM_ERROR_BOUNDS
end if
end procedure
procedure EepromExtArray'put(dword in address, byte in datab[]) is
-- to do: check page boundary
var volatile bit commOK
var byte controlDevice, addressLow, addressHigh
var byte addressBytes[3] at address -- split the memory address
var dword timeout = _EEPROM_WAIT_FOR_BUS_INIT
var word idx
var byte ch, id
if ((address + count(datab)) < _EepromExtArraySize) then
controlDevice = _EepromExtControl -- address zero & read
-- now add in the 3 bit address only
controlDevice = controlDevice | ((addressBytes[2]<1) &
byte(0b0000_1110))
addressHigh = addressBytes[1]
addressLow = addressBytes[0]
if _EepromExtChipAddressBits < 16 then
-- fixup addressHigh and ControlDevice
end if -- else all of AddressHigh is used
if _EepromExtBaseAddress > 0 then
-- fixup controlDevice
end if -- else controlDevice is either 3rd byte of address or
part of 2nd byte
while ! i2c_Seize(400_000_000, true) & ( timeout > 0) loop
timeout = timeout -1
_usec_delay(1)
end loop
if (timeout > 0) then
i2c_start() -- send start bit
commOK = i2c_transmit_byte(controlDevice) -- transmit
datab & wait for ack
commOK = i2c_transmit_byte(addressHigh) -- transmit datab &
wait for ack
commOK = i2c_transmit_byte(addressLow) -- transmit datab &
wait for ack
for count(datab) using idx loop
commOK = i2c_transmit_byte(datab[idx]) --
transmit datab & wait for ack
if !commOK then
_EepromExtLastError = _EEPROM_ERROR_TX
exit loop
end if
end loop
i2c_stop -- send stop bit
-- change to a timer driving a signal
_usec_delay(5_000) -- datasheet says
writes take 5ms
i2c_Release()
_EepromExtLastError = _EEPROM_ERROR_NONE
else
_EepromExtLastError = _EEPROM_ERROR_TX
end if
else
_EepromExtLastError = _EEPROM_ERROR_BOUNDS
end if
end procedure
--
You received this message because you are subscribed to the Google Groups
"jallib" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/jallib?hl=en.