From: notaz <notasas@gmail.com>
Date: Thu, 2 Oct 2014 23:33:13 +0000 (+0300)
Subject: teensy3lib: do level masking instead of disable
X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ad7d1ddee4bb654f8b8a8420516fcc39fc0f68d;p=megadrive.git

teensy3lib: do level masking instead of disable

we need to avoid higher priority irq latency
---

diff --git a/teensy3/kinetis.h b/teensy3/kinetis.h
index fe6a938..c2af4fa 100644
--- a/teensy3/kinetis.h
+++ b/teensy3/kinetis.h
@@ -2551,6 +2551,17 @@ typedef struct __attribute__((packed)) {
 #define __disable_irq() __asm__ volatile("CPSID i");
 #define __enable_irq()	__asm__ volatile("CPSIE i");
 
+/* only mask default irqs, see NVIC_SET_PRIORITY users
+ * note: usb code uses 112 priority */
+#define __mask_irq() do { \
+  int basepri_ = 128 - 16; \
+  __asm__ volatile("msr BASEPRI, %0" :: "r"(basepri_)); \
+} while (0)
+#define __unmask_irq() do { \
+  int basepri_ = 0; \
+  __asm__ volatile("msr BASEPRI, %0" :: "r"(basepri_)); \
+} while (0)
+
 // System Control Space (SCS), ARMv7 ref manual, B3.2, page 708
 #define SCB_CPUID		(*(const    uint32_t *)0xE000ED00) // CPUID Base Register
 #define SCB_ICSR		(*(volatile uint32_t *)0xE000ED04) // Interrupt Control and State
diff --git a/teensy3/usb_dev.c b/teensy3/usb_dev.c
index e87f158..5ff8726 100644
--- a/teensy3/usb_dev.c
+++ b/teensy3/usb_dev.c
@@ -531,13 +531,13 @@ usb_packet_t *usb_rx(uint32_t endpoint)
 	usb_packet_t *ret;
 	endpoint--;
 	if (endpoint >= NUM_ENDPOINTS) return NULL;
-	__disable_irq();
+	__mask_irq();
 	ret = rx_first[endpoint];
 	if (ret) {
 		rx_first[endpoint] = ret->next;
 		usb_rx_byte_count_data[endpoint] -= ret->len;
 	}
-	__enable_irq();
+	__unmask_irq();
 	//serial_print("rx, epidx=");
 	//serial_phex(endpoint);
 	//serial_print(", packet=");
@@ -550,11 +550,11 @@ static uint32_t usb_queue_byte_count(const usb_packet_t *p)
 {
 	uint32_t count=0;
 
-	__disable_irq();
+	__mask_irq();
 	for ( ; p; p = p->next) {
 		count += p->len;
 	}
-	__enable_irq();
+	__unmask_irq();
 	return count;
 }
 
@@ -583,9 +583,9 @@ uint32_t usb_tx_packet_count(uint32_t endpoint)
 
 	endpoint--;
 	if (endpoint >= NUM_ENDPOINTS) return 0;
-	__disable_irq();
+	__mask_irq();
 	for (p = tx_first[endpoint]; p; p = p->next) count++;
-	__enable_irq();
+	__unmask_irq();
 	return count;
 }
 
@@ -605,14 +605,14 @@ void usb_rx_memory(usb_packet_t *packet)
 
 	cfg = usb_endpoint_config_table;
 	//serial_print("rx_mem:");
-	__disable_irq();
+	__mask_irq();
 	for (i=1; i <= NUM_ENDPOINTS; i++) {
 		if (*cfg++ & USB_ENDPT_EPRXEN) {
 			if (table[index(i, RX, EVEN)].desc == 0) {
 				table[index(i, RX, EVEN)].addr = packet->buf;
 				table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
 				usb_rx_memory_needed--;
-				__enable_irq();
+				__unmask_irq();
 				//serial_phex(i);
 				//serial_print(",even\n");
 				return;
@@ -621,14 +621,14 @@ void usb_rx_memory(usb_packet_t *packet)
 				table[index(i, RX, ODD)].addr = packet->buf;
 				table[index(i, RX, ODD)].desc = BDT_DESC(64, 1);
 				usb_rx_memory_needed--;
-				__enable_irq();
+				__unmask_irq();
 				//serial_phex(i);
 				//serial_print(",odd\n");
 				return;
 			}
 		}
 	}
-	__enable_irq();
+	__unmask_irq();
 	// we should never reach this point.  If we get here, it means
 	// usb_rx_memory_needed was set greater than zero, but no memory
 	// was actually needed.
@@ -647,7 +647,7 @@ void usb_tx(uint32_t endpoint, usb_packet_t *packet)
 
 	endpoint--;
 	if (endpoint >= NUM_ENDPOINTS) return;
-	__disable_irq();
+	__mask_irq();
 	//serial_print("txstate=");
 	//serial_phex(tx_state[endpoint]);
 	//serial_print("\n");
@@ -673,13 +673,13 @@ void usb_tx(uint32_t endpoint, usb_packet_t *packet)
 			tx_last[endpoint]->next = packet;
 		}
 		tx_last[endpoint] = packet;
-		__enable_irq();
+		__unmask_irq();
 		return;
 	}
 	tx_state[endpoint] = next;
 	b->addr = packet->buf;
 	b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0);
-	__enable_irq();
+	__unmask_irq();
 }