Trying building a USB HID Bootloader for 18F14K50

Post Reply
Author
Message
Henk van Beek
Posts: 97
Joined: 11 Mar 2005 11:14
Location: Breda, The Netherlands

Trying building a USB HID Bootloader for 18F14K50

#1 Post by Henk van Beek » 15 Feb 2018 18:11

Hello,
I'm working with Pascal pro version 7.0.0
I wanna create USB HID Bootloader firmware for Pic18F14K50.
I've changed the USB-Ram locations in Config.mpas to accomodate this chip. No success
Then I tried the example to build the default one for 18F2550 and it does not work. I tested it on a StartUSB.
Can someone be of help ?
What God wants, God gets.

solveering
Posts: 11
Joined: 15 Aug 2012 21:04

Re: Trying building a USB HID Bootloader for 18F14K50

#2 Post by solveering » 16 Feb 2018 02:34

I've been meddling with a HID Bootloader for the 18F25K50 which should be similar enough. First off, get the project from the examples (C:\Users\Public\Documents\Mikroelektronika\mikroBasic PRO for PIC\Examples\Other) for me (I'm using mikroBasic, so change your location to whatever applicable) and you should find the HID Bootloader folder there (not the regular Bootloader as that uses UART/serial - works better but obviously not what you are looking for).
My approach is to usually copy/paste to a new folder and then edit any information in the group/project file using Notepad++ (excellent notepad application IMHO).
No on to the issues/things I've discovered that may help you:
Prior to the Config() method call in main (these may look different in Pascal, but you'll get the idea), you may need to initialize your MCU. Things such as setting your TRISx bits, ANSELx, etc. and most likely your OSCCON register if you are running from a non-default configuration (In my view, don't assume anything is set correctly and go through all the important registers during initialization. The datasheet is your friend here).
Also, you may need to turn on the USB module. With the 25K50, this is done by setting the USBMD bit to zero.
For proper debugging, I strongly recommend you have an LED available on a pin and flash it for a known amount of time at this point. I can't count the number of times I was looking for a bug only to find that the FOSC was off by a factor of 2x or similar. Blink a LED for 1second and you'll notice if it 1) Doesn't. 2) stays on for 2,4 etc. seconds or less. I've made it a point that any custom design that I put together has at least one LED even if the device is not visible. There is nothing worse than having to solder wires to a board only to be able to get a 'it works' type of feedback..
On to some items I've discovered:
For one, I don't like the use of the USB_Polling_Proc, I far prefer the Interrupt handler. But I did not want to mess with this too much. The polling should be done approx. once every 100 uSec (per their help files), strangely, the firmware is set up to only do it once every 1mSec... So I changed that part (using a Delay_us(100) rather than Delay_1ms and then setting Timer to 50000 to adjust).
Also, if you have re-created the USBdsc file, you will need to modify it to set USB_INTERRRUPT as char =0 since the interrupt handler isn't used. Notice that you need to keep the descriptor as it is (USB HID Bootloader), otherwise the ME HID bootloader software does not work.
A few more items:
I removed the #I ..// item in the Config file and declared the procedures directly (i.e. copy/paste the content from that file into the Config section at the top).
Depending on your PIC, you'll need to change the FLASH_Write_32 method with FLASH_Erase_Write_64.
Also, in the UHB_Driver file, I found that sometimes the application would hang, possibly due to the HID_Write in the SendBootInfo (I replaced it with a Loop that would repeat until HID_Write would return a value other than 0).
On more thing. In the Config file, towards the top, there is a section

Code: Select all

const BootInfo as TBootInfo = (sizeof(TBootInfo),                    ' This record's size in bytes.
                               (bifMCUTYPE,    MCU_TYPE),            ' MCU family.
                               (bifMCUSIZE,    __FLASH_SIZE),        ' MCU flash size.
                               (bifERASEBLOCK, FLASH_ERASE_BLOCK),   ' MCU Flash erase block size in bytes.
                               (bifWRITEBLOCK, FLASH_WRITE_BLOCK),   ' MCU Flash write block size in bytes.
                               (bifBOOTREV,    BOOTLOADER_REVISION), ' Version of bootlaoder firmware.
                               (bifBOOTSTART,  BOOTLOADER_START),    ' Bootloader code start address.
                               (bifDEVDSC,     DEVICE_NAME)          ' Name of this device.
                              )
For some reason, the IDE shows an error (but does compile), so I changed the BootInfo to a variable and then defined it during the ConfigMem method:

Code: Select all

sub procedure ConfigMem()
  OrgAll(BOOTLOADER_START-RESET_VECTOR_SIZE)
  SetOrg(main, BOOTLOADER_START)
  SetOrg(StartProgram, BOOTLOADER_START-RESET_VECTOR_SIZE)
  if (@Reserve4thBankForUSB) then
  end if
  
  BootInfo.bSize        = btSize
  BootInfo.bMcuType     = mcuFamily
  BootInfo.ulMcuSize    = mcuFlashSize
  BootInfo.uiEraseBlock = mcuFlashEraseSize
  BootInfo.uiWriteBlock = mcuFlashWriteSize
  BootInfo.uiBootRev    = blVers
  BootInfo.ulBootStart  = blStart
  BootInfo.sDevDsc      = devName
  
