MikroElektronika

From Pinguino-Wiki
Jump to: navigation, search
  • Operating system: Windows XP/Windows 7
  • Board: Pinguino 26J50

A toolchain is the set of programming tools that are used to create a product (typically another computer program or system of programs). The tools may be used in a chain, so that the output of each tool becomes the input for the next, but the term is used widely to refer to any set of linked development tools.

MikroElectronica sell various Windows operating system language compilers for 8 bit PIC microcontrollers, among others, including BASIC, C and Pascal. They also make fully functional demo versions of their compilers available for use with the only limit being the output is limited to 2K of program words.

mikroPascal PRO for PIC

Main program source file: Pinguino_HID_Read_Write_Interrupt.mpas

{*
 * Project name:
     HID_Read_Write_Interrupt (Testing the USB HID connection)
 
 * Revision History:  
     20131004 - initial revision (TR)
 
 * Description:
     This example establishes connection with the HID terminal that is active
     on the PC. On connection establishment, the HID Device Name will appear
     in the respective window. After that program will wait for a single
     character and then start outputting from 1 in 0.1 increments until
     it reaches 10 and then repeats 1..10 in 0.1 increments forever.
 
 * Test configuration:
     MCU:             PIC18F26J50
                      http://ww1.microchip.com/downloads/en/DeviceDoc/39775c.pdf
     Dev board:       Pinguino 26J50
                      http://wiki.pinguino.cc/index.php/PIC18F26J50_Pinguino
     Oscillator:      HS+PLL, USB+PLL
                      Input crystal = 20MHz  (PLL prescaler divide 5 = 4MHz)
                      CPU frequency = 48MHz  (4MHz raised with PLL to 48MHz)
     Ext. Modules:    None.
     Compiler:        mikroPascal PRO for PIC 6.01
                      http://www.mikroe.com/mikropascal/pic/
 
     NOTES:           Non-default configuration words which need setting
                      in Project -> Edit Project:                      
                      - pll prescaler: divide by 5
                      - oscillator: HS+PLL, USB+HS+PLL
 
                      Libraries to include using the IDE Library Manager:
                      - Conversions
                      - String
                      - USB
 *}
 
program Pinguino_HID_Read_Write_Interrupt;
 
var cnt : byte;
var pos : byte;
var counter : real;
var tmpbuff : string[63];          // 63 to allow for terminating null making 64
var tmpbuff2 : string[63];         // 63 to allow for terminating null making 64
var readbuff : array[64] of byte; absolute 0x500;   // Buffer must be in USB RAM, see datasheet
var writebuff : array[64] of byte; absolute 0x540;  // Buffer must be in USB RAM, see datasheet
 
procedure Interrupt();
begin
   USB_Interrupt_Proc();                // USB servicing is done inside the interrupt
end;
 
procedure write_usb(var buffer : array[64] of byte);
begin
  while(HID_Write(@buffer,64) = 0) do  // Write buffer contents to USB
        ;
end;
 
begin
  PLLEN_bit := 1;                // PLL turned on
  Delay_ms(150);                 // wait for oscillator to stabilise
 
  ANCON0 := 0xFF;                // Default all pins to digital
  ANCON1 := 0xFF;
 
  counter := 1.0;
 
  HID_Enable(@readbuff,@writebuff);       // Enable HID communication
 
  while(HID_Read() = 0) do                // Wait here for input
         ;
 
  writebuff := 'Hello!' + chr(13) + chr(10);
  write_usb(writebuff);                   // Output buffer contents
 
  while TRUE do
    begin
            if(counter > 10) then
                counter := 1.0
            else
                counter := counter + 0.1;
 
            FloatToStr(counter, tmpbuff2);             // convert to string
            pos := strcspn(tmpbuff2, '.');             // locate decimal point
 
            memset(@tmpbuff, '', 63);                  // clear buffer
            strncpy(tmpbuff, tmpbuff2, pos+2);         // truncate to one decimal place
            strcat(tmpbuff, chr(13) + chr(10));        // add return, newline;
 
            writebuff := tmpbuff;                      // assign to USB write buffer
            write_usb(writebuff);                      // output
 
            delay_ms(250);                             // delay
    end;
end.


USB descriptors source file (generated using the Descriptor tab of the HID Terminal - see image below): USBdsc.mpas


unit USBdsc;
 
