Processor is a MK66FX1M0, reference manual is K66P144M180SF5RMV2.pdf
(actually using a Teensy 3.6 with USBHost_t36 library)
USBHS is running in host mode, at high-speed
Page 1606 section 54.3.17 USB Interrupt Enable Register (USBHS_USBINTR)
The bit is 16, NAKE, NAK Interrupt Enable
#define USBHS_USBINTR (*(volatile uint32_t *)0x400A1148) // USB Interrupt Enable Register
#define USBHS_USBINTR_TIE1 ((uint32_t)0x02000000)
#define USBHS_USBINTR_TIE0 ((uint32_t)0x01000000)
#define USBHS_USBINTR_UPIE ((uint32_t)0x00080000)
#define USBHS_USBINTR_UAIE ((uint32_t)0x00040000)
#define USBHS_USBINTR_NAKE ((uint32_t)0x00010000)
I have a rather odd project that requires me to handle the case when a bulk packet is sent from host-to-device (OUT) but receives a NAK and handle that case immediately instead of waiting for more NAKs. This ISR is not firing even though I have set both USBHS_USBINTR_NAKE and the corresponding bits in the USBHS_ENDPTNAKEN registers
Debugging further to find a root cause, it seems like: the place inside USBHS_USBINTR where USBHS_USBINTR_NAKE should be simply does not exist (like a reserved bit). Writing into it and reading it back out, bit position 16 is always zero.
Example code
#include "USBHost_t36.h"
USBHost myusb;
USBHIDParser hid1(myusb);
USBDriver *drivers[] = { &hid1, };
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char* driver_names [CNT_DEVICES] = { "hid1", };
bool driver_active[CNT_DEVICES] = { false, };
void setup()
{
while (!Serial && (millis() < 5000)) ; // wait for Arduino Serial Monitor
Serial.println("\n\nUSB Host Testing USBHS_USBINTR_NAKE");
myusb.begin();
}
void loop()
{
myusb.Task();
USBHS_USBINTR |= (1 << 16); // explicitly use the number 16 instead of USBHS_USBINTR_NAKE
if ((USBHS_USBINTR & (1 << 16)) == 0)
{
Serial.printf("Error: NAKE not written, 0x%08X\n", USBHS_USBINTR);
delay(500);
}
}
The NAKE bit fails to be written, the register reads back as 0x030C0016, what is expected is 0x030D0016
Another try
#include "USBHost_t36.h"
USBHost myusb;
USBHIDParser hid1(myusb);
USBDriver *drivers[] = { &hid1, };
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char* driver_names [CNT_DEVICES] = { "hid1", };
bool driver_active[CNT_DEVICES] = { false, };
void setup()
{
while (!Serial && (millis() < 5000)) ; // wait for Arduino Serial Monitor
Serial.println("\n\nUSB Host Testing USBHS_USBINTR_NAKE");
myusb.begin();
}
void loop()
{
myusb.Task();
USBHS_USBINTR = 0xFFFFFFFF;
Serial.printf("USBHS_USBINTR: 0x%08X\n", USBHS_USBINTR);
delay(500);
}
The register reads back as 0x030C00BF, but I expected 0x030D00BF if bit position 16 was writable
What is going on? Where is USBHS_USBINTR_NAKE? How do I generate a ISR when I get a NAK?
(NOTE: there is no code that clears USBHS_USBINTR without me knowing about it)
(NOTE: I have tried writing to USBHS_ENDPTNAKEN before writing to USBHS_USBINTR, it does NOT help)
(NOTE: I am using a USB HS analyzer, TotalPhase Beagle USB 480, I can see every single ACK, NAK, SOF, ping, etc)
(NOTE: I checked the errata about this)
Thanks
Frank
Hi @frankzhao_sony ,
The USB_USBINTR[NAKE] bit is for device mode only. In host mode, this bit can't write. You can download K66 SDK and compare in host and device demo in the SDK.
Regards,
Jing