• AVR Freaks

Hot!PIC32MX USB PLL

Author
Memen
Starting Member
  • Total Posts : 35
  • Reward points : 0
  • Joined: 2017/04/08 12:17:32
  • Location: 0
  • Status: offline
2019/07/25 09:35:19 (permalink)
0

PIC32MX USB PLL

Hi
 
I am trying to implement the USB module on the PIC32MX795F512L, but I cannot get it to work yet. Windows gives the well-known "device descriptor failed" message, but only after disconnecting or pausing the device in debugger.
 
- Interrupts for USB seem to work okay (fire correctly in debugger mode)
- endpoints and device descriptors etc seem to be initialised correctly (most of the code was initially for another similar chip - PIC32MM, on which it works, so I made no changes to that)
- DEVCFG clock settings are set correctly (UPPLEN is 0 / ON, UPLLIDIV = DIV_2)
- OSCCON clock settings are set correctly (UFRCEN is 0, i.e. Primary Oscillator is used as input for the USBPLL)
- Primary oscillator seems to work (8MHz, system clock is switched to POSCPLL during initialization)
 
I could upload code if needed of course, but maybe these two specific questions can be answered without it:
1. The ULOCK bit in OSCCON register remains 0, indicating that the USBPLL is "out of lock or USB PLL module start-up timer is in progress or USB PLL is disabled", but even after milliseconds, or seconds, this bit never gets set. What could this indicate? Should it be set?
2. What actually starts the transfer of device descriptors to the pc? Or is it sent automatically when prepared correctly?
 
Best regards,
#1