const USB_VENDOR_ID : word = 0x1234;
const USB_PRODUCT_ID : word = 0x0001;
const USB_SELF_POWER : char = 0x80;            // Self powered 0xC0,  0x80 bus powered
const USB_MAX_POWER : char = 50;               // Bus power required in units of 2 mA
const HID_INPUT_REPORT_BYTES : char = 64;
const HID_OUTPUT_REPORT_BYTES : char = 64;
const EP_IN_INTERVAL : char = 1;
const EP_OUT_INTERVAL : char = 1;
 
const USB_INTERRUPT : char = 1;
const USB_TRANSFER_TYPE : char = 0x03;         //0x03 Interrupt
const USB_HID_EP : char = 1;
const USB_HID_RPT_SIZE : char = 33;
 
type device_descriptor = record
    bLength : char;               // bLength         - Descriptor size in bytes (12h)
    bDescriptorType : char;       // bDescriptorType - The constant DEVICE (01h)
    bcdUSB : word;                // bcdUSB          - USB specification release number (BCD)
    bDeviceClass : char;          // bDeviceClass    - Class Code
    bDeviceSubClass : char;       // bDeviceSubClass - Subclass code
    bDeviceProtocol : char;       // bDeviceProtocol - Protocol code
    bMaxPacketSize0 : char;       // bMaxPacketSize0 - Maximum packet size for endpoint 0
    idVendor : word;              // idVendor        - Vendor ID
    idProduct : word;             // idProduct       - Product ID
    bcdDevice : word;             // bcdDevice       - Device release number (BCD)
    iManufacturer : char;         // iManufacturer   - Index of string descriptor for the manufacturer
    iProduct : char;              // iProduct        - Index of string descriptor for the product.
    iSerialNumber : char;         // iSerialNumber   - Index of string descriptor for the serial number.
    bNumConfigurations : char;    // bNumConfigurations - Number of possible configurations
end;
 
const device_dsc : device_descriptor = (
  0x12,                   // bLength
  0x01,                   // bDescriptorType
  0x0200,                 // bcdUSB
  0x00,                   // bDeviceClass
  0x00,                   // bDeviceSubClass
  0x00,                   // bDeviceProtocol
  8,                      // bMaxPacketSize0
  USB_VENDOR_ID,          // idVendor
  USB_PRODUCT_ID,         // idProduct
  0x0001,                 // bcdDevice
  0x01,                   // iManufacturer
  0x02,                   // iProduct
  0x00,                   // iSerialNumber
  0x01                    // bNumConfigurations
);
 
// Configuration 1 Descriptor
const configDescriptor1 : array[41] of byte = (
    // Configuration Descriptor
    0x09,                   // bLength             - Descriptor size in bytes
    0x02,                   // bDescriptorType     - The constant CONFIGURATION (02h)
    0x29,0x00,              // wTotalLength        - The number of bytes in the configuration descriptor and all of its subordinate descriptors
    1,                      // bNumInterfaces      - Number of interfaces in the configuration
    1,                      // bConfigurationValue - Identifier for Set Configuration and Get Configuration requests
    0,                      // iConfiguration      - Index of string descriptor for the configuration
    USB_SELF_POWER,         // bmAttributes        - Self/bus power and remote wakeup settings
    USB_MAX_POWER,          // bMaxPower           - Bus power required in units of 2 mA
 
    // Interface Descriptor
    0x09,                   // bLength - Descriptor size in bytes (09h)
    0x04,                   // bDescriptorType - The constant Interface (04h)
    0,                      // bInterfaceNumber - Number identifying this interface
    0,                      // bAlternateSetting - A number that identifies a descriptor with alternate settings for this bInterfaceNumber.
    2,                      // bNumEndpoint - Number of endpoints supported not counting endpoint zero
    0x03,                   // bInterfaceClass - Class code
    0,                      // bInterfaceSubclass - Subclass code
    0,                      // bInterfaceProtocol - Protocol code
    0,                      // iInterface - Interface string index
 
    // HID Class-Specific Descriptor
    0x09,                   // bLength         - Descriptor size in bytes.
    0x21,                   // bDescriptorType - This descriptor's type: 21h to indicate the HID class.
    0x01,0x01,              // bcdHID          - HID specification release number (BCD).
    0x00,                   // bCountryCode    - Numeric expression identifying the country for localized hardware (BCD) or 00h.
    1,                      // bNumDescriptors - Number of subordinate report and physical descriptors.
    0x22,                   // bDescriptorType - The type of a class-specific descriptor that follows
    USB_HID_RPT_SIZE,0x00,  // wDescriptorLength - Total length of the descriptor identified above.
 
    // Endpoint Descriptor
    0x07,                   // bLength - Descriptor size in bytes (07h)
    0x05,                   // bDescriptorType - The constant Endpoint (05h)
    USB_HID_EP or 0x80,     // bEndpointAddress - Endpoint number and direction
    USB_TRANSFER_TYPE,      // bmAttributes - Transfer type and supplementary information
    0x40,0x00,              // wMaxPacketSize - Maximum packet size supported
    EP_IN_INTERVAL,         // bInterval - Service interval or NAK rate
 
    // Endpoint Descriptor
    0x07,                   // bLength - Descriptor size in bytes (07h)
    0x05,                   // bDescriptorType - The constant Endpoint (05h)
    USB_HID_EP,             // bEndpointAddress - Endpoint number and direction
    USB_TRANSFER_TYPE,      // bmAttributes - Transfer type and supplementary information
    0x40,0x00,              // wMaxPacketSize - Maximum packet size supported
    EP_OUT_INTERVAL         // bInterval - Service interval or NAK rate
);
 
