News:

;) This forum is the property of Proton software developers

Main Menu

dsPIC33CK bootloader ?

Started by diebobo, Oct 19, 2023, 04:42 PM

Previous topic - Next topic

RGV250

QuoteWimax, take a look at the Northern software programmer/Chip/Bootloader.  HERE
Hi Jon,
The chip version seems to good to be true, really cheap. Unfortunately for me, small quantities get dwarfed by the cost of shipping. Do you know if they have distributors in Europe or UK?

Bob

JonW

#21
No, I don't, unfortunately, as I tend to use 8-bit parts and build my own HID and CDC USB device using the same chip and run a bootloader from Evan Venn.  Perhaps there are enough people on here who would be willing to split the cost with you?

I have written USB HID and CDC firmware for the 16F1454, and it is available for around $1 in small quantities and approximately 70 cents in volume, making the price fair for both the code and the PC software. It's not an expensive MCU and Microchip use it for their USB to Uart devices.  I would imagine it has taken a significant amount of development time to get the PC side right.  There is not much RAM left on those small MCUs after you have a USB stack on there, so I presume they leave the bulk of the processing to the PC side and use small buffers.

Wimax

I very much doubt they would be available via LCSC. It would be ideal if they were.  Maybe if someone who had a UK company selling boards (like John L), could contact them with a possibility to sell under license or provide the hex under NDA to be sold in the UK/EU.  I would be doubtful, though, as this would be extremely hard to monitor and control. They may provide a quantity for free issue, though, to be sold locally, as the cost is relatively small.


JonW

The reason I don't use them is that the stack doesn't come up as a CDC device, as it uses HID, thus any PC side software will need to use their drivers.  With AI now, this shouldn't be a problem for a modest coder.

Fanie

#23
Tinybootloader.
It does not support the 33 pics, however, I'm sure it could still work for the 33's if you find a 30 pic that is similar.  If the bootloader simply perform the programming then the bootloader should do that, and does not concern itself with what extended functions the micro have.

Similarly you need not change the pic you program with a programmer if the structure is similar, ie the 12F683, 16F684 and others can be programmed without selecting that specific pic, as long as your code does not exceed the pic's program space, and if of course connected to the required program pins.

QuoteProgramming: (dsPIC33) Uses the same XC16 compiler as PIC24, but requires special functions (e.g., from the libq library or built-in functions) to access the DSP engine.

There is a list of other bootloaders on the page too.
http://www.etc.ugal.ro/cchiculita/software/picbootloader.htm


Fanie

QuoteThe structure for implementing a bootloader on both PIC24 and dsPIC33 microcontrollers is very similar because they share a common development ecosystem and memory architecture. Both families of devices can use the same MPLAB Code Configurator (MCC) 16-bit bootloader, which can be configured to run on either type of chip using a host application to transfer new code. The key difference lies in the application code itself, with the dsPIC33 being a Digital Signal Controller that can handle more complex DSP tasks, while the PIC24 is a general-purpose microcontroller.

QuoteThe main difference is that PIC33 (dsPIC33) and PIC30 are families that share a common bootloader architecture, including a two-part structure (target and host), but they may have different memory sizes and specific features like dual-partition flash, which affect the bootloader's configuration and placement. Implementing a bootloader is a standard process for both families, involving reserving memory, typically a "boot block," for the bootloader code and using a communication interface like UART or CAN for the host to send new firmware.

Wimax

News from Northern: they can ship NSDSP chips directly to PCB manufacturer in order to be parts of the bom for pcb assembly.

Fanie

Micro Robotics in .ZA is selling these kits.  My brother said he used more than 400 of them already with 0 problems.
At 70c it is a bargain for you.  Order some from them and resell there.
https://www.robotics.org.za/CH340G-KIT?search=CH340G

John Lawton

Hi Fanie,

good price, some other CH340 models don't even need a crystal, see my Amicus boards schematics https://easy-driver.co.uk/Amicus/

Can Robotics.org.za export stuff to the UK reliably, you've often said how difficult it is for you to import parts?

John

Fanie

