Revision: 1182
Author: [email protected]
Date: Mon Aug 10 14:12:58 2009
Log: added auto-start bootloader, fixed goto, required due to compiler  
bug-fix
http://code.google.com/p/jallib/source/detail?r=1182

Added:
  /trunk/test/peripheral/usb/test_usb_bootloader_autostart.jal
Modified:
  /trunk/test/peripheral/usb/test_usb_bootloader.jal

=======================================
--- /dev/null
+++ /trunk/test/peripheral/usb/test_usb_bootloader_autostart.jal        Mon Aug 
10  
14:12:58 2009
@@ -0,0 +1,670 @@
+-- Title: USB (legacy) bootloader
+-- Author: Albert Faber, Copyright (c) 2009, all rights reserved.
+-- Adapted-by: -
+-- Compiler: >=2.4j
+--
+-- This file is part of jallib (http://jallib.googlecode.com)
+-- Released under the BSD license  
(http://www.opensource.org/licenses/bsd-license.php)
+--
+-- Description: This application implements the Microchip PDF/USB  
bootloader (legacy)
+-- The compiled code shall fit in the first 1024 words 0x0000..0x0800
+-- The booloader checks the bootloader_program_pin, if it is low at  
initialization time
+-- the bootloader will be activated, otherwise the user program (starting  
at 0x800) is
+-- executed. Currently only the high priority interrupts are supported,  
since JAL does
+-- not support low priority interrupts. When the bootloader is active, he  
PDFSUSB utility
+-- can be used to program the flase (from 0x800 and onwards), eeprom and  
configuration data
+--
+--
+-- Sources: http://www.microchip.org for PICDEM specifications
+--
+-- Notes: compiled with following flags
+--     use -no-variable-reuse when debugging flags are
+--  set due to a compiler issue
+--
+-- -----------------------------------------------------
+--
+
+-- whether or not using the serial port
+-- const HAS_SERIAL_DEBUG_PORT = 1
+-- const STUB_ERASE = 1
+-- const STUB_WRITE_FLASH = 1
+
+-- needed to get compact code, bootloader has to
+-- fit within first 2048 bytes in order to be
+-- compatible with default of PDFSUSB
+-- currently only 2 bytes left (2022 bytes)
+PRAGMA OPT CONST_DETECT YES
+
+
+
+;@jallib use chipdef
+
+
+;@jallib use bootloader
+
+
+const byte READ_VERSION    = 0x00
+const byte READ_FLASH      = 0x01
+const byte WRITE_FLASH     = 0x02
+const byte ERASE_FLASH     = 0x03
+const byte READ_EEDATA     = 0x04
+const byte WRITE_EEDATA    = 0x05
+const byte READ_CONFIG     = 0x06
+const byte WRITE_CONFIG    = 0x07
+const byte UPDATE_LED      = 0x32
+const byte RESET           = 0xFF
+
+const byte MINOR_VERSION   = 0x14    -- Bootloader Version 1.20
+const byte MAJOR_VERSION   = 0x01
+
+
+if defined( HAS_SERIAL_DEBUG_PORT ) == true then
+
+       const serial_hw_baudrate = 115_200
+
+       include serial_hardware
+       include format
+       include print
+
+       -- intialze serial device
+       serial_hw_init()
+
+       -- uncomment when directly coupled (i.e. without max 232) to rs-232C
+       -- BAUDCON_CKTXP = true
+
+       procedure serial_print_spc() is
+               serial_hw_write( " " )
+       end procedure
+
+       procedure serial_newline() is
+               serial_hw_write( 10 )
+               -- serial_hw_write( 13 )
+       end procedure
+
+       procedure print_nibble( byte in nibble ) is
+
+               if nibble > 9 then
+                       nibble = nibble + ( "A" - 10 )
+               else
+                       nibble = nibble + ( "0" )
+               end if
+               serial_hw_data = nibble
+       end procedure
+
+       procedure print_hex( byte in bt ) is
+               var byte nibble = bt >> 4
+               print_nibble( nibble )
+               nibble = bt & 0x0F
+               print_nibble( nibble )
+       end procedure
+
+       const bit USB_DEBUG = false
+       const bit USB_HID_DEBUG = true
+       const bit ADD_RW_OFFSET = true
+else
+       const bit USB_DEBUG = false
+       const bit USB_HID_DEBUG = false
+
+end if
+
+const bit USB_DEBUG_HIGH = USB_DEBUG
+const bit USB_HID_DEBUG_HIGH = USB_DEBUG
+
+include usb_defs
+
+const byte USB_EP0_OUT_SIZE = 8
+const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
+const byte USB_EP0_IN_SIZE  = 8
+const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )
+
+const bit USB_EP1 = 1
+const byte USB_EP1_OUT_SIZE = 64
+const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
+const byte USB_EP1_IN_SIZE  = USB_EP1_OUT_SIZE
+const word USB_EP1_IN_ADDR  = USB_EP1_OUT_ADDR -- point to the same buffer!
+
+var volatile byte  usb_ep1in_buf[ USB_EP1_IN_SIZE ] at USB_EP1_IN_ADDR
+var volatile byte  usb_ep1out_buf[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR
+var volatile byte  boot_cmd_buffer[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR
+
+
+-- *********************************************************************
+-- * General Data Packet Structure:
+-- * .
+-- * __________________           boot_cmd fields
+-- * |    COMMAND     |   0       [CMD]
+-- * |      LEN       |   1       [LEN]
+-- * |     ADDRL      |   2       [        ]  [addrl]
+-- * |     ADDRH      |   3       [ADR.pAdr]: [addrh]
+-- * |     ADDRU      |   4       [        ]  [addru]
+-- * |                |   5       [DATA]
+-- * |                |
+-- * .      DATA      .
+-- * .                .
+-- * |                |   62
+-- * |________________|   63
+-- *
+-- ********************************************************************/
+var volatile byte  boot_cmd_cmd at boot_cmd_buffer[0]
+var volatile byte  boot_cmd_len at boot_cmd_buffer[1]
+var volatile byte  boot_cmd_addrl at boot_cmd_buffer[2]
+var volatile byte  boot_cmd_addrh at boot_cmd_buffer[3]
+var volatile byte  boot_cmd_addru at boot_cmd_buffer[4]
+var volatile byte  boot_cmd_data[USB_EP1_OUT_SIZE-6] at boot_cmd_buffer[5]
+
+const bit USB_EP2 = 0
+const byte USB_EP2_OUT_SIZE = 8
+const word USB_EP2_OUT_ADDR = 0x0000
+const byte USB_EP2_IN_SIZE  = 8
+const word USB_EP2_IN_ADDR  = 0x0000
+
+const bit USB_EP3 = 0
+const byte USB_EP3_OUT_SIZE = 8
+const word USB_EP3_OUT_ADDR = 0x0000
+const byte USB_EP3_IN_SIZE = 8
+const word USB_EP3_IN_ADDR  = 0x0000
+
+
+const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
+       USB_DEVICE_DESCRIPTOR_SIZE,     -- 18 bytes long
+       USB_DT_DEVICE,  -- DEVICE 01h
+       0x00,
+       0x02,           -- usb version 2.00
+       0x00,           -- class
+       0x00,           -- subclass
+       0x00,           -- protocol
+       USB_EP0_OUT_SIZE,               -- max packet size for end point 0
+       0xd8,
+       0x04,           -- Microchip's vendor
+       0x0b,
+       0x00,           -- Microchip bootloader
+       0x01,
+       0x00,        -- version 1.0 of the product
+       0x00,           -- string 1 for manufacturer
+       0x00,           -- string 2 for product
+       0x00,           -- string 3 for serial number
+       0x01            -- number of configurations
+}
+
+const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x07 + 0x07
+
+const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE  
]=
+{
+       -- configuration descriptor - - - - - - - - - -
+       0x09,   -- length,
+       USB_DT_CONFIGURATION,   -- descriptor_type
+
+       USB_CONFIGURATION_DESCRIPTOR_SIZE,
+       0x00,   -- total_length;
+
+       0x01,   -- num_interfaces,
+       0x01,   -- configuration_value,
+       0x00,   -- configuration_string_id,
+       0b10000000, -- attributes (bus powered, no remote wake up)
+       100,    -- max_power; (200ma)
+
+       -- interface descriptor - - - - - - - - - - - -
+       0x09,                                           -- length,
+       USB_DT_INTERFACE,                       -- descriptor_type,
+       0x00,                                           -- interface_number, 
(starts at zero)
+       0x00,                                           -- alternate_setting, 
(no alternatives)
+       0x02,                                           -- num_endpoints,
+       0x00,                                           -- interface_class,
+       0x00,                                           -- interface_subclass,
+       0x00,                                           -- interface_protocol,
+       0x00,                                           -- interface_string_id;
+
+       -- endpoint descriptor(s)  - - - - - - - - - - - -
+       0x07,                           -- length,
+       USB_DT_ENDPOINT,        -- descriptor_type,
+       0b10000001,                     -- endpoint_address, (Endpoint 1, IN)
+       USB_EPT_BULK,           -- attributes
+       USB_EP1_IN_SIZE,
+       0x00,                           -- max_packet_size
+       0x00,                           -- interval
+
+       0x07,                           -- length,
+       USB_DT_ENDPOINT,        -- descriptor_type,
+       0b00000001,                     -- endpoint_address, (Endpoint 1, OUT)
+       USB_EPT_BULK,           -- attributes
+       USB_EP1_OUT_SIZE,
+       0x00,                           -- max_packet_size
+       0x00                            -- interval
+}
+
+const byte USB_STRING0[] =
+{
+       0x04,   -- bLength
+       USB_DT_STRING,  -- bDescriptorType
+       0x09,   -- wLANGID[0] (low byte)
+       0x04    -- wLANGID[0] (high byte)
+}
+
+include usb_drv_core
+
+
+procedure trigger_dev2host_transfer() is
+       var volatile bit dts_bit at usb_bd1in_stat : USB_BDSTATUS_DTS
+--     var volatile bit uown_bit_out at usb_bd1in_stat : USB_BDSTATUS_UOWN
+
+       if ( dts_bit  ) then
+               usb_bd1in_stat = 0b_1000_1000
+       else
+               usb_bd1in_stat = 0b_1100_1000
+       end if
+end procedure
+
+
+
+procedure start_write() is
+    EECON2 = 0x55
+    EECON2 = 0xAA
+    EECON1_WR = 1
+       if USB_HID_DEBUG then
+        serial_hw_data = "S"
+        serial_hw_data = "W"
+               serial_hw_data = " "
+               serial_hw_data = " "
+               print_hex( TBLPTRU )
+               print_hex( TBLPTRH )
+               print_hex( TBLPTRL )
+               serial_hw_data = 10
+               serial_hw_data = 13
+       end if
+end procedure
+
+procedure set_boot_address() is
+       -- pragma inline
+       TBLPTRU = boot_cmd_addru
+       TBLPTRH = boot_cmd_addrh
+       TBLPTRL = boot_cmd_addrl
+
+       if defined( ADD_RW_OFFSET ) == true then
+               TBLPTRH = TBLPTRH + 0x10
+       end if
+
+end procedure
+
+procedure disable_boot() is
+       var word big_counter = 0xFFFF
+
+       -- disable timer 1
+       T1CON = 0x00
+
+       -- disable USB
+       UCON = 0x00
+
+       -- force timeout on USB
+       while big_counter != 0  loop
+               big_counter = big_counter - 1
+       end loop
+end procedure
+
+
+procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr,  
byte in byte_count) is
+       pragma inline
+    var byte cdc_rx_next
+
+       -- if USB_HID_DEBUG then
+       if false then
+               var byte idx
+        const byte str[] = " EP data out: "
+        const byte str1[] = " bytes "
+        print_string(serial_hw_data,str)
+        print_hex( byte_count )
+        print_string(serial_hw_data,str1)
+        for byte_count using idx loop
+                       print_hex( boot_cmd_buffer[ idx ] )
+        end loop
+    end if
+
+       if USB_HID_DEBUG then
+               serial_hw_data = "C"
+               serial_hw_data = "M"
+               serial_hw_data = "D"
+               serial_hw_data = " "
+
+               print_hex( boot_cmd_cmd )
+               serial_hw_data = " "
+               print_hex( boot_cmd_len )
+               serial_hw_data = " "
+               print_hex( boot_cmd_addru )
+               print_hex( boot_cmd_addrh )
+               print_hex( boot_cmd_addrl )
+               serial_hw_data = " "
+    end if
+
+    usb_bd1in_cnt = 0x00
+
+    case boot_cmd_cmd of
+               READ_VERSION:
+               block
+                       boot_cmd_buffer[2] = MINOR_VERSION;
+                       boot_cmd_buffer[3] = MAJOR_VERSION;
+                       usb_bd1in_cnt = 4
+                       T1CON = 0b0000_0000 -- disable timer 1
+               end block
+
+               READ_EEDATA:
+               block
+if true then
+
+
+                       if defined( EECON1_EEPGD ) == true then
+                               var byte counter
+                               EECON1_EEPGD = 0
+                               EECON1_CFGS = 0
+
+                               if USB_HID_DEBUG then
+                                       serial_hw_data = "R"
+                                       serial_hw_data = "E"
+                                       serial_hw_data = ":"
+                                       serial_hw_data = " "
+                                       print_hex( TBLPTRU )
+                                       print_hex( TBLPTRH )
+                                       print_hex( TBLPTRL )
+                                       serial_hw_data = 10
+                                       serial_hw_data = 13
+                               end if
+
+                               for boot_cmd_len using counter loop
+                                       EEADR = boot_cmd_addrl + counter
+                                       -- EEADRH = byte( (word(boot_cmd_addrl) 
+ word(counter) ) >> 8)
+                                       EECON1_RD = 1;
+                                       boot_cmd_data[ counter ] = EEDATA
+                               end loop
+                       end if
+end if
+
+                       usb_bd1in_cnt = 5 + boot_cmd_len
+
+               end block
+
+               READ_FLASH,READ_CONFIG:
+               block
+                       set_boot_address()
+
+                       if USB_HID_DEBUG then
+                               serial_hw_data = "R"
+                               serial_hw_data = "F"
+                               serial_hw_data = ":"
+                               serial_hw_data = " "
+                               print_hex( TBLPTRU )
+                               print_hex( TBLPTRH )
+                               print_hex( TBLPTRL )
+                               serial_hw_data = 10
+                               serial_hw_data = 13
+                       end if
+
+                       if defined( STUB_READ ) == false then
+                               var byte counter
+                               for boot_cmd_len using counter loop
+                                       asm TBLRD*+
+                                       boot_cmd_data[ counter ] = TABLAT
+                               end loop
+                       end if
+
+                       usb_bd1in_cnt = 5 + boot_cmd_len
+               end block
+               WRITE_FLASH:
+               block
+                        -- * The write holding register for the 18F4550 family 
is
+                        -- * actually 32-byte. The code below only tries to 
write
+                        -- * 16-byte because the GUI program only sends out 
16-byte
+                        -- * at a time.
+                        -- * This limitation will be fixed in the future 
version.
+                       EECON1 = 0b_1000_0100 -- Setup writes: EEPGD=1,WREN=1
+
+                       set_boot_address()
+
+                       TBLPTRL = ( TBLPTRL & 0xF0 )   -- Force 16-byte boundary
+
+                       if USB_HID_DEBUG then
+                               serial_hw_data = "W"
+                               serial_hw_data = "F"
+                               serial_hw_data = ":"
+                               serial_hw_data = " "
+                               print_hex( TBLPTRU )
+                               print_hex( TBLPTRH )
+                               print_hex( TBLPTRL )
+                               serial_hw_data = 10
+                               serial_hw_data = 13
+                       end if
+
+                       if defined( STUB_WRITE_FLASH ) == false then
+                               var volatile byte counter
+                               for boot_cmd_len using counter loop
+                                       TABLAT = boot_cmd_data[ counter ]
+
+                                       if USB_HID_DEBUG then
+                                               serial_hw_data = " "
+                                               print_hex(TABLAT)
+                                       end if
+
+                                       asm TBLWT*+
+
+                                       if ((counter & 0x0F ) == 0x0F ) then
+                                               asm TBLRD*-
+                                               start_write()
+                                       end if
+                               end loop
+                       end if
+
+                       usb_bd1in_cnt = 1
+
+               end block
+               ERASE_FLASH:
+               block
+                       -- The most significant 16 bits of the address pointer 
points to the  
block
+                       -- being erased. Bits5:0 are ignored. (In hardware).
+
+                       -- LEN = # of 64-byte block to erase
+                       -- Setup writes: EEPGD=1,FREE=1,WREN=1
+                       EECON1 = 0b10010100
+
+                       set_boot_address()
+
+                       if USB_HID_DEBUG then
+                               serial_hw_data = "E"
+                               serial_hw_data = "F"
+                               serial_hw_data = ":"
+                               serial_hw_data = " "
+                               print_hex( TBLPTRU )
+                               print_hex( TBLPTRH )
+                               print_hex( TBLPTRL )
+                               serial_hw_data = 10
+                               serial_hw_data = 13
+                       end if
+
+                       if defined( STUB_ERASE ) == false then
+                               var byte counter
+                               for boot_cmd_len using counter loop
+                                       start_write();
+                                       TBLPTRL = TBLPTRL + 32
+                                       if TBLPTRL == 0 then
+                                               TBLPTRH = TBLPTRH + 1
+                                       end if
+                               end loop
+                               -- TBLPTRU = 0
+                       end if
+
+                       usb_bd1in_cnt = 1
+               end block
+
+
+               WRITE_EEDATA:
+               block
+if true then
+
+                       if defined( EECON1_EEPGD ) == true then
+
+                               var byte counter
+                               for boot_cmd_len using counter loop
+                                       EEADR = boot_cmd_addrl + counter
+                                       -- EEADRH = byte( (word(boot_cmd_addrl) 
+ word(counter) ) >> 8)
+                                       EEDATA = boot_cmd_data[ counter ]
+                                       start_write()
+                                       while ( EECON1_WR ) loop
+                                       end loop
+                               end loop
+                       end if
+end if
+                       usb_bd1in_cnt = 1
+               end block
+
+
+               WRITE_CONFIG:
+               block
+
+                       -- * The write holding register for the 18F4550 family 
is
+                       -- * actually 32-byte. The code below only tries to 
write
+                       -- * 16-byte because the GUI program only sends out 
16-byte
+                       -- * at a time.
+                       -- * This limitation will be fixed in the future 
version.
+                       EECON1 = 0b10000100                                     
                        -- Setup writes: EEPGD=1,WREN=1