end sub
I have no idea whether all of these changes are required or not. But these are the changes I made, at it appears to work now...

Let me know if you get it to work on your end. I'd be interested what changes are required to make this work with a 14K50.

Henk van Beek
Posts: 97
Joined: 11 Mar 2005 11:14
Location: Breda, The Netherlands

Re: Trying building a USB HID Bootloader for 18F14K50

#3 Post by Henk van Beek » 16 Feb 2018 09:47

Thanks for the tips.
I'll let you know my findings.
What God wants, God gets.

Henk van Beek
Posts: 97
Joined: 11 Mar 2005 11:14
Location: Breda, The Netherlands

Re: Trying building a USB HID Bootloader for 18F14K50

#4 Post by Henk van Beek » 17 Feb 2018 18:18

@Solveering:

I implemented your suggestions as follows:
  • Added a LED so I can verify the speed of the MCU
    Added a Serial terminal at 115200 baud
    replaced the polling procedure by the interrupt driven one.
Now it is recognised by the me-program. But it does not tell "connected". It hangs.
Var "dataRx" is always 0, I can see that in my serial terminal. In polling-mode and in interrupt mode.
But I am not shure of setting the USB-ram.
The 18F14K50 has only one 256-bytes USB-ram from 0x200 up to 0x2FF.
So I declared as follows:

Code: Select all

var HidReadBuff: array[64] of byte;  absolute 0x200;          // USB HID read buffer.
    HidWriteBuff: array[64] of byte; absolute 0x240;          // USB HID write buffer.
    Reserve4thBankForUSB: array[256] of byte; absolute 0x200; // Dummy allocation of 4th bank
                                                              //   (used by USB module internaly),
                                                              //   to prevent compiler from allocating
                                                              //   ram variables there.

I'm hoping you can elighten me.
What God wants, God gets.

solveering
Posts: 11
Joined: 15 Aug 2012 21:04

Re: Trying building a USB HID Bootloader for 18F14K50

#5 Post by solveering » 19 Feb 2018 16:05

Quite frankly, I'm not sure if the interrupt procedure will work better than the polling approach. My preference is to use interrupts for things like this to keep things event driven rather than time/loop based. But if you follow debug practices, you may want to first implement as-is before making changes.
That being said, here a few items to consider:
- Before getting into the bootloader side of things (so just before the "if EnterBootloaderMode()=0" or similar call), I recommend you add a section to first test your USB interface. This could look something like this:

Code: Select all

While True
        While(HID_Read() = 0)
        Wend
        HIDWriteBuff=HIDReadBuff
        While(HID_Write(@writebuff,64) = 0)
        Wend
Wend
(obviously you'll need to update this from basic to pascal and modify any variable names. Also, this is the approach used for the interrupt approach, add a USB_Polling_Proc call and delay_us(100) if using the polling).
From this you'll get information about whether or not your USB communication works (it will echo the received info). The HID terminal is good for this... even though it has an annoying 'feature' where if you disconnect the device and then re-connect you'll need to re-select the device, otherwise it crashes. But the important part is that you can debug whether it is an issue with USB or something down-stream (divide and conquer approach to troubleshooting).

- Assuming this works, take a look at anything that can cause delays. USB is somewhat tricky when it comes to delays (another reason I prefer interrupts) so make sure there is nothing there that pauses when there should be some reply being sent (make sure your UART terminal does not block USB).
- I have found that the delay being used by the polling approach of 1ms delay can cause some issues and have opted for a 100us instead.
- I would recommend using the ICD to debug this step by step.... however, the mikroProg ICD is a POS (IMHO). I have found it to work moderately well for stepping through code line by line for simple stuff (where you usually don't need an ICD) but it fails to work for more difficult scenarios (like USB/etc.). Lacking that, I resort to my useful LED to show me a 'blinking' (or solid ON for conditions) message at certain steps so that I know when it reaches that point. If you gradually move the LED indication along the path you think it should be taking, you'll find where it deviates from that path and can perhaps take action to fix the issue there...

Anyway, keep posting updates on this... I'd be interested to hear where the LED shows a deviation.

Henk van Beek
Posts: 97
Joined: 11 Mar 2005 11:14
Location: Breda, The Netherlands

Re: Trying building a USB HID Bootloader for 18F14K50

#6 Post by Henk van Beek » 20 Feb 2018 14:36

@Solveering,

I tried several suggestions but it is too difficult to me. So, I went to the libstock and found one for the 14K50 wich was ready.
So, I gave up to make it my own.
Maybe I will figure out the sources (in Basic) in the future.
Thanks for your help.
What God wants, God gets.

Post Reply

Return to “mikroBootloader”