There is an even cheaper and smaller one with built-in oscillator, I just saw it.
https://www.robotics.org.za/CH340N-SOP-8
CH340N USB to Serial Converter

I'm sure the owner of micro robotics will ship to you without problems.
If I need something he brings it in for me.  I can give you his contact number and you can whatsapp him.

It is not from China where the problem is, it is from the USA and Europe.  I was looking for something and they notified me there is sanctions on Sick Africa (which is a hoax), and they won't send to me.

Fanie

See in your PM if you got the contact ?

Wimax

#30
Hello Everybody !  ;)

After several days spent implementing an XModem-128 CRC reception protocol and, above all, struggling with the flash memory of the dspic33ck256mp508, I managed to create a mixed Positron24/Assembler code capable of receiving 128-byte packets from the PC with CRC control, recombining them into triplets of 384 bytes compatible with the flash row structure, writing them to the flash memory starting from address 0x2000 using the double program word approach. The firmware is developed on the Curiosity board (just change the uart pins and modify or delete the commands for the LEDs). I tested it with TeraTerm, keeping the baud rate deliberately low, and it seems to work well. As it is currently structured, it can receive any type of file, as long as it is a multiple of 384 bytes in length (for simplicity, I did not include internal padding for the moment). The programme waits for the file to be received via XModem-128 CRC for a few seconds after the reset. If it receives the start character, it launches the transfer.
Being designed for bootloader functionality, it does not use libraries (which I really missed...), and all the code is written in line without any procedures.
At this point, I am trying to understand how to modify the "gld" files for the linker. I believe that Positron24 uses the "gld" file in the installation directory (the original one) for the linker and does not take it from the working directory as it does for the "inc" files. During testing, I risked corrupting the original file several times. I believe that modifying the "gld" file is absolutely necessary for both the bootloader and the application in order to correctly remap the memory, interrupt vectors, disable any allocations for fuses (if necessary), etc.
In theory, starting from the hex file with the correct structure, with records without jumps, the next step is to generate a binary file of minimum size, using hex2bin for example, ready to be transferred to the micro.
At the moment, I am still trying to modify the "gld" effectively, as the information found online is sometimes contradictory. I continue to have Hex files with out-of-order records with blocks of the type:
0000 - 0007
0018 - 001B
as well as a main block that does not match the origin declared in the gld and inside Positron with "org" directive (I tried with a very simple target program to allocate starting from 0x2000).
If anyone has experience in this area, they are welcome to share it, and perhaps we can achieve a result that is useful to everyone.
The next step is to try a version that parses directly the hex file by commanding the writing/deletion of selected areas in flash, without having to act in sequential mode and without needing a suitably formatted bin file. Unless we shift the complexity of parsing to the microcontroller by limiting the transmission of only the hex file by the host, it is reasonable to do the opposite, but we would have to use special scripts created for this purpose. With the protocol details available, we could also consider using Microchip's Java unified bootloader tool... but that's just one of many ideas. In the meantime, we will try to solve the "rebus" of the gld file.


'****************************************************************
'*  Name    : Micro_boot_Max.bas                                *
'*  Author  : [Max]                                             *
'*  Notice  : Copyright (c) 2025                                *
'*          : All Rights Reserved                               *
'*  Date    : 26/10/2025                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************

Device = 33CK256MP508
Declare Xtal = 200

Declare Library_Core = Off ' No library

Symbol SOH = 0x01
Symbol EOT = 0x04
Symbol ACK = 0x06
Symbol NAK = 0x15
Symbol TIMEOUT_LOOPS = 500000000
Symbol CHAR_C = 67        ' 'C' ASCII = 67, richiede CRC mode al mittente
Dim data [128] As Byte
Dim i As Word
Dim j As Dword
Dim b As SWord
Dim blkNum As SWord
Dim blkNumComp As SWord
Dim sum As SWord
Dim attempts As SWord
Dim filePos As Dword
Dim crcCalc As Dword
Dim crcHi As SWord
Dim crcLo As SWord
Dim crcRecv As Dword
Dim k As Dword
Dim MCU_TBLPAG As Byte
Dim MCU_Code_Write_Offset As Word
Dim ausilio As Word
Dim numriga As Byte

