Browse Source

USB touchscreen for Teensy 4.0 now working

teensy4-core
PaulStoffregen 5 years ago
parent
commit
ced1805c88
3 changed files with 39 additions and 47 deletions
  1. +4
    -1
      teensy4/usb.c
  2. +1
    -1
      teensy4/usb_desc.c
  3. +34
    -45
      teensy4/usb_touch.c

+ 4
- 1
teensy4/usb.c View File

//printf("error\n"); //printf("error\n");
} }
if ((USB1_USBINTR & USB_USBINTR_SRE) && (status & USB_USBSTS_SRI)) { if ((USB1_USBINTR & USB_USBINTR_SRE) && (status & USB_USBSTS_SRI)) {
printf("sof %d\n", usb_reboot_timer);
//printf("sof %d\n", usb_reboot_timer);
if (usb_reboot_timer) { if (usb_reboot_timer) {
if (--usb_reboot_timer == 0) { if (--usb_reboot_timer == 0) {
usb_stop_sof_interrupts(NUM_INTERFACE); usb_stop_sof_interrupts(NUM_INTERFACE);
#ifdef MIDI_INTERFACE #ifdef MIDI_INTERFACE
usb_midi_flush_output(); usb_midi_flush_output();
#endif #endif
#ifdef MULTITOUCH_INTERFACE
usb_touchscreen_update_callback();
#endif
} }
} }



+ 1
- 1
teensy4/usb_desc.c View File

MULTITOUCH_ENDPOINT | 0x80, // bEndpointAddress MULTITOUCH_ENDPOINT | 0x80, // bEndpointAddress
0x03, // bmAttributes (0x03=intr) 0x03, // bmAttributes (0x03=intr)
MULTITOUCH_SIZE, 0, // wMaxPacketSize MULTITOUCH_SIZE, 0, // wMaxPacketSize
1, // bInterval
4, // bInterval, 4 = 1ms
#endif // KEYMEDIA_INTERFACE #endif // KEYMEDIA_INTERFACE
}; };



+ 34
- 45
teensy4/usb_touch.c View File

static uint16_t ypos[MULTITOUCH_FINGERS]; static uint16_t ypos[MULTITOUCH_FINGERS];
static uint16_t scan_timestamp; static uint16_t scan_timestamp;


#define TX_NUM 20
#define TX_BUFSIZE 32 #define TX_BUFSIZE 32
static transfer_t tx_transfer[TX_NUM] __attribute__ ((used, aligned(32)));
DMAMEM static uint8_t txbuffer[TX_NUM * TX_BUFSIZE] __attribute__ ((aligned(32)));
static uint8_t tx_head=0;
static transfer_t tx_transfer __attribute__ ((used, aligned(32)));
DMAMEM static uint8_t txbuffer[TX_BUFSIZE] __attribute__ ((aligned(32)));
extern volatile uint8_t usb_high_speed;
#if MULTITOUCH_SIZE > TX_BUFSIZE #if MULTITOUCH_SIZE > TX_BUFSIZE
#error "Internal error, transmit buffer size is too small for touchscreen endpoint" #error "Internal error, transmit buffer size is too small for touchscreen endpoint"
#endif #endif


void usb_touchscreen_configure(void) void usb_touchscreen_configure(void)
{ {
memset(tx_transfer, 0, sizeof(tx_transfer));
tx_head = 0;
memset(&tx_transfer, 0, sizeof(tx_transfer));
usb_config_tx(MULTITOUCH_ENDPOINT, MULTITOUCH_SIZE, 0, NULL); usb_config_tx(MULTITOUCH_ENDPOINT, MULTITOUCH_SIZE, 0, NULL);
// TODO: need to cause usb_touchscreen_update_callback to be run on SOF
usb_start_sof_interrupts(MULTITOUCH_INTERFACE);
} }




pressure[finger] = 0; pressure[finger] = 0;
} }



static int transmit(const uint8_t *data)
{
if (!usb_configuration) return 0;
uint32_t head = tx_head;
transfer_t *xfer = tx_transfer + head;
uint32_t status = usb_transfer_status(xfer);
if ((status & 0x80)) return 0;
if (status & 0x68) {
// TODO: what if status has errors???
}
delayNanoseconds(30); // TODO: is this needed? (probably not)
uint8_t *buffer = txbuffer + head * TX_BUFSIZE;
memcpy(buffer, data, MULTITOUCH_SIZE);
usb_prepare_transfer(xfer, buffer, MULTITOUCH_SIZE, 0);
arm_dcache_flush_delete(buffer, TX_BUFSIZE);
usb_transmit(MULTITOUCH_ENDPOINT, xfer);
if (++head >= TX_NUM) head = 0;
tx_head = head;
return 1;
}

// touch report // touch report
// 0: contact id + on/off // 0: contact id + on/off
// 1: pressure // 1: pressure
// 6: scan time lsb // 6: scan time lsb
// 7: scan time msb // 7: scan time msb



// Called by the start-of-frame interrupt. // Called by the start-of-frame interrupt.
// //
void usb_touchscreen_update_callback(void) void usb_touchscreen_update_callback(void)
{ {
// TODO: if 480 speed, run only every 8th time
static uint8_t microframe_count=0;

if (usb_high_speed) {
// if 480 speed, run only every 8th micro-frame
if (++microframe_count < 8) return;
microframe_count = 0;
}

// do nothing if previous packet not yet sent
uint32_t status = usb_transfer_status(&tx_transfer);
if ((status & 0x80)) {
return;
}
if (status & 0x68) {
// TODO: what if status has errors???
}


if (scan_index == 0) { if (scan_index == 0) {
if (usb_tx_packet_count(MULTITOUCH_ENDPOINT) > 1) {
// wait to begin another scan if if more than
// one prior packet remains to transmit
return;
}
scan_timestamp = millis() * 10; scan_timestamp = millis() * 10;
scan_count = 0; scan_count = 0;
} }
contactid[scan_index] = 0; contactid[scan_index] = 0;
} }
uint8_t buffer[MULTITOUCH_SIZE]; // MULTITOUCH_SIZE = 8 uint8_t buffer[MULTITOUCH_SIZE]; // MULTITOUCH_SIZE = 8
buffer[0] = id;
buffer[1] = press;
buffer[2] = xpos[scan_index];
buffer[3] = xpos[scan_index] >> 8;
buffer[4] = ypos[scan_index];
buffer[5] = ypos[scan_index] >> 8;
buffer[6] = scan_timestamp;
buffer[7] = scan_timestamp >> 8;
if (transmit(buffer)) scan_index++;
txbuffer[0] = id;
txbuffer[1] = press;
txbuffer[2] = xpos[scan_index];
txbuffer[3] = xpos[scan_index] >> 8;
txbuffer[4] = ypos[scan_index];
txbuffer[5] = ypos[scan_index] >> 8;
txbuffer[6] = scan_timestamp;
txbuffer[7] = scan_timestamp >> 8;
//delayNanoseconds(30);
usb_prepare_transfer(&tx_transfer, txbuffer, MULTITOUCH_SIZE, 0);
arm_dcache_flush_delete(txbuffer, TX_BUFSIZE);
usb_transmit(MULTITOUCH_ENDPOINT, &tx_transfer);
scan_index++;
return; return;
} }
scan_index++; scan_index++;

Loading…
Cancel
Save