MCP2210 Library — Reference

MCP2210 Library is an open source C++ library that enables communications between the host computer and slave MCP2210 devices under Linux. This library utilizes functions from Signal 11‘s HID API (hidraw) open source project to communicate over the USB HID interface. You can find the most up-to-date source code on github. This library is released under Apache License, Version 2.0.

Overview

The primary goal of this project was to create an open source Linux library for the versatile MCP2210 USB-to-SPI chip. Technically speaking, this library should also work with Windows and Mac OS X as the underlying HID API can be cross-compiled on any of these platforms. Since Microchip offers an .Net based API for Windows, my focus has been concentrated on the Linux environment.

Library Documentation

The library reference can either be downloaded from github (under doc directory) or can be viewed directly following the link below:

The Doxygen generated documentation also includes comments from the hidapi library. Most of the documentations for function definitions of the MCP2210 library can be found under mcp2210.h.

License

The library is released under Apache License, Version 2.0.

Copyright 2012 Kerry D. Wong

Licensed under the Apache License, Version 2.0 (the “License”);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Source Code and Build Instructions

You can get the latest source code using:

git clone git://github.com/kerrydwong/MCP2210-Library.git

Or you can download the source files from here.

The project was built using NetBeans 7.2 under Ubuntu 12.04 (64 bits). The project has a dependency on udev. If you are using NetBeans to build, everything should have already been setup for you. If you are using other IDEs or are compiling from the command line, please remember to include -ludev as the linker option.

You may also need to add a UDEV rule to /etc/udev/rules.d for the underlying hidapi. The rule file (99-hid.rules) is supplied with the source code on github. Depending on the Linux system you use, super user privilege may also be required for your compiled code to interact with the HID device.

Getting Started

All application code should start with the initialization of the library and release the device handle at the end:

#include "mcp2210.h"

void main()
{
    hid_device *handle;

    handle = InitMCP2210();
    if (handle == 0) 
    {
        //Error initializing
        exit(-1);
    }

    //===================
    //user code goes here
    //===================

    ReleaseMCP2210(handle);
}

The library also supports multiple connected MCP2210 devices via the overloaded InitMCP2210 functions. Please refer to the project documentation for more details.

Most of the function calls that gets values from MCP2210 takes the device handle as the parameter and returns a definition value object which contains the settings. For instance:

  SPITransferSettingsDef def = GetSPITransferSettings(handle);

The ErrorCode field within the definition indicates whether the operation was successful. And most of the function calls that writes values to the MCP2210 takes the device handle and the corresponding definition as parameters and return a status code:

    SPITransferSettingsDef def;
    
    //code to fill def

    int r = SetSPITransferSettings(handle, def);

The following links list some of the examples using the library:

Be Sociable, Share!