'----------------
Dim crc As Word
Dim bot As Byte
Dim appoggio As Dword
Symbol BlockSize = 128
Symbol NumBlocks = 4

Dim FL As Byte
Dim ii As Word
Dim jj As Word
Dim bbc As Word
Dim ReadVal As Word
Dim WriteVal As Word
Dim FlashData[BlockSize] As Byte
Dim byte_buffer [384] As Byte
Dim contatore As Byte
Dim FlashStart As Dword

Org  0x0000             ' Bootloader initial address


__reset:
WDTCONLbits_ON=0
CLKDIV = $3001          ' FRCDIV FRC/1, PLLPRE 1, DOZE 1:8
PLLFBD = 100
OSCTUN = $00
PLLDIV = $21            ' POST1DIV 1:2, VCODIV FVCO/4, POST2DIV 1:1
ACLKCON1 = $0101        ' FRCSEL FRC, APLLPRE 1:1
APLLFBD1 = $C8
APLLDIV1 = $42          ' APOST1DIV 1:4, APOST2DIV 1:2, AVCODIV FVCO/4*)

Write_OSCCON($0301)
While OSCCONbits_OSWEN <> 0 : Wend      ' Wait for the clock switch to occur
While OSCCONbits_LOCK <> 1 : Wend       ' Wait for the oscillator to lock

TRISE.13=0
' Mappa UART1 TX su RD4 (RP68), RX su RD3 (RP67)

RPOR18bits_RP68R =1     ' UART1 TX function = 1 ? assigned to RP68 (RD4)
RPINR18bits_U1RXR=67    ' UART1 RX assigned to RP67 (RD3)
TRISD.4=0   ' RD4 as output (TX)
TRISD.3=1   ' RD3 as input (RX)

U1MODEL = %1000000000110000
U1BRGL  = 650
'U1BRGH = %00000010      ' 9600 bps
          '10001010
'U1BRGL = %10010001
          '00000010
U1MODEbits_UARTEN  = 1 'Enable uart
U1MODEbits_UTXEN   = 1 'Transmitter enabled
U1MODEbits_URXEN   = 1 'Receiver enabled

FlashStart=0x2000
MCU_TBLPAG =  (FlashStart >> 16) & 0xFF
MCU_Code_Write_Offset = FlashStart & 0xFFFF
contatore=0
filePos = 0
attempts = 0
numriga=0
FL=0

' Send 'C' to request sending in CRC mode
While U1STAHbits_UTXBF = 1 : Wend
U1TXREG = CHAR_C
While U1STAbits_TRMT = 0 : Wend

