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.

Reply via email to