12 Comments

  1. RJohnston says:

    Kerry,

    Great job on the MCP2210 driver. I have incorporated all your source code examples into a single QT application that allows the user to select which test to run as a validation of the software driver. All seems to work great.

    I am trying to use the MCP2210 to interface to an external SPI device, in particular an Atmel Bamboo RFID reader. Some additional handshaking was required to interface to this device as follows:
    GP2: Configured as a CS output to RFID reader – must be low during SPI commands
    GP3: Configured as a GPIO input from RFID reader – ISTAT line which signals host that there is data to be read from the RFID reader. Must continue to read until this line goes low.
    GP5: Configured as a GPIO output to RFID reader – Reset line to RFID reader which is pulsed low to reset the RFID reader device.

    My QT program is configured to produce code that runs in both Windows and Linux (depending on which OS it is compiled in) as a test program to validate the MCP2210 driver operation in both operating systems. I modified the driver to insert the needed handshaking as detailed above to verify the operation of the Atmel Reader with the MCP2210. I placed the necessary handshaking with addition function parameters inside the SPIDataTransfer and SPISendReceive functions to build the inner packet for the SPI Data Transfer command. The problem seems to be that there is something wrong with the 0x42 SPI data transfer command as no matter how many times I read it, ISTAT stays high. I have read somewhere on the MicroChip forums that the way to solve this (undocumented) is to perform another read with a ‘0’ byte length but that does not seem to work. All of the handshaking is working correctly as verified with a logic analyzer.

    Any recommendations you can provide would be helpful. I have contacted Microchip but so far they have been no help. I can provide my source code to you if you want to see it or use it as a single example program on your web page that encapsulates all of your examples.

    Regards,
    Richard Johnston

    • kwong says:

      Hi Rich,

      Glad to hear you were able to use this library! Regarding the ISTAT were you referring to GP6? Without the hardware setup, it’s a bit difficult to say exactly what was causing the issue. But if you could send me your SPISendReceive function, I will try my best to take a look.

  2. RJohnston says:

    I have my modified driver working better now as I experimentally discovered that I must read data in SPI xfer packets sizes. With my packet size set to the default of 4 bytes, when I send a command that expects a 1 byte response, I must read 4 bytes. At some point beyond the command’s real response size, the reader signals via the SPI engine status that there are no more bytes to read and ISTAT goes low. As a generalized solution, I make the driver always try to read 64 bytes (multiple of 4 byte packet size) and it always signals that there is no more data at some byte beyond the real response size.

    I still have some issues with the responses, in particular for the Atmel Bamboo RFID reader’s initialization where the write register command is used to configure the device, I get back all ‘0’ for response data, still working on that issue.

    Regards,
    Richard Johnston

  3. Ajay says:

    Hi Kerry,

    Since I am not familiar with C#, I plan to use these drivers in Windows. I am having problems trying to compile. Header files like unistd.h, sys/ioctl.h … etc are not found. I could not solve the problem to compile the test source code. Any help is appreciated.

    Regards,
    Ajay

    • Ajay says:

      Hi all,

      I managed to get the library compiled in windows. I just had to change to the correct version of (windows compatible) hid.c and hidapi.h files.

      However, I see a problem when trying to run mcp2210test.cpp. InitMCP2210() goes through fine but hid_write() (inside GetChipSettings() function) returns error. Any help is appreciated.

      Regards,
      Ajay

      • Remco says:

        Been fighting this for two days and finally got it working.

        It’s a windows thing. You have to prepend a report byte of 0x00 to your 64 commands. I ended up doing it inside SendUSBCmd (i.e. i’m sending 65 bytes there, the first of which is zero, the other 64 is the cmdBuf). If you don’t do this, either SendUSBCmd will fail or you’ll get garbage in your rsp buffer.

        There’s also a weirdness with windows adding a zero on the response, but that is caught in the hid_read_timeout routine (line 648), so the hidapi guys are aware of it.

        Now when you check the cmd versus the rsp buffers, you’ll see your command echoed as rsp[0] and rsp[1]=0x0, if all is well.

  4. Djoub says:

    Hi Kerry

    Thanks for the driver, you’ve spared me tons of frustration!

    Just a note: to get the library working on either a Raspberry Pi or a Beaglebone Black (default operating systems, Raspbian and Angstrom) I had to modify the driver to use libusb instead of hidraw. To do this, I replaced the hid.c file with the hid.c from the libusb folder from the hidapi git repository code. Therafter I edited the Makefile-Debug.mk in the library nbprojects folder to compile using the libusb-1.0 library instead of the libudev library.

    I’ve only tested these implementations with hidtest.

    Regards
    -Djoub

  5. Kailesh says:

    Hi,
    sir,
    Glad to use this driver in my project it is working very nice thank you very much.
    I have a question:
    I am using 2 things to talk with my chip uart and spi
    with uart on 115000 baudrate i am getting good speed than spi with 11 Mhz i saw on oscilloscope and i aslo tried with 3 MHz
    for both cases i shoud get 10 times faster than uart but i am gettin 10 times less speed.I am opening the usb and keeping it open and reading register. for each register i shoud get 500 us but i am gettin 2-3 ms. after every byte there is 40 us delay that also i took it in count.
    By my maths spi shoud be 10 times faste.
    Why it is slow?
    I am suspecting may be it is os delay?
    Is there anyway to make it fly.

    thanks sir
    kailesh

  6. farmanali says:

    Hi sir,

    I have used your MCP2210 Library and installed it.
    after that I used this code posted by you on your website http://www.kerrywong.com/mcp2210-library-reference/

    #include “mcp2210.h”

    void main()
    {
    hid_device *handle;

    handle = InitMCP2210();
    if (handle == 0)
    {
    //Error initializing
    exit(-1);
    }

    //===================
    //user code goes here
    //===================

    ReleaseMCP2210(handle);
    }

    but we have the following error

    /tmp/ccdnd69Y.o: In function `main’:
    test.c:(.text+0xa): undefined reference to `InitMCP2210()’
    test.c:(.text+0x2d): undefined reference to `ReleaseMCP2210(hid_device_*)’
    collect2: ld returned 1 exit status

    please help us

  7. sunio says:

    Hi all,
    I am using mcp2210 for usb to spi conversion, the place where i am stuck is word length or bits per word supported by mcp2210.The driver currently available through a link mentioned on microchip website says device is having limitation of 8 bit word whereas in datasheet i did not found where the word length is mentioned. I want to use it for 16 bit word length.
    If any body is having idea plz let me know is this is a device limitation??

Leave a Reply