type hid_report_descriptor = record
  report : array[USB_HID_RPT_SIZE] of byte;
end;
 
const hid_rpt_desc : hid_report_descriptor = (
  (0x06, 0x00, 0xFF,      // Usage Page = 0xFF00 (Vendor Defined Page 1)
  0x09, 0x01,             // Usage (Vendor Usage 1)
  0xA1, 0x01,             // Collection (Application)
  // Input report
  0x19, 0x01,             // Usage Minimum
  0x29, 0x40,             // Usage Maximum
  0x15, 0x00,             // Logical Minimum (data bytes in the report may have minimum value = 0x00)
  0x26, 0xFF, 0x00,       // Logical Maximum (data bytes in the report may have maximum value = 0x00FF = unsigned 255)
  0x75, 0x08,             // Report Size: 8-bit field size
  0x95, HID_INPUT_REPORT_BYTES,// Report Count
  0x81, 0x02,             // Input (Data, Array, Abs)
  // Output report
  0x19, 0x01,             // Usage Minimum
  0x29, 0x40,             // Usage Maximum
  0x75, 0x08,             // Report Size: 8-bit field size
  0x95, HID_OUTPUT_REPORT_BYTES,// Report Count
  0x91, 0x02,             // Output (Data, Array, Abs)
  0xC0)                   // End Collection
  );
 
//Language code string descriptor
type str1 = record
  bLength : char;
  bDscType : char;
  str : array[1] of word;
end;
 
const strd1 : str1 = (
  4,
  0x03,
  (0x0409)
);
 
//Manufacturer string descriptor
type str2 = record
  bLength : char;
  bDscType : char;
  str : array[16] of word;
end;
 
const strd2 : str2 = (
  34,           //sizeof this descriptor string
  0x03,
  ('M','i','k','r','o','e','l','e','k','t','r','o','n','i','k','a')
);
 
//Product string descriptor
type str3 = record
  bLength : char;
  bDscType : char;
  str : array[14] of word;
end;
const strd3 : str3 = (
  30,           //sizeof this descriptor string
  0x03,
  ('P','i','n','g','u','i','n','o',' ','2','6','J','5','0')
);
 
 
var USB_config_dsc_ptr : array[1] of ^const byte;
 
var USB_string_dsc_ptr : array[3] of ^const byte;
 
procedure USB_Init_desc();
implementation
  procedure USB_Init_desc();
  begin
    USB_config_dsc_ptr[0] := @configDescriptor1;
    USB_string_dsc_ptr[0] := ^const byte(@strd1);
    USB_string_dsc_ptr[1] := ^const byte(@strd2);
    USB_string_dsc_ptr[2] := ^const byte(@strd3);
  end;
end.


Using the HID Terminal to generate the USB descriptors file:

Mikro hid term desriptor.png

Compile the above two source files and then program the Pinguino 26J50 with the resulting hex file using a standard PIC programmer (eg PICkit2) connected to the Pinguino's ICSP pins.

Connect the Pinguino via USB to your computer and use the MikroElectronika HID Terminal (select from IDE Tools Menu) to send a character to the Pinguino and trigger the output which should look similar to:

Mikro hid terminal.png

Downloadable files

Pinguino_HID_Read_Write_Interrupt.hex

OS X command line program to list USB devices and read output from the Pinguino 26J50 running the USB HID program.

Personal tools