Thursday, August 27, 2020

Lego Time

 Here is a brief look at some of the items we are looking at integrating into the Brick Controller in some form, yet to be determined.


Here is a bigger look at what is coming.



Bluetooth Integration (part 2)

Another frustrating late night.  It was mostly working for a while, but tapping the serial port between the RN4020 and the PIC32, caused the RN4020 initialization data not to be transferred, consistently.  I can only suspect that the 6 inch wire to the RS232-USB converter is causing the problem.  

It was the most stable with the PICKit3 attached. Which is a change from previous testing.  One item I am becoming more convinced about is the issue is related to order of execution and/or timing.  The PICKit3 effect (good or bad) is an indication of timing.  I have been looking very carefully at order of execution.  One item I noticed is that I was trying to send debug info through the USB connection, before there was a connection.  In the PIC18F implementations, this was not a problem, since the executive loop did not execute that portion until the USB was connected.  That is now fixed.  But I suspect there are still other order of execution issues and timing issues.  

Finally there are issues with decoding the BT commands.  For whatever reason the RN4020 is assigning different handles to the different characteristics.  I need to go back and review all of the BT products and see what handles were assigned to what characteristics.


Wednesday, August 26, 2020

Bluetooth Integration

I have been distracted again by my life, but integration does go on, just slowly.  I soldered down the RN4020 module to the prototype.  It works, sort of.  It is flaky on starting, as in sometimes it starts and sometimes it doesn't.  There is no true power on reset pin. All of the control pins are under PIC32 control and the start sequence is the same as all of the other RN4020 equipped systems I have done.  Not to mention that the PIC32 firmware doesn't always start.  And to make life even more fun, attaching the various serial ports cause issues.  See this post for serial ports.

Using the debugger and the console output seemed to cause different scenarios.  The PICKit3 especially caused different things to happen.  But what I did notice was the code seemed to be caught in an interrupt loop for the BT UART.  Part of the problem was the Harmony initializing code.  I have always cleared all of the flags before enabling the interrupts and disabling any interrupts that dont have ISRs.  Well only part of that was happening.

There are 3 interrupts for the UART, these are Tx, Rx and ERROR.  First the flags were not being cleared until the UART was opened, but at that point the interrupts were already enabled in the SYSTEM_INIT module.  Also the ISRs are not registered until the after the UART is opened. The list goes on.  Again this is a problem with Harmony when you have multiple peripherals, mostly interrupt driven, the order of instantiation has to be carefully reviewed.

I carefully went through the order, made sure the flags were always cleared when going through the interrupt.  Now it is more stable, though we are not still where the PIC18F25K50 firmware is.  This still needs more analysis.  I suspect I need to implement an UART ERROR ISR, just to see what is happening.

Tuesday, August 18, 2020

USB HID Failing (Solved)

