USB Keyboard

This week, I was able to pinpoint the reason behind the erratic behaviour of the board. Upon rereading the documentation for the Harmony USB Libraries, I found out that in particular for the PIC32MZ family of microcontrollers which includes the board that we were working on, the buffers that are sent to most library functions are required to be placed in coherent memory and aligned at a 16 byte boundary. This was not needed in the Ethernet Starter Kit as it uses the PIC32MX family of microcontrollers and hence causing issues when porting the code for the PIC32MZ microcontrollers. Adding the line

__attribute__((coherent, aligned(16)))

to each of the buffers used quickly solved the problem.

With that done and the code working consistently, getting the debugging functionality to work using the USB CDC class also proved to be quite simple as it shared a similar codebase to the USB HID code that was used to get the keyboard working. I then conducted a few tests which are documented below:

On Windows, the keyboard worked flawlessly out of the box without requiring any additional delays. The detection of NumLock and CapsLock keys also works which helps to print out the string in the proper casing in the event that one’s computer has their keyboard CapsLock activated by inversing the capitalisation of the outputted string depending on their CapsLock status.

On the work computers which run on Linux, it still takes an unusually long time to load before receiving the report indicating the status of NumLock and CapsLock keys. Keen to get the keyboard to activate faster on the work computers for debugging purposes, I checked the kernel log and it turns out that some kind of USB HID report is timing out after every 10 seconds the device is connected. This managed to confirm my suspicions that something must be missing in the code considering the fact that a regular keyboard can be connected to the work computers and work almost immediately unlike the board we were working on. With this clue in mind, I dived in the Harmony USB documentation once more to find out the event that is called when the USB HID Host requests for a report. To send the report when requested, in the USB HID Event Handler task I added

USB_DEVICE_ControlSend(deviceHandle, keyboardReportRequest, ((USB_DEVICE_HID_EVENT_DATA_GET_REPORT*)eventData)->reportLength);

whereby keyboardReportRequest is a blank 8 byte array which gets the job done. The work computers however, still needed a delay between receiving the first Output Report (NumsLock data, CapsLock data, etc) and sending the first character of the payload or the first few characters of the payload will not be interpreted by the computer. This required a delay to avoid missing out on the first few characters of the payload. However, this delay was for some reason not required by Windows where the board can instantly deploy the keypresses upon receiving the first Output Report. Also another difference between the Windows and Linux computers was that the USB_DEVICE_HID_EVENT_GET_REPORT was not even called by Windows which in a way shows how the behaviour of boards can change in multiple environments.

On Mac, I had to choose the European settings for the keyboard to get it to configure properly or the keyboard configuration prompt will keep popping-up when I choose the other setting (some Japanese-sounding keyboard configuration if I recall properly).

At the end of the week, Dr. Shawn briefed me on my next task which was to get the PIC to emulate a modem by translating serial commands into actions done by the TCP/IP stack and also to merge the USB HID and CDC codes into the main board firmware while fixing any bugs in the firmware while I am at it.

You may also like...

Leave a Reply