18 Replies Related Threads

    TS9
    Super Member
    • Total Posts : 785
    • Reward points : 0
    • Joined: 2010/05/07 10:52:22
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/25 09:59:18 (permalink)
    0
    Are you using MLA or Harmony?
    #2
    Memen
    Starting Member
    • Total Posts : 35
    • Reward points : 0
    • Joined: 2017/04/08 12:17:32
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/25 12:45:15 (permalink)
    0
    Neither, I am writing my own implementation (I have tried both Harmony and MAL, but the code is just plain unreadable and not working for PIC32MX). The code is in C++, I am not sure people here are waiting for multiple files of code to look into, so I stated the two questions first instead. Hoping someone could explain and/or check with a working USB module on the PIC32MX..
    #3
    Memen
    Starting Member
    • Total Posts : 35
    • Reward points : 0
    • Joined: 2017/04/08 12:17:32
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/27 02:57:57 (permalink)
    0
    Attached I have a working minimal project (MPLAB X v5.15, XC32++ v2.15) that shows the behavior of the first post.
     
    I have tested with a logic analyzer to check the first time the USB module receives a "Token Processing Complete" interrupt. The first interrupt occurs at timestamp 0 in the txt file.
     
    How do I know the USB module is sending or receiving? And why is the interrupt so much time after the SETUP and DATA0 packets?
    Actually this part looks promising, since the one of the packets is an ACK packet, which should have been sent by the PIC32 right?
    post edited by Memen - 2019/07/27 03:36:14
    #4
    davekw7x
    Entropy++
    • Total Posts : 1814
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Second star on the right, straight on till morning
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/27 11:50:07 (permalink)
    0
    Memen
     
    How do I know the USB module is sending or receiving? And why is the interrupt so much time after the SETUP and DATA0 packets?

    I use Wireshark on my Linux workstation.  (Wireshark is also available for Windows, but I don't use it.)
     
    Bottom line: Wireshark can show the goesintas and the comesoutas with details of each packet. Very specific filtering can be setup to eliminate stuff you don't want to see.
     
    Regards,
     
    Dave
     
    post edited by davekw7x - 2019/07/27 11:53:29

    Attached Image(s)


    Sometimes I just can't help myself...
    #5
    cvm
    Super Member
    • Total Posts : 293
    • Reward points : 0
    • Joined: 2011/09/16 05:16:15
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/27 15:24:41 (permalink)
    0
    My code was designed for a pic32mm, I don't know what is different on an mx but apparently you have most of it figured out.
     
    Here is my cdc test, pick out the part where UsbDebug is used to send usb debug messages via a uart-
    https://github.com/cv007/PIC32MM_Curiosity_CPP/blob/master/cdc_test.cpp
    It would probably be more informative to see what the pic thinks is going on.
     
    Also, cdc.init() returns a bool which you can check if it is active, or can use cdc.is_active(). The Osc.cpp file comparison lit up the Meld app, so did not want to start digging around in there.  Since the actual clock values are calculated at run time, you should be able to query the Osc class to what you are getting for the various clock frequencies. To check the usb clock, there may be various things one could do- one idea would be to set the UTEYE bit to get the D lines toggling so you can measure them and get a good idea what the usb clock is doing.
     
    I would note that I did not put a license on my code. That is mostly intentional- I'm not sure I want my name on it, I have no power to enforce any license I attach, and mainly put it on github to give an idea of what I think code should/can look like as opposed to what comes out of a code generator. Those that are concerned with licenses will probably notice no license, those that are not will not. In both cases, I am fine with it. I may throw in a license file someday- mit/bsd/apache/whatever. I imagine there are about 3 users of this code, me included.
    #6
    cvm
    Super Member
    • Total Posts : 293
    • Reward points : 0
    • Joined: 2011/09/16 05:16:15
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/27 16:11:28 (permalink)
    4 (1)
    I was looking around the Osc.cpp file to see what I could find (looks ok, but it would be an easy place to get something wrong), and would just point out something-
     
    //Reg::val(OSCCON + 2, m); <-- WRITE TO ODD ADDRESS: REMOVE
     
    The OSCCON register is different in the pic32mm, so nothing wrong with replacing those lines. I would just point out that the (overloaded) 'val' function template in Reg.hpp uses the second argument type to get the pointer type (width). So in this case 'm' is an enum of type uint8_t, which means the write to the register OSCCON (byte address OSCCON+2) is done as a uint8_t*, which means it will work without an alignment error. So 'val' writes whatever width the second argument is.
     
    But, do this
     
    //Reg::val(OSCCON + 3, d<<3); <-- WRITE TO ODD ADDRESS: REMOVE
     
    and the 'd' (uint8_t) may (or will) be promoted to an int because of the <<3, so the 'val' may see something wider than a uint8_t, and be trying to write with an instruction that requires alignment, which will end up with an alignment error.
     
    I think I have changed my tune on this (letting the template figure out the width of the arg type), and now just add specific functions for each width- val8, val16, val32 (just like the read versions). Then you can see what you are doing, do not have to cast a value when uncertain if integer promotion will be done, and probably just makes it clearer what will actually happen.
    #7
    Memen
    Starting Member
    • Total Posts : 35
    • Reward points : 0
    • Joined: 2017/04/08 12:17:32
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/29 06:08:34 (permalink)
    0
    Thanks for your suggestions!
     
    I tried and used Wireshark, it is much more detailed than other USB analyzers, so that is great! It seems however it does not work for packets behind a USB hub?
     
    Attached the eyetest result from the start. In the beginning timing seems off, but after the first 0.7us the pattern is actually correct I think.
     
    I have tried to add a delay after powering on the USB module (as that is when the USB pll will be turned on), but it still shows the same weird timing at the beginning:
     {
            Usb usb;
            usb.power(Usb::POWER::USBPWR, true);
            Delay::wait(1_ms);
            usb.config(Usb::EYETEST, true);
            Delay::wait(2_ms);
            usb.config(Usb::EYETEST, false);
        }

     
    The output of the UsbDebug over UART would indeed be very useful, but I don't have a decent way of showing that on windows. What are you using to display the uart output?
     
     bool cdc_active = cdc.init(true);
    actually returns true, so initialization seems okay. If I let the code run, Windows does not see a new device (checked device manager), also no error is given at all. Only if the code is halted windows generates the "The USB-device is not recognized" notification.
     
    Do you have any links as to find out what packets I should see on a USB cdc acm device?
    post edited by Memen - 2019/07/29 06:11:43

    Attached Image(s)

    #8
    davekw7x
    Entropy++
    • Total Posts : 1814
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Second star on the right, straight on till morning
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/29 07:46:46 (permalink)
    0
    Memen
    I tried and used Wireshark, it is much more detailed than other USB analyzers, so that is great! It seems however it does not work for packets behind a USB hub?

     
    [Disclaimer]
    I haven't tried to debug you application, and I don't suppose I will.  I just compiled your code and uploaded to my PIC32 Ethernet StarterKitII for purposes of showing the Wireshark capture.
    [/Disclaimer]

    My tests were with an external USB 2.0 hub.  In my "Captured" screenshot, the lines showing Source and Destination 3.0 are Request/Response packets from my "Pluggable USB 2.0 7-port hub."  The hub shows up on Bus 001, Device 003 under lsusb as "Treminus Technology Inc. FE 2.1 7-port hub."  Bus 001 is the motherboard hub's USB connection port 1.

    The packet that I have highlighted, showing response Source 0.0, is from the ESKII plugged into one of the ports on the hub. The "0.0" means that it has not gotten through the attachment sequence.

    As long as a device is responding to Get Descriptor Request from the USB host, the host will keep trying to complete the attachment sequence.  When you halt the PIC32 for debugging, the host will give up after a certain number of non-responses, and the OS gives an error message.  (At least that what I see.)

    Memen
    The output of the UsbDebug over UART would indeed be very useful, but I don't have a decent way of showing that on windows. What are you using to display the uart output?


    For my own projects I simply use one of the UARTs with Tx/Rx connected through an RS232-to-logic converter on a serial port and run a terminal emulator (minicom) at 115200 Baud.

    For Windows users, If you don't already have a favourite terminal emulator I suggest putty.

    For "modern" computers that don't have RS232 serial ports, note that USB-to-logic adapters are available on e-bay for a few bucks (or you can use a Microchip MCP2200 Breakout Module or some such thing).

    My (home-brew) RS232 adapters use a MAX3232 that obtains power from the target and, therefore, automatically has logic levels set to the appropriate voltage. Similarly for my USB-to-logic adapters using one of the FTDI chips.   If you buy an adapter, be sure to get one that is configured (or configurable) for 3.3V logic levels.

    Regards,

    Dave


    post edited by davekw7x - 2019/07/29 07:50:03

    Sometimes I just can't help myself...
    #9
    cvm
    Super Member
    • Total Posts : 293
    • Reward points : 0
    • Joined: 2011/09/16 05:16:15
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/29 11:22:45 (permalink)
    0
    I connected up my curiosity, and captured the debug output when connecting to usb. I have my uart connected to an Onion Omega2 (little Linux module with wifi), and I ssh into it to see the uart output from my pic32mm. I also have the uart cranked up to 921600 (1Mbaud actual), so may want/need to lower it if anything in the uart path cannot handle that. I have it cranked up so will have less impact on timing (I think 115200/230400 will also work ok and not cause any problems when enumerating with debug on).
     
    For terminal app in Windows, I would use putty. Note, there is 'markup' turned on in the usb debug output, so will get ansi color codes. If using some terminal app that doesn't handle that, it will not very nice. Putty will handle it.
     
    My cdc.is_active() / return from cdc.init() may not be totally correct, I think it just returns true if the 'attach' code was reached.
    #10
    cvm
    Super Member
    • Total Posts : 293
    • Reward points : 0
    • Joined: 2011/09/16 05:16:15
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/29 12:18:36 (permalink)
    0
    > Note, there is 'markup' turned on in the usb debug output, so will get ansi color codes
     
    Actually, markup has to be turned on first (read Markup.hpp) so if not turned on the markup code will be stripped out (plain output, no colors). The markup can be enabled/disabled via a uart printf string- if it contains the markup on/off code "{+}" or "{-}", then it will enable/disable markup.
    #11
    Memen
    Starting Member
    • Total Posts : 35
    • Reward points : 0
    • Joined: 2017/04/08 12:17:32
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/30 03:15:25 (permalink)
    0
    Unfortunately, I only have a Bus Pirate v4 which does not see anything on UART for some reason. I tried to capture as much as posisble with a logic analyzer, but it can only capture the first 14 lines due to limited memory. The output seems to be exactly the same as with your file:
               ][UsbCentral.cpp][init          ] usb started  
    [0001078921][UsbEP.cpp     ][setup         ] <-- [even][data0][64b]  
    [0005718981][UsbCentral.cpp][service       ] frame: 1742  ustat: 0  
    [0006949058][UsbEP.cpp     ][service       ] ustat: 0  ep: 0  pid: 13  bdt: 00080034  
    [0008737993][UsbEP.cpp     ][service       ] ustat: 0  ep: 0  pid: 13  bdt: 00080034  
    [0010527145][UsbEP.cpp     ][control       ] pkt: 80 06 0100 0000 0040  
    [0012024999][UsbEP.cpp     ][setup         ] --> [even][data1][18b]  
    [0013460374][UsbEP.cpp     ][setup         ] <-- [odd][data1][64b]  
    [0014874987][UsbEP.cpp     ][setup         ] <-- [even][data0][64b]  
    [0016311801][UsbCentral.cpp][service       ] frame: 224  ustat: 2  
    [0017704216][UsbEP.cpp     ][service       ] ustat: 2  ep: 0  pid: 9  bdt: 00120064  
    [0019473113][UsbCentral.cpp][service       ] frame: 382  ustat: 1  
    [0020866275][UsbEP.cpp     ][service       ] ustat: 1  ep: 0  pid: 1  bdt: 00000044  
    [0022634452][UsbCentral.cpp][init          ] usb started 

     
    Problem is most likely somewhere else. If everything would work correct, I should see a serial device in device manager with a COMx number to it right?
     
    For the further debug output I will have to wait till I receive the USB-Uart TTL device I just ordered, will get back to this problem as soon as I have it. Thanks a lot for helping!
     
    Best regards,
    #12
    cvm
    Super Member
    • Total Posts : 293
    • Reward points : 0
    • Joined: 2011/09/16 05:16:15
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/30 03:49:53 (permalink)
    0
    I have never hooked up to a Windows pc with my code (Linux only). I think it doesn't make any difference, though and it does seem you are making it to the second 'init' (first part pc just wants to get the control endpoint size, then resets usb and starts over).
     
    I'm not sure what Windows does on cdc devices now days, maybe it still wants a driver. If so you would see an unknown device in device manager (and you could view its properties in device manager where you could see the vid/pid). But I also think Windows would have started to ask for a driver if it was looking for one.
     
    Here is a utility that will show/log usb connections-
    http://nirsoft.net/utils/usb_log_view.html
    #13
    Memen
    Starting Member
    • Total Posts : 35
    • Reward points : 0
    • Joined: 2017/04/08 12:17:32
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/30 08:20:04 (permalink)
    0
    Just plugged it in on a linux pc, it actually enumerates correctly. I have no idea how to open a serial port on linux command line, but it showed up on "sudo lsusb -v" as attached below. It seems that enumeration is correct, but it is not working on Windows. I do not think it is due to drivers, as the Bus Pirate shows up immediately after connecting as a COMx device.

    I tried the tool you mentioned, but it does not detect the pic32mx. I can see the Bus Pirate connecting (it is a PIC24FJ..) though, attached image shows the properties of this device.
    post edited by Memen - 2019/07/30 08:33:21

    Attached Image(s)

    #14
    nigelwright7557
    Super Member
    • Total Posts : 284
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: online
    Re: PIC32MX USB PLL 2019/07/30 09:51:27 (permalink)
    0
    I haven't had many problems getting usb to work with pci32mx and harmony.
    I did get caught out with the usb pll which I set to 96MHz when it should be 48MHz.
    I just used the USB HID example code and set up harmony to use usb.
     
    #15
    cvm
    Super Member
    • Total Posts : 293
    • Reward points : 0
    • Joined: 2011/09/16 05:16:15
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/07/30 13:11:59 (permalink)
    0
    > I have no idea how to open a serial port on linux command line
     
    You can open a terminal, use 'dmesg -w'  to watch various events- you will see when the device is plugged in, and you will also see what the device name is- most likely ttyACM0
     
    Once you have the device name, there are various ways to access the port. One option is to get a terminal app like putty (sudo apt install putty -will probably do it), another is to simply use the terminal to view the incoming rx traffic.
     
    stty -F /dev/ttyACM0 19200 #to set whatever baud you used
    cat /dev/ttyACM0 #will simply read that 'file' (everything is a file), ctrl-c to cancel
     
    #16
    Memen
    Starting Member
    • Total Posts : 35
    • Reward points : 0
    • Joined: 2017/04/08 12:17:32
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/08/21 12:39:30 (permalink)
    0
    Finally received the USB->TTL converter! I set the UART baud rate to 2M in order to get a clear output and I attached the file with debug output.
     
    The thing I noted is that the output on my pic32 keeps repeating. Up to line 18 everything is the same as in your case. However line 19 the control packet is repeated, whereas it changes in your debug output. From there repetition starts and no usb address is set.
     
    Any ideas what the issue might be?
     
    I did test on linux as well, however I could not get it to work either. The repetition did not occur on linux. I will try and collect the debug output for linux enumeration tomorrow. Do you have a chance to test maybe on windows to see the behavior of your correct working device there?
    #17
    nigelwright7557
    Super Member
    • Total Posts : 284
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: online
    Re: PIC32MX USB PLL 2019/08/21 13:05:05 (permalink)
    0

    I remember back in the dark days of PIC32MX USB.
    I messed around for ages trying to get something that worked.
    In the end despite "48MHz USB" being greyed it was in fact the USB PLL that was wrong !
    "48MHz USB" should go red if incorrect.
    I enclose picture of Harmony USB clock setup assuming 8MHz crystal.
     
    post edited by nigelwright7557 - 2019/08/21 13:06:36
    #18
    Memen
    Starting Member
    • Total Posts : 35
    • Reward points : 0
    • Joined: 2017/04/08 12:17:32
    • Location: 0
    • Status: offline
    Re: PIC32MX USB PLL 2019/08/22 05:57:39 (permalink)
    0
    nigelwright7557: I have checked and UPPLIDIV = DIV_2 and UPLLEN = ON in configuration, which should result in a 48MHz clock if I am not mistaken. Or do you mean that the system clock should also be 48MHz?
     
    Just tested on Ubuntu 18.04 LTS and enumeration looks similar to cvm's debug output. However, when I do 'stty -F /dev/ttyACM0 19200' or 'cat /dev/ttyACM0' nothing shows up. The txcallback is called though, so it seems cdc.write is successful. The code for the cdc.write is:
    d_xmit_dly.set(1500_ms); // delay between sending
    static char hw[] = "\033[3_mHello ";
    static int color = 1;
    hw[3] = color + '0'; // replace _ with 1-7
    color++;
    if (color > 7) color = 1;
    if (d_cdc.write((char const *) hw, txcallback))
      led1.on();

     
    The debug output that shows every other second (for every cdc.write) is
    [3023220842][UsbEP.cpp ][setup ] --> [even][data0][11b]
    [3023280425][UsbCentral.cpp][service ] frame: 1935 ustat: 10
    [3023298915][UsbEP.cpp ][service ] ustat: 10 ep: 2 pid: 9 bdt: 000b0024

     
    On Windows still no luck. Not sure how to proceed there, as I cannot find good documentation on device requirements or on how it differs with Linux.
    post edited by Memen - 2019/08/22 06:01:27
    #19
    Jump to:
    © 2019 APG vNext Commercial Version 4.5