This problem has really bothered me, since I know it should be fixable.  After searching the Microchip site, I finally found the Harmony USB Reference for V2.06. (Be careful, Ver1.11 still exists. Don't know if there are differences.)  Digging through this and going back to the original Harmony HID example program, I found a slight difference.  

As I noted in the previous post, the Device Suspend, Device Resume and HID Set IDLE sequence bothered me.  Looking at the USB Reference, they specifically note that neither Device Suspend or Device Resume require a response from the PIC32 Application.  The example program only does a SYS_PRINT for each state in the state machine.  However for some reason I changed the state of the USB_Tasks STATE MACHINE to WAIT_FOR_CONFIGURATION.  Not sure why I did this, but this is where the HID Rx HANDLE is being change to invalid.

This is happening in the function call to USB_DEVICE_HID_ReportReceive.  The USB reference has this for the description of the function call

This function submits the buffer to HID function driver library to receive a report from host to device. On completion of the transfer the library generates USB_DEVICE_HID_EVENT_REPORT_RECEIVED event to the application. A handle to the request is passed in the transferHandle parameter. The transfer handle expires when event handler for the USB_DEVICE_HID_EVENT_REPORT_RECEIVED exits. If the receive request could not be accepted, the function returns an error code and transferHandle will contain the value USB_DEVICE_HID_TRANSFER_HANDLE_INVALID.

The important part to note is the last line, the transferHandle value is changed to INVALID.  Additionally this function returns one of 4 results.  Currently this result is never checked. 

It now became obvious that ReportRecieve function was changing the transferHandle to invalid, because it is called in the WAIT_FOR_CONFIGURATION state of the USB Tasks state machine.  This function call was needed after configuration in the initial configuration or the USB connection would not work.  But at this state of the connection, this is causing a problem.   So I changed the action in the Device Suspend state to "no action".  

After testing, this change solved the problem.  The Brick Controller 2 goes through the sequence of SUSPEND, RESUME and HID SET IDLE, but the transferHandle is not invalidated.  When the MyMakerTools software starts, it connects normally.  Problem Solved.

One last comment.  I have said this before, the generated Harmony Source in APP.C is quite good, but it is not production code.  There is insufficient error handling.  The USB Reference provides a good starting point to providing proper error handling, but you will have implement the code yourself.





 

Sunday, August 16, 2020

USB HID Failing (Long Term connection)

 I have been running long term tests on the Brick Controller 2.  The setup is as follows:

Connection

  • USB connected to PC
  • Debug Serial Port connected to PC
  • PICKit3 connected only to program PIC32
  • LEDs hooked up only to verify PC connectivity and response

PC

  • TeraTerm to watch the debug serial port
  • HID Device Tester-PC program to report what Windows see as plugged in HID devices
  • MyMakerTools BrickBuddy software ready to run, but not running

Test Process

  1. Download program into PIC32
  2. Verify the BC2 connects to PC via debug serial port and HID device tester
  3. Start MyMakerTools software to verify HID connection and control of deivce (exercise LEDs)
  4. Close MyMakerTools software
  5. Wait 60 to 90 minutes, sometimes hours
  6. Repeat steps 3 thru 5 until failure occurs

The first data showed that the failure is happening in the USBDeviceHIDEventHandler, which is part of the Harmony framework.  The event handler is triggered by the USB framework that is part of the USB driver/middleware of the Harmony Framework. 

When the MyMakerTools software starts up it sends a report (USB terminology) to the device, basically it is a 64 byte message to start the application level connection process so the PC software can determine what is connected.  The event that is triggered in the Brick Controller 2 is:

USB_DEVICE_HID_EVENT_REPORT_RECEIVED

Here are the comments from the Harmony Framework

    /* The eventData parameter will be
   * USB_DEVICE_HID_EVENT_REPORT_RECEIVED pointer type containing
   * details about the report that was received. */

What this does is take the pointer to the eventData that is passed to the HID event handler from the USB driver and cast it as report received type.  The next thing it does is check the driver handle to see if it matches the handle when the USB device was opened.  For some reason it is not matching.

What I tried was to implement a restart of the USB driver.  I created a new state in USB tasks called USB_STATE_RESTART.  In this new state I call USB_DEVICE_CLOSE with the handle.  Then I start the USB initialization again, reopening the the USB Device.  This failed to do a complete restart, but I did not have enough debug info to determine what was happening.

On the next capture, the UART debug port revealed the USB EVENT handler had executed a Device Suspend event (this happened the last time also, but I failed to keep the capture).  The USB driver went through some tasks of trying to reconfigure, the driver handle is set to invalid and then it receives a USB Device Resume event followed by a HID SET IDLE event from the PC.  This is where I think the issue emanates from.  For whatever reason the PC puts the device into suspend, then resumes and then a HID set idle.  When I launch the MyMakerTools software, the PIC32 code detects the request, but the driver handle is invalid.  The newly added code appears to successfully re-initialize the USB driver, but it fails to connect.

Now for whatever reason, the PC is not sending the USB Device Suspend event.  It has been 36 hours and the device is still running and working.  

This is really a very small corner case, but it is bothering me.  For now I will leave it alone and go on to other items in the TODO list.  When I have time or need to do something else, I can always set this up and run the tests.







Saturday, August 15, 2020

Refactoring Brick Controller 2

One my tasks I needed to do was to refactor the PIC32 firmware.  When you build the firmware in Harmony, it places  most of the newly generated code in APP.C and APP.H.  This is not very modular, especially if you want to reuse features in a follow on project.  Here is what I did:

  • Moved all of the USB functionality (source and headers) to a separate module.  This contains the Harmony framework state machines for USB Tasks, USB Device Events and USB HID events.  All of the variables are contained in a usbData structure instead of the appData structure.  Finally it also includes generic application level handling of the messages.
  • Created a generic I2C header for use by the different I2C modules
  • Created a module for the LP5569 LED light controller IC routines, state machine and I2C implementation.  This uses the generic I2C header file to create the I2C tasks specific to the LP5569.
  • Created a module for the motor control and control of LED10, since these are all connected to output compare peripherals in the PIC32.  This generates the PWM control for the motors and LED10.
  • Created a module to handle the script execution.  This was not part of the Harmony framework, so it was already on the path as a separate module.
  • Created a module for the RN4020 BT Module.  This includes the routines for the USART port that connects the RN4020 to the PIC32. 
  • Create a module that handles the MP3 state machines and control routines for the VS1053 MP3 decoder chip.  (This is actually a TODO item, since I have not tested the new board yet.)
  • Create a module for the file system that is contained in the SST26 FLASH memory chip that holds the MP3 music file.  (This is actually a TODO item, since I have not tested the new board yet.)

So what does that leave in APP.C.  As you might recall, there is a timer generating interrupts at 100ms, 500ms and 1000ms.  The state machine to handle this in APP.C.  My thinking was this is very specific to the Application, so it should stay in APP.C.  Also APP_Tasks is here, which is the main application state machine.  After initialization, here is the main state

        case APP_STATE_SERVICE_TASKS:
     {
            USBTasks();
            FSTasks();
            MP3Tasks();
            LP5569_Tasks();
            PWMCtrl_Tasks();
            BluetoothTasks();
            NVM_Tasks();
            APP_TIMER_Tasks();
            SCRIPT_Tasks();
            break;
     }


Friday, August 14, 2020

Distraction is Done

 Well I have done all the damage to my credit card that I can.  Here is a just a few of the things I bought.


 

I already have the 3 stall version of this, but like this one, it may be missing pieces.  My idea is to build the round house, but to leave it in a partial state of construction.  3 or 4 of the stalls in use and the others under construction.  A small bit of kit bashing.

 

 This is the one engine in the Marklin line that is most produced and thus the least expensive.  I am working on a battery powered track cleaning unit.  The plan is to convert this to a DC motor/controller and then power it by battery contained in a low sided goods wagon it pulls.  As it cleans the track, it can start to recharge the battery from track power.  With a BT interface, it can be controlled by a mobile device.  Obviously there can be lots of other features that can be included.  Too many projects to do.

 

Could not resist this.  A mode modern version of the signals I already have.