' Main receiving loop
While 1=1
LoopStart:
    'SOH/EOT wait with timeout
    j = 0
    b = -1
    While j < TIMEOUT_LOOPS
         While U1STAHbits_URXBE=1:Wend
        If U1STAHbits_URXBE = 0 Then
            If U1STAbits_OERR = 1 Then U1STAbits_OERR = 0
            b = U1RXREG & 0xFF
            Break
        EndIf
        j = j + 1
    Wend

    If b = -1 Then
        attempts = attempts + 1
        If attempts > 20 Then Break
        ' try again requesting CRC mode
        While U1STAHbits_UTXBF = 1 : Wend
        U1TXREG = CHAR_C
        While U1STAbits_TRMT = 0 : Wend
        GoTo LoopStart
    EndIf

    If b = EOT Then
        'End of transmission
        While U1STAHbits_UTXBF = 1 : Wend
        U1TXREG = ACK
        While U1STAbits_TRMT = 0 : Wend
        ' Send text confirmation "OK" using direct ASCII codes
        While U1STAHbits_UTXBF = 1 : Wend
        U1TXREG = 79    ' 'O' ASCII = 79
        While U1STAbits_TRMT = 0 : Wend
        While U1STAHbits_UTXBF = 1 : Wend
        U1TXREG = 75    ' 'K' ASCII = 75
        While U1STAbits_TRMT = 0 : Wend
        Break
        Toggle PORTE.13
        Toggle PORTE.6 
    EndIf

    If b <> SOH Then
        ' Unrecognized byte: request retransmission
        While U1STAHbits_UTXBF = 1 : Wend
        U1TXREG = NAK
        While U1STAbits_TRMT = 0 : Wend
        attempts = attempts + 1
        If attempts > 10 Then Break
        GoTo LoopStart
    EndIf

    If b = SOH Then
     
    ' Receive block number and complement
        j = 0
        blkNum = -1
        While j < TIMEOUT_LOOPS
            While U1STAHbits_URXBE=1:Wend
            If U1STAHbits_URXBF = 1 Then
                blkNum = U1RXREG & 0xFF
                Break
            EndIf
            j = j + 1
        Wend
        If blkNum = -1 Then
            While U1STAHbits_URXBE=1:Wend
            U1TXREG = NAK
            While U1STAbits_TRMT = 0 : Wend
            GoTo LoopStart
        EndIf
   
        j = 0
        blkNumComp = -1
        While j < TIMEOUT_LOOPS
            While U1STAHbits_URXBE=1:Wend
            If U1STAHbits_URXBF = 1 Then
                blkNumComp = U1RXREG & 0xFF
                Break
            EndIf
            j = j + 1
        Wend
        If blkNumComp = -1 Then
            While U1STAHbits_UTXBF = 1 : Wend
            U1TXREG = NAK
            While U1STAbits_TRMT = 0 : Wend
            GoTo LoopStart
        EndIf
   
   EndIf
     
    ' Receives 128 bytes and calculate CRC
    For i = 0 To 127
        j = 0 : b = -1
       
            While U1STAHbits_URXBE=1:Wend
                               
                If U1STAbits_OERR = 1 Then
                U1STAbits_OERR = 0
                EndIf
                b = U1RXREG & 0xFF
               
        data[i] = b & 0xFF
        ausilio=contatore*128+i 'Calculate the index of the second array, which will contain 384 bytes (128 x 3).
        byte_buffer[ausilio]=b & 0xFF
       
    Next

    ' If loop exited due to data timeout, go to next cycle
    If i < 127 Then GoTo LoopStart

    ' Receive 2 bytes of CRC (high, low)
    j = 0 : crcHi = -1
    While j < TIMEOUT_LOOPS
        While U1STAHbits_URXBE=1:Wend
        If U1STAHbits_URXBE = 0 Then
            crcHi = U1RXREG & 0xFF
            Break
        EndIf
        j = j + 1
    Wend
    If crcHi = -1 Then
        While U1STAHbits_UTXBF = 1 : Wend
        U1TXREG = NAK
        While U1STAbits_TRMT = 0 : Wend
        GoTo LoopStart
    EndIf

    j = 0 : crcLo = -1
    While j < TIMEOUT_LOOPS
        While U1STAHbits_URXBE=1:Wend
        If U1STAHbits_URXBE = 0 Then
            crcLo = U1RXREG & 0xFF
            Break
        EndIf
        j = j + 1
    Wend
    If crcLo = -1 Then
        While U1STAHbits_UTXBF = 1 : Wend
        U1TXREG = NAK
        While U1STAbits_TRMT = 0 : Wend
        GoTo LoopStart
    EndIf

    crcRecv = ((crcHi & 0xFF) * 256) | (crcLo & 0xFF)

    'Calculate CRC16 XMODEM of the 128 bytes in the data
    crcCalc = 0
    For i = 0 To 127
        crcCalc = crcCalc ^ ((data[i] & 0xFF) * 256)
        For k = 0 To 7
            If (crcCalc & 0x8000) <> 0 Then
                crcCalc = ((crcCalc << 1) ^ 0x1021) & 0xFFFF
            Else
                crcCalc = (crcCalc << 1) & 0xFFFF
            EndIf
        Next
    Next
   
    If (crcRecv & 0xFFFF) = (crcCalc & 0xFFFF)  Then
        Inc contatore,1 'Increases the packet counter by 128 bytes, up to a maximum of 3
    EndIf
     If numriga=8 And contatore=3 Or FL=0 Then
                             
                             numriga=0
                             If FL>0 Then
                             Inc FlashStart, 2048  ' I wrote 1024 program words then Jump 2048 addresses
                             EndIf
                             FL=1
                             MCU_TBLPAG =  (FlashStart >> 16) & 0xFF
                             MCU_Code_Write_Offset = FlashStart & 0xFFFF
                                                         
                             Asm
                             ' Prepare to ERASE FLASH PAGE
                             Mov MCU_TBLPAG,   W4
                             Nop
                             Mov MCU_Code_Write_Offset,   W3
                             Nop
                             Mov W3,NVMADR       
                             Mov W4,NVMADRU
                             Nop
                             Nop
                             
                              ' Set up NVMCON to erase one page of Program Memory
                             Mov #0x4003,W10
                             Nop
                             Mov  W10,NVMCON
                             Nop
                                                         
                               ' Disable interrupts < priority 7 for next 5 instructions
                             Disi #06
                             ' Write the KEY Sequence
                             Mov   #0x55,W1
                             Mov   W1,NVMKEY
                             Mov   #0xAA,W1
                             Mov   W1,NVMKEY
                             
                             ' Start the erase operation
                             Bset  NVMCON,#15
                           
                             ' Insert 3 NOPs after the erase cycle (required)
                             Nop
                             Nop
                             Nop
                             Nop
                             Nop
                             
                             ; Wait erasing process
                             WaitE:
                             Btsc    NVMCON, #15        ; If WR than wait
                             Bra     WaitE
                           
                             ; Check for error
                             Btss    NVMCON, #13        ; If WRERR = 0 ? OK
                             Bra     No
                             
                              ; Error, so turn on LED on RE5
                             Bclr.b  TRISEH, #5         ; RE5 output
                             Bset.b  LATEH,  #5         ; Turn on LED
                           
                             No:
                             EndAsm
     
     EndIf
   

    If (crcRecv & 0xFFFF) = (crcCalc & 0xFFFF)  Then    'CRC OK !

        filePos = filePos + 128
        attempts = 0
        While U1STAHbits_UTXBF = 1 : Wend
        U1TXREG = ACK
        While U1STAbits_TRMT = 0 : Wend
    Else
        ' CRC NOK
        While U1STAHbits_UTXBF = 1 : Wend
        U1TXREG = NAK
        While U1STAbits_TRMT = 0 : Wend
        attempts = attempts + 1
        If attempts > 10 Then Break
        GoTo LoopStart
    EndIf
   
   
     If contatore=3 Then
                 Toggle PORTE.13
                 contatore=0
                 
                     ' Valid block: write block to memory
                     Asm
                    '----------------------------- --------------
                    ' WRITE 384 BYTES USING DOUBLE PROGRAM WORDS
                    '----------------------------- --------------
                        Mov   #byte_buffer, W2
                        Mov   #64, W3                 ; I write 64*2=128 in Word, or 384 bytes.
                        Mov   MCU_Code_Write_Offset, W4
                        Mov   W4, NVMADR
                        Mov   MCU_TBLPAG, W5
                        Mov   W5, NVMADRU
                        Mov   #0x4001, W7
                    LoopDW:
                        Clr W4
                        Clr W5
                        Clr W6
                        ; Init PAGE
                        Mov   #0xFA, W0
                        Mov   W0, TBLPAG
                        Mov   #0x00, W1      ; EA pointer for TBL
                       
                        ; ----- populate first program word (B0,B1,B2) -----

                        Mov.b   [W2++], W6        ; B0 -> W6 (MSB of program word)
                        Mov.b   [W2++], W5        ; B1 -> W5
                        Mov.b   [W2++], W4        ; B2 -> W4
                   
                        ; BUild LSW = (B1 << 8) | B2
                        Swap    W5                ; Move B1 to high byte of W5
                        Ior     W4, W5, W4        ; W4 = (B1 << 8) | B2
                   
                        ; Write latches
                        TblwtL  W4, [W1]          ; Load LSW (16 bit)
                        Nop
                        Nop
                        TblwtH  W6, [W1++]        ; Load MSB (8 bit)
                        Nop
                        Nop
                        Clr W4
                        Clr W5
                        Clr W6
 
                        Mov.b   [W2++], W6        ; B0 -> W6 (MSB della program word)
                        Mov.b   [W2++], W5        ; B1 -> W5
                        Mov.b   [W2++], W4        ; B2 -> W4
                   
                        ; Build LSW = (B1 << 8) | B2
                        Swap    W5                ; Move B1 to high byte of W5
                        Ior     W4, W5, W4        ; W4 = (B1 << 8) | B2
                        ; Write to latches
                        TblwtL  W4, [W1]          ; Load LSW (16 bit)
                        Nop
                        Nop
                        TblwtH  W6, [W1++]        ; Load MSB (8 bit)
                        Nop
                        Nop
                   
                        ; ----- Set NVMCON and start writing for the current double word -----
                        Mov   #0x4001, W7     
                        Mov   W7, NVMCON
                       
                        Disi  #6
                        Mov   #0x55, W7
                        Mov   W7, NVMKEY
                        Mov   #0xAA, W7
                        Mov   W7, NVMKEY
                   
                        Bset  NVMCON, #15      ; WR = 1
                        Nop
                        Nop
                        Nop
                    WaitWR:
                        Btsc  NVMCON, #15
                        Bra   WaitWR
                        Nop
                        Nop
                        ; ----- error check -----
                        Btss  NVMCON, #13      ; WRERR == 1 ?
                        Bra   NoError
                   
                    HandleError:
                       
                        Bclr.b  TRISEH, #5   ' Turn on LED
                        Bset.b  LATEH,  #5
                        Bra   Done
                   
                    NoError:
                        Bclr  NVMCON, #14      ; WREN = 0
                   
                        ; ----- update NVMADR for the next double-word -----
                       
                        Mov     NVMADR, W12     ; read 16-bit low/mid
                        Add     #4,   W12       ; add 4 (byte)
                        Mov     W12,  NVMADR    ; write back 16-bit
                        'Bra     NC, no_carry   ; if no carry...jump
                        Mov    NVMADRU,  W13    ; read high byte/word alto to W13
                        Mov     #0,   W14       ; zero to add only Carry
                        Addc    W14,  W13, W13  ; W13 = W13 + 0 + Carry
                        Mov    W13,  NVMADRU    ; write high byte of EA
                                             
                        ; ----- Continue-----
                        Dec   W3, W3
                        Bra   NZ, LoopDW
                   
                    Done:   
                   
                EndAsm
                Inc numriga,1   ' I have filled 1 row of 384 bytes, I can proceed with writing to FLASH
                Inc MCU_Code_Write_Offset, 256  ' Update Row
               
               
     EndIf
       
     
   
Wend


Asm
' Call ....Application address  0x2000
EndAsm



' ===== Config (unchanged by bootloader) =====
Config FSEC        = BWRP_OFF, BSS_DISABLED, BSEN_OFF, GWRP_OFF, GSS_DISABLED, CWRP_OFF, CSS_DISABLED, AIVTDIS_OFF
Config FOSCSEL     = FNOSC_FRC, IESO_OFF
Config FOSC        = POSCMD_EC, OSCIOFNC_ON, FCKSM_CSECMD, PLLKEN_OFF, XTCFG_G0, XTBST_ENABLE
Config FWDT        = SWDTPS_PS2147483648, RCLKSEL_LPRC
Config FPOR        = BISTDIS_DISABLED
Config FICD        = ICS_PGD3, JTAGEN_OFF, NOBTSWP_DISABLED
Config FDMT        = DMTDIS_OFF
Config FDEVOPT     = ALTI2C1_OFF,ALTI2C2_OFF,ALTI2C3_ON, SMBEN_SMBUS, SPI2PIN_PPS
Config FALTREG     = CTXT1_OFF, CTXT2_OFF, CTXT3_OFF, CTXT4_OFF
Config FBOOT       = BTMODE_SINGLE