+
+                       set_boot_address()
+
+                       var byte counter
+                       for boot_cmd_len using counter loop
+                               TABLAT = boot_cmd_data[ counter ]
+
+                               if USB_HID_DEBUG then
+                                       serial_hw_data = " "
+                                       print_hex( TABLAT )
+                               end if
+
+                               asm TBLWT*
+                               start_write()
+                               asm TBLWT*+
+                       end loop
+
+                       usb_bd1in_cnt = 1
+
+               end block
+
+               UPDATE_LED:
+               block
+
+               end block
+
+               RESET:
+                       block
+                               disable_boot()
+                               -- asm reset
+                               asm goto 0x800
+                       end block
+    end case
+
+
+    if usb_bd1in_cnt > 0 then
+               -- if defined( HAS_SERIAL_DEBUG_PORT ) == true then
+               if false then
+                       const byte str4[] = " XFER BYTES "
+                       print_string(serial_hw_data,str4)
+                       print_hex( usb_bd1in_cnt )
+                       serial_hw_data = " "
+                       serial_hw_data = "T"
+                       serial_hw_data = "0"
+                       serial_hw_data = " "
+                       print_hex( usb_bd1in_addrh )
+                       print_hex( usb_bd1in_addrl )
+
+               end if
+               trigger_dev2host_transfer()
+    end if
+
+       usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )
+
+end procedure
+
+
+include usb_drv
+
+
+-- constants
+-- const  byte str_welcome[] = "JAL USB BOOTLOADER 0.10\n"
+
+-- variables
+
+
+procedure usb_tasks() is
+       pragma inline
+    usb_handle_isr()
+end procedure
+
+-- interrupts? No thanks
+-- INTCON_GIE = false
+
+if defined( HAS_SERIAL_DEBUG_PORT ) == high then
+       -- put info on RS-232 serial line
+       serial_newline()
+       serial_newline()
+
+       -- print_string(serial_hw_data, str_welcome )
+       serial_newline()
+end if
+
+procedure interrupt_high() is
+       pragma interrupt raw
+       asm goto ( 0x0818 )
+end procedure
+
+-- read first byte of USER ID
+-- TBLPTRU = 0x20
+-- TBLPTRH = 0x00
+-- TBLPTRL = 0x00
+--asm TBLRD*+
+
+--if ( TABLAT != 0x00 ) then
+-- if ( false) then
+--     asm goto ( 0x800)
+--else
+       -- setup the USB device
+       usb_setup()
+
+       -- enable USB device
+       usb_enable_module()
+--end if
+
+usb_bd1in_addr = USB_EP1_IN_ADDR
+
+T1CON = 0b0011_0001 -- timer 1 on, prescaler 8
+
+var byte t1_count = 0
+
+-- main loop
+forever loop
+       -- poll the usb ISR function on a regular base, in order to
+       -- serve the USB requests
+    usb_handle_isr()
+       if defined( HAS_SERIAL_DEBUG_PORT ) == true then
+               if PIR1_RCIF then
+               end if
+       end if
+
+       if PIR1_TMR1IF == 1 then
+               t1_count = t1_count + 1
+               PIR1_TMR1IF = 0
+
+               -- 22 counts per second, ~10 seconds wait => 220 ticks
+               -- if expired,
+               if t1_count > 220 then
+                       -- set ID 0
+                       -- EECON1 = 0b_1000_0100 -- Setup writes: EEPGD=1,WREN=1
+
+                       -- TBLPTRU = 0x20
+                       -- TBLPTRH = 0x00
+                       -- TBLPTRL = 0x00
+                       -- TABLAT  = 0x00
+                       -- asm TBLWT*+
+                       -- start_write()
+                       disable_boot()
+
+
+                       -- start user app
+                       asm goto 0x800
+
+               end if
+       end if
+end loop
=======================================
--- /trunk/test/peripheral/usb/test_usb_bootloader.jal  Wed Jun  3 16:05:08  
2009
+++ /trunk/test/peripheral/usb/test_usb_bootloader.jal  Mon Aug 10 14:12:58  
2009
@@ -525,7 +525,7 @@
                                while big_counter != 0  loop
                                        big_counter = big_counter - 1
                                end loop
-                               -- TODO, NOT SUPPORTED YET asm reset
+                               asm reset
                        end block
      end case

@@ -588,13 +588,13 @@

  procedure interrupt_high() is
        pragma interrupt raw
-       asm goto ( 0x0818 / 2 )
+       asm goto 0x0818
  end procedure

  if ( bootloader_program_pin == high ) then
  -- if ( false) then
        ADCON1 = saved_adcon
-       asm goto ( 0x800 / 2 )
+       asm goto 0x800
  else
        -- setup the USB device
        usb_setup()

--~--~---------~--~----~------------~-------~--~----~
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