Last edited:
................
malloc() is reentrant?
.... Once you solve that USB Serial issue and provide a 'none' type for the USB port,
I forget which particular post it was, but we discussed having a 'none' option in the menu for USB to allow custom code/disable USB. The idea here is to present power savings or custom code.Can you refresh my memory on this particular issue, and perhaps explain in more detail. Or if there's a prior message with all that, just a link to it would be fine.
Whatever this issue is, it's not currently on my TO-DO list.
Calling malloc() from an ISR might cause a big increase in interrupt latency? Malloc() can loop looking for a right-sized free block, etc.
First time I've heard/read of someone doing such from an ISR, in the embedded world.
Bulk Register to USB Host @ 0x1FFF88D4
Bulk Register to USB Host Address Pool @ 0x1FFF88D8
MAX3421E 'this' USB Host @ 0x1FFF88D4
MAX3421E 'this' USB Host Address Pool @ 0x1FFF88DC
Configuring HOST USB Host @ 0x1FFF88D8
Configuring HOST USB Host Address Pool @ 0x1FFF88DC
Bulk Init from USB Host @ 0x1FFF88D4
Bulk Init USB Host Address Pool @ 0x1FFF88D8
class MAX3421E_HOST :
#if defined(SWI_IRQ_NUM)
public dyn_SWI,
#endif
public UHS_USB_HOST_BASE
{
....
}
class MAX3421E_HOST :
public UHS_USB_HOST_BASE
#if defined(SWI_IRQ_NUM)
, public dyn_SWI
#endif
{
....
}
Bulk Register to USB Host @ 0x1FFF88D4
Bulk Register to USB Host Address Pool @ 0x1FFF88D8
MAX3421E 'this' USB Host @ 0x1FFF88D4
MAX3421E 'this' USB Host Address Pool @ 0x1FFF88D8
HOST USB Host @ 0x1FFF88D4
HOST USB Host Address Pool @ 0x1FFF88D8
Bulk Init from USB Host @ 0x1FFF88D4
Bulk Init USB Host Address Pool @ 0x1FFF88D8
Maybe this is a sign you'd be better off with a simple static callback?
Each ordinary C++ member function has a compiler-generated parameter called this, which is a pointer to an object of the member function’s class type. Each ordinary member function call passes a value for this along with values for any of the function’s explicitly declared parameters. Interrupt handlers are not passed arguments by the host microprocessor, however, so ordinary C++ member functions cannot be used directly as ISRs.
C++ provides the static keyword for defining member functions that do not take a this pointer. A static member function is therefore akin to a typical C function, including its suitability for direct use as an ISR. However, the absence of the this pointer creates the expected limitation: a static member function cannot directly manipulate non-static data members of its class.
Interrupt tester
28 Interrupts available.
16 (0)...OK.
17 (1)...OK.
18 (2)...OK.
19 (3)...OK.
20 (4)...OK.
21 (5)...OK.
22 (6)...OK.
23 (7)...OK.
24 (8)...OK.
25 (9)...OK.
26 (10)...OK.
27 (11)...OK.
28 (12)...OK.
29 (13)...OK.
30 (14)...OK.
31 (15)...OK.
32 (16)...OK.
33 (17)...OK.
34 (18)...OK.
35 (19)...OK.
36 (20)...OK.
37 (21)...OK.
38 (22)...OK.
39 (23)...OK.
40 (24)...OK.
41 (25)...OK.
42 (26)...OK.
43 (27)...OK.
Done.
#if !defined(NVIC_SET_PENDING)
#define NVIC_SET_PENDING(n) NVIC_SetPendingIRQ((IRQn_Type)n)
#endif
#if !defined(NVIC_ENABLE_IRQ)
#define NVIC_ENABLE_IRQ(n) NVIC_EnableIRQ((IRQn_Type)n)
#endif
volatile int chk;
#if defined(CORE_TEENSY)
const unsigned char swInterrupts[] = {
#if defined(__MK20DX128__)
5,
#elif defined(__MK20DX256__)
17,23,28,37,38,39,40,41,42,43,51,52,53,54,55,56,75,76,77,78,79,80,82,86,92,93,
#endif
IRQ_UART0_LON,
IRQ_SOFTWARE,
0};
#else
extern "C" {
#define NVIC_NUM_INTERRUPTS ((int)PERIPH_COUNT_IRQn)
#define VECTORTABLE_SIZE (NVIC_NUM_INTERRUPTS+16)
#define VECTORTABLE_ALIGNMENT (0x100ul)
uint32_t _VectorsRam[VECTORTABLE_SIZE] __attribute__((aligned(VECTORTABLE_ALIGNMENT)));
}
#endif
void softISR() {
chk = 1;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
Serial.println("...OK.");
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
while(!Serial);
Serial.println("\r\nInterrupt tester");
Serial.print(NVIC_NUM_INTERRUPTS, DEC);
Serial.println(" Interrupts available.");
#if defined(CORE_TEENSY)
unsigned char n = 0;
while (swInterrupts[n] > 0) {
int interrupt = swInterrupts[n];
_VectorsRam[interrupt+16] = (uint32_t)softISR;
NVIC_ENABLE_IRQ(interrupt);
n++;
}
#else
uint32_t *X_Vectors = (uint32_t *)((uint32_t)SCB->VTOR);
for(int i = 0; i < VECTORTABLE_SIZE; i++) {
_VectorsRam[i] = X_Vectors[i]; /* copy vector table to RAM */
}
/* relocate vector table */
__disable_irq();
SCB->VTOR = (uint32_t) & _VectorsRam;
__DSB();
__enable_irq();
for(int interrupt=0; interrupt<NVIC_NUM_INTERRUPTS; interrupt++) {
_VectorsRam[interrupt+16] = (uint32_t)softISR;
NVIC_ENABLE_IRQ(interrupt);
}
#endif
}
void loop() {
#if defined(CORE_TEENSY)
unsigned char n = 0;
while (swInterrupts[n] > 0) {
int interrupt = swInterrupts[n];
Serial.print(interrupt + 16);
Serial.print(" (");
Serial.print(interrupt);
Serial.print(")");
chk = 0;
NVIC_SET_PENDING(interrupt);
delay(500);
if (!chk) Serial.println("...NOT OK.");
n++;
}
#else
for(int interrupt=0; interrupt<PERIPH_COUNT_IRQn; interrupt++) {
Serial.print(interrupt + 16);
Serial.print(" (");
Serial.print(interrupt);
Serial.print(")");
chk = 0;
NVIC_SET_PENDING(interrupt);
delay(500);
if (!chk) Serial.println("...NOT OK.");
}
#endif
Serial.println("Done.");
while(1){;}
}
Exactly, and more than one device when you attach a hub.I'm trying to understand the state of USB host mode and when it might be possible to do things like connect typical USB devices to a Teensy 3 such as a USB keyboard, flash memory stick, wifi dongle, etc.
Partially. "None" mode would allow for custom device mode. Another option, 'host' mode would allow host. There should be an 'OTG' mode also, to allow switching. All three would be nearly the same, but not quite.If I understand xxajk correctly, he's very close to having USB Host mode support (without an additional circuit board), but he's waiting on a couple of tweaks to the current usb mode/boards.txt support to allow a "none" mode.
I'll have to take a look at that and see if I can gleen anything useful from it.There's also work going on by Pedvide but it is in a nascent state. At least a couple of others have indicated interest in working on the problem.
Yes, and the initial development is using the UHS mini. One thing I know that Paul is going to have to be convinced of is using malloc in an ISR. It is totally safe though once the additional library bits are added.As of now, the practical alternatives I'm aware of are either to use the Circuits@Home USB Host Shield for Arduino Pro Mini or to use alternate interfaces such as serial, I2C, SPI, etc.
//(c) Frank B 2017/4
//License: MIT
void listInterrupts() {
unsigned adrFaultNMI = (unsigned)_VectorsRam[3];
unsigned adrUnusedInt = (unsigned)_VectorsRam[IRQ_FTFL_COLLISION + 16];//IRQ_FTFL_COLLISION is normally unused
unsigned adr;
Serial.println("Interrupts in use:");
Serial.println("NMI (non-maskable):");
for (unsigned i = 1; i < 16; i++) {
adr = (unsigned)_VectorsRam[i];
if (adr != adrUnusedInt) {
Serial.print(i);
Serial.print(": \t");
if (adr == adrFaultNMI) {
Serial.print("Fault NMI");
} else {
Serial.print("\t");
}
Serial.print("\t0x");
Serial.print(adr, HEX);
Serial.println();
}
}
Serial.println("IRQ:");
for (unsigned i = 0; i < NVIC_NUM_INTERRUPTS; i++) {
adr = (unsigned)_VectorsRam[i + 16];
if (adr != adrUnusedInt) {
Serial.print(i);
Serial.print(": ");
Serial.print("\tPriority:");
Serial.print(NVIC_GET_PRIORITY(i));
Serial.print("\t0x");
Serial.print(adr, HEX);
if (NVIC_IS_ENABLED(i)) Serial.print("\t is enabled");
Serial.println();
}
}
}
void setup() {
Serial.begin(9600);
//Serial1.begin(9600);
listInterrupts();
}
void loop() {
}
Interrupts in use:
NMI (non-maskable):
1: 0x411
3: Fault NMI 0xB31
4: Fault NMI 0xB31
5: Fault NMI 0xB31
6: Fault NMI 0xB31
7: Fault NMI 0xB31
8: Fault NMI 0xB31
9: Fault NMI 0xB31
10: Fault NMI 0xB31
13: Fault NMI 0xB31
15: 0x196D
IRQ:
31: Priority:64 0xA1D is enabled
33: Priority:128 0x90D
35: Priority:128 0x831
37: Priority:128 0x759
53: Priority:112 0x1D8D is enabled
66: Priority:128 0x681
86: Priority:128 0x19A5
A little function that is handy sometimes:
Maybe it's useful for others, too.
To stay on topic: All other interrupts can be used as "Software Interrupt".