The Godfather talking
You can run, but you can't hide.
Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
April 19, 2024, 11:37:22 11:37


Login with username, password and session length


Pages: [1]
Print
Author Topic: dynamically update USB HID Serial number - MikroC  (Read 6464 times)
0 Members and 1 Guest are viewing this topic.
Some Anon Guy
Junior Member
**
Offline Offline

Posts: 43

Thank You
-Given: 58
-Receive: 25



« on: December 03, 2013, 05:35:28 05:35 »

I had a need to have many of the same USB HID devices on the same system. I needed a way to update the serial number of each unit to a unique address.
Using PIC18f26j50 and MikroC

What I did was set the address of the string array used for the serial number in the USB descriptor file to an absolute location. (0x2000)
Code:
//Product serial number
const struct{
  char bLength;
  char bDscType;
  unsigned int string[8];
}strd4={
    18,          //sizeof this descriptor string
    0x03,
    {'b','b','b','b','b','b','b','b'}
 }absolute 0x2000; // <-- Set to 0x2000 absolute location

Then in my main program I have a function that sets up the new serial number, erases the flash at 0x2000, and finally writes the new serial number to flash.
Code:
void updateSerial(void){
     unsigned char serialnum[64]={18,0x03,'a',0,'a',0,'a',0,'a',0,'a',0,'a',0,'a',0,'a',0}; // Expected format. Change the values inside the ''
     char i=0;               // Had to use all the 0's above ^ because the origional data was written as integers, I am hacking this with chars
     for (i=18;i<64;i++){
         serialnum[i]=0xff;   // Set remaining unused positions to 0xff so that we do not have random data.
     }
     FLASH_Erase_1024(0x2000);  //Have to erase first. OUCH! have to erase in blocks of 1024!
     FLASH_Write_64(0x2000,serialnum);  //Write the new Serial Number.
     asm reset;   // Need to reset PIC after Serial number update
}

This successfully changes the USB HID serial number for the device from bbbbbbbb to aaaaaaaa.
 
You should only call this function when needed. You do not want to wear out the flash memory if it is run every boot.

This is just a skeleton, you still need to add the code to generate your unique serial number (Read from another IC?..., Assigned by the computer they are attached to?... etc...)

Hopefully someone else will find this helpful.
Logged
krishna.velu
Newbie
*
Offline Offline

Posts: 13

Thank You
-Given: 10
-Receive: 1


« Reply #1 on: July 30, 2014, 11:05:39 11:05 »

The PIC18f26j50 has 64K and you are placing the variable in 0x2000 (8K)

And then you are trying to erase and reprogram those bytes in 0x2000. what will you do if your program iteself is more than 7.5K or 8K.

Erase your program code Tongue Tongue?

Placing the variable in the end of the flash will be a good idea... A good design will be place these in an EEPROM.
Logged
Some Anon Guy
Junior Member
**
Offline Offline

Posts: 43

Thank You
-Given: 58
-Receive: 25



« Reply #2 on: August 04, 2014, 07:47:43 07:47 »

The PIC18f26j50 has 64K and you are placing the variable in 0x2000 (8K)

And then you are trying to erase and reprogram those bytes in 0x2000. what will you do if your program iteself is more than 7.5K or 8K.

Erase your program code Tongue Tongue?

Placing the variable in the end of the flash will be a good idea... A good design will be place these in an EEPROM.

Obviously.
If you can figure out how to place these in an EEPROM using MikroC and save us the trouble then by all means please share.
This was written this way because it was the only way I could figure out how to accomplish what was required.
Logged
metal
Global Moderator
Hero Member
*****
Offline Offline

Posts: 2420

Thank You
-Given: 862
-Receive: 678


Top Topic Starter


« Reply #3 on: August 05, 2014, 02:47:38 02:47 »

The PIC18f26j50 has 64K and you are placing the variable in 0x2000 (8K)

And then you are trying to erase and reprogram those bytes in 0x2000. what will you do if your program iteself is more than 7.5K or 8K.

Erase your program code Tongue Tongue?

Placing the variable in the end of the flash will be a good idea... A good design will be place these in an EEPROM.

show us your work dude..
Logged
krishna.velu
Newbie
*
Offline Offline

Posts: 13

Thank You
-Given: 10
-Receive: 1


« Reply #4 on: August 06, 2014, 10:26:08 10:26 »

Obviously.
If you can figure out how to place these in an EEPROM using MikroC and save us the trouble then by all means please share.
This was written this way because it was the only way I could figure out how to accomplish what was required.

Place the structure in 0xFFC0 (64K - 64Bytes). Assuming that your structure can grow upto 64Bytes.
PIC18f26j50 doesnt have any EEPROM that you can store. Do you have any external EEPROM?

More generic would be find some #define for the end of FLASH and use that. Every compiler's device header file must have end of flash or the size of flash

@Metal what work you want me to show?
« Last Edit: August 06, 2014, 10:55:17 10:55 by krishna.velu » Logged
fantomex
Newbie
*
Offline Offline

Posts: 14

Thank You
-Given: 12
-Receive: 0


« Reply #5 on: February 26, 2015, 11:24:08 11:24 »

If you can figure out how to place these in an EEPROM using MikroC and save us the trouble then by all means please share.
I'm not familiar with MikroC but I can tell you how I do it with the Microchip USB library.

1) in your USB device descriptor, set the second to last byte 'iSerialNumber' to the number of string descriptors you have. Typically you have a product (1) and manufacturer (2) so you would set this to 3.
2) find the usb event callback handler for a 'EVENT_EP0_REQUEST' request. This is where your class-specific handling such as HID or CDC handling is placed. In this handler, look at the SetupPkt variable. The request type should be 0x80, bRequest should be 0x06 (get descriptor), bDescriptorType should be 0x03 (string type) and the descriptor index (bDscIdx) should be the number you specified in 1).
3) If all these requirements are met, we can fill the CtrlTrfData data with our serial number and transmit it. Keep in mind that this is a 16-bit UTF string without null termination. When done, update inPipes[0] to start transmitting.

Code:

bool USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, uint16_t size) {
    switch (event) {
         ...
        case EVENT_EP0_REQUEST:
            ...
            USBCheckGetSerial();
            break;     
}

void USBCheckGetSerial() {
    // pick up Get_Descriptor(STRING, serial number ) request
    if (SetupPkt.bmRequestType == 0x80
            && SetupPkt.bRequest == USB_REQUEST_GET_DESCRIPTOR
            && SetupPkt.bDescriptorType == USB_DESCRIPTOR_STRING
            && SetupPkt.bDscIndex == 3) {
        // here, read out serial number string desc to CtrlTrfData[]
        // The size of CtrlTrfData[] array is USB_EP0_BUFF_SIZE (default: 8)
        // if the desc size doesn't fit to this size, declare greater array and assign it instead.

        // copy 'xxxxxxxx' serial to CtrlTrfData
        CtrlTrfData[0] = 14; // number of bytes
        CtrlTrfData[1] = USB_DESCRIPTOR_STRING;
        unsigned char i;
        for (i = 0; i < 10; i++) {
            CtrlTrfData[2 + i * 2] = 'x';
            CtrlTrfData[2 + i * 2 + 1] = '\0';
        }
        inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type
        inPipes[0].pSrc.bRam = (UINT8*) CtrlTrfData; // Set Source
        inPipes[0].wCount.v[0] = CtrlTrfData[0]; // Set data count
        inPipes[0].info.bits.busy = 1;
    }
}

In the for loop you can set the serial to anything you want, like something from EEPROM.
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC