?? pp.c
字號:
/**************************************************** * pp.c * Copyright (C) 2002, Michael Hetherington * chinook@pacific.net.sg * * this file is based on * * sunkbd_hid.c * Copyright (C) 2001, Arnim Laeuger * arnim@users.sourceforge.net * * & * * uss720.c * Copyright (C) 1999, Thomas Sailer * sailer@ife.ee.ethz.ch * * History: * 0.01 16.6.2002 Created * ****************************************************/ #include <8051.h>#include <string.h>#include "ezusb_reg.h"#include "delay.h"#include "usb.h"#include "parport.h"/**************************************************** * get_request() ****************************************************/static void get_request (byte request, byte value, byte index) { switch(request){ case 0: in0buf[0] = parport_read_status(); IN0BC = 1; EP0CS = 0x02; break; case 1: parport_frob_control(index,value); /* direction */ if(index & 0x20){ if(value & 0x20) parport_data_reverse(); else parport_data_forward(); } in0buf[0] = parport_read_control(); IN0BC = 1; EP0CS = 0x02; break; case 2: in0buf[0] = reg_1284.done; IN0BC = 1; EP0CS = 0x02; break; case 3: in0buf[0] = parport_read_data(); IN0BC = 1; EP0CS = 0x02; break; default: EP0CS = 0x03; break; }}/**************************************************** * set_request() ****************************************************/static byte set_request (byte request, byte value, byte index) { switch(request){ /* mode */ case 2: reg_1284.mode = value; if (value & 0x80){ /* in */ reg_1284.main_state = 1; reg_1284.expected = index; /* unarm endpoint */ //IN2BC = 0; //IN2BC = 0; IN2CS |= 0x02; } else { /* out */ reg_1284.irq_state = 1; reg_1284.expected = index; /* unarm endpoint */ OUT1BC = 0; } EP0CS = 0x02; break; /* data set */ case 3: parport_write_data(value); EP0CS = 0x02; break; case 4: value &= PARPORT_STATUS_ERROR | PARPORT_STATUS_SELECT | PARPORT_STATUS_PAPEROUT| PARPORT_STATUS_ACK | PARPORT_STATUS_BUSY; reg_1284.mask_status = value; reg_1284.old_status = parport_read_status(); /* rearm interrupt endpoint */ if (value) { parport_enable_irq(); in4buf[0] = reg_1284.old_status; IN4BC = 1; } else { /* unarm endpoint */ parport_disable_irq(); IN4CS |=0x02; } EP0CS = 0x02; break; default: EP0CS = 0x03; break; }}/**************************************************** * get_descriptor() ****************************************************/static void get_descriptor(void) using 1 { switch (sdata -> wValueH){ case USB_DT_DEVICE: EP0CS = 0x02; /* clear HSNAK */ SUDPTRH = (byte)((unsigned int)dev_desc >> 8); SUDPTRL = (byte)((unsigned int)dev_desc & 0xFF); break; case USB_DT_CONFIG: EP0CS = 0x02; /* clear HSNAK */ SUDPTRH = (byte)((unsigned int)conf_desc >> 8); SUDPTRL = (byte)((unsigned int)conf_desc & 0xFF); break; case USB_DT_STRING: if (sdata -> wValueL < 2) { EP0CS = 0x02; SUDPTRH = (byte)(string_index[sdata->wValueL] >> 8); SUDPTRL = (byte)(string_index[sdata->wValueL] & 0xFF); } else { EP0CS = 0x03; } break; default: EP0CS = 0x03; /* stall */ break; }}/**************************************************** * get_status() ****************************************************/static void get_status (void) using 1 { switch (sdata->bmRequestType){ /* device status */ case 0x80: /* bus powered/no wakeup */ in0buf[0] = 0; in0buf[1] = 0; IN0BC = 0x02; EP0CS = 0x02; break; /* interface status */ case 0x81: if(sdata->wIndexL == 0){ in0buf[0] = 0; in0buf[1] = 0; IN0BC = 0x02; EP0CS = 0x02; } else EP0CS = 0x03; break; /* endpoint status */ case 0x82: switch (sdata->wIndexL){ /* endpoint 0 IN/OUT */ case 0x00: case 0x80: in0buf[0] = 0; in0buf[1] = 0; IN0BC = 0x02; EP0CS = 0x02; break; /* endpoint 1 OUT */ case 0x01: in0buf[0]=(OUT1CS & 0x01 ? 0x01:0x00); in0buf[1] = 0; IN0BC = 0x02; EP0CS = 0x02; break; /* endpoint 2 IN */ case 0x82: in0buf[0] = (IN2CS & 0x01 ? 0x01:0x00); in0buf[1] = 0; IN0BC = 0x02; EP0CS = 0x02; break; /* endpoint 3 IN */ case 0x84: in0buf[0] = (IN4CS & 0x01 ? 0x01:0x00); in0buf[1] = 0; IN0BC = 0x02; EP0CS = 0x02; break; /* stall */ default: EP0CS = 0x03; break; } break; /* stall */ default: EP0CS = 0x03; break; }}/**************************************************** * clear_feature() ****************************************************/static void clear_feature (void) using 1 { /* only clear endpoint feature is supported */ /* use usb_clear_halt to clear */ if(sdata->bmRequestType == 0x02 && sdata->wValueL == 0){ switch (sdata->wIndexL){ /* endpoint 1 OUT */ case 0x01: OUT1CS = 0x00; /* clear stall bit */ TOGCTL = 0x01; /* select endpoint 1 OUT */ TOGCTL = 0x21; /* toggle */ EP0CS = 0x02; /* clear HSNAK */ break; /* endpoint 2 IN */ case 0x82: IN2CS = 0x00; TOGCTL = 0x12; TOGCTL = 0x32; EP0CS = 0x02; break; /* endpoint 4 IN */ case 0x84: IN4CS = 0x00; TOGCTL = 0x14; TOGCTL = 0x34; EP0CS = 0x02; break; /* stall */ default: EP0CS = 0x03; break; } }else EP0CS = 0x03;}/**************************************************** * set_feature() ****************************************************/static void set_feature (void) using 1 { /* only set feature endpoint is supported */ if(sdata->bmRequestType == 0x02 && sdata->wValueL == 0){ switch (sdata->wIndexL){ /* endpoint 1 OUT */ case 0x01: OUT1CS = 0x01; /* set stall bit */ TOGCTL = 0x01; /* select endpoint 1 OUT */ TOGCTL = 0x21; /* toggle */ OUT1BC = 0x00; /* write any value into endpoint's BC register */ EP0CS = 0x02; /* clear HSNAK */ break; /* endpoint 2 IN */ case 0x82: IN2CS = 0x01; TOGCTL = 0x12; TOGCTL = 0x32; IN2CS |= 0x02; EP0CS = 0x02; break; /* endpoint 4 IN */ case 0x84: IN4CS = 0x01; TOGCTL = 0x14; TOGCTL = 0x34; IN4CS |= 0x02; EP0CS = 0x02; break; default: EP0CS = 0x03; break; } } else EP0CS = 0x03;}/**************************************************** * set_interface() ****************************************************/static void set_interface(void) using 1 { /* only one interface supported */ if(sdata->bmRequestType == 0x01 && sdata->wIndexL == 0x00){ switch(sdata->wValueL){ case 0x00: TOGCTL = 0x01; /* select endpoint 1 OUT */ TOGCTL = 0x21; /* toggle */ OUT1BC = 0x00; /* write any value */ TOGCTL = 0x12; /* select endpoint 2 IN */ TOGCTL = 0x32; /* toggle */ IN2CS |= 0x02; /* clear busy bit */ TOGCTL = 0x14; /* select endpoint 4 IN */ TOGCTL = 0x34; /* toggle */ IN4CS |= 0x02; /* clear busy bit */ EP0CS = 0x02; break; default: EP0CS = 0x03; break; } } else EP0CS = 0x03;}/**************************************************** * usb_isr() * ****************************************************/static void usb_isr (void) interrupt 8 using 1 { /* clear INT2 interrupt */ EXIF &= 0xEF; /* was this SUDAV interrupt */ if (USBIRQ & 0x01) { /* clear SUDAV interrupt */ USBIRQ = 0x01; /* vendor requests */ if((sdata->bmRequestType & 0x60) == 0x40){ /* get register */ if(sdata->bmRequestType == 0xC0) get_request(sdata->bRequest,sdata->wValueL, sdata->wIndexL); else { /* set register */ if(sdata->bmRequestType == 0x40){ set_request(sdata->bRequest,sdata->wValueL, sdata->wIndexL); } else EP0CS = 0x03; } } else /* standard requests */ if ((sdata->bmRequestType & 0x60) == 0){ switch (sdata->bRequest){ /* get status */ case 0x00: get_status(); break; /* clear feature */ case 0x01: clear_feature(); break; /* set feature */ case 0x03: set_feature(); break; /* get descriptor */ case 0x06: get_descriptor(); break; /* get configuration */ case 0x08: /* only one configuration is supported */ if (sdata->bmRequestType == 0x80 && sdata->wLengthL == 0x01){ in0buf[0] = 0x01; IN0BC = 0x01; EP0CS = 0x02; } else EP0CS = 0x03; break; /* set configuration */ case 0x09: /* only one configuration is supported */ EP0CS = ((sdata->bmRequestType == 0 && sdata->wValueL == 0x01) ? 0x02:0x03); break; /* get interface */ case 0x0A: /* only one interface */ if(sdata->bmRequestType == 0x81 && sdata->wIndexL == 0x00 && sdata->wLengthL == 0x01){ in0buf[0] = 0; IN0BC = 0x01; EP0CS = 0x02; } else EP0CS = 0x03; break; /* set interface */ case 0x0B: set_interface(); break; /* stall */ default: EP0CS = 0x03; break; } } else EP0CS = 0x03; } /* IN 0 interrupt ? */ if (IN07IRQ & 0x01) { IN07IRQ = 0x01; } /* OUT 0 interrupt ? */ if (OUT07IRQ & 0x01) { OUT07IRQ = 0x01; } /* OUT 1 interrupt */ if (OUT07IRQ & 0x02) { if(reg_1284.irq_state){ reg_1284.irq_state = 0; reg_1284.main_state = 1; } else OUT1BC = 0; OUT07IRQ = 0x02; } /* IN 2 interrupt */ if (IN07IRQ & 0x04) { IN07IRQ = 0x04; } /* IN 4 interrupt */ if (IN07IRQ & 0x10) { reg_1284.irq_status = 1; IN07IRQ = 0x10; } /* reset ? */ if (USBIRQ & 0x10){ USBIRQ = 0x10; }}/**************************************************** * _sdcc_external_startup() * ****************************************************/byte _sdcc_external_startup(){ USBCS &= ~0x04; USBCS |= 0x08; return (0);}/**************************************************** * setup_usb_int( * Setup the USB inetrrupts ****************************************************/static void setup_usb_int(void){ EA = 0; /* disable global interrupts */ USBBAV = 0; /* clear autovectoring and break reporting*/ USBIRQ = 0xFF; /* enable SUDAV interrupt and all other interrupts */ USBIEN = 0x11; /* enable SUDAV interrupt and RESET interrupt */ IN07IRQ = 0xFF; /* clear all interrupts */ IN07IEN = 0x15; /* enable IN0 IN2 IN4 interrupt */ OUT07IRQ = 0xFF; /* clear all interrupts */ OUT07IEN = 0x03; /* enable OUT0 OUT1 interrupt */ OUT1CS = 0x00; /* unstall endpoint OUT 1 */ IN2CS = 0x00; /* unstall endpoint IN 2 */ IN4CS = 0x00; /* unstall endpoint IN 4 */ IN07VAL = 0x15; /* endpoint IN 0 IN2 IN4 */ OUT07VAL = 0x03; /* endpoint OUT 0 OUT 1 */ EUSB = 1; /* enable USB interrupt */ EA = 1; /* enable global interrupts */}/**************************************************** * setup uss () * apply default setting ****************************************************/static void setup_uss(void){ /* disable USB interrupts */ EUSB = 0; /* data */ PORTACFG = 0; OEA = 0xFF; OUTA = 0; /* status */ PORTBCFG = 0; OEB = 0x07; OUTB = 0x06; reg_1284.status = 0; /* control */ PORTCCFG = 0; OEC = 0xF8; OUTC = 0xF8; reg_1284.ctr = 0xFC; reg_1284.irq_state = 0; reg_1284.main_state = 0; reg_1284.irq_status = 0; /* timer 0 */ /* mode 1 */ TMOD |= 0x01; TMOD &=~0x02; /* timer 0 select */ TMOD &=~0x04; /* enable timer */ TCON |= 0x10; TL0 = 0; TH0 = 0; EUSB = 1;}/**************************************************** * main () * Basic initialization, re-enumeration and the reset ****************************************************/int main (void){ unsigned int time = 10; unsigned int loop = 5000; while (loop--); setup_usb_int(); setup_uss(); USBCS |= 0x02; USBCS &= ~0x08; USBCS |= 0x04; while (1){ /* IEEE1284 transfers */ if(reg_1284.main_state){ EUSB = 0; switch (reg_1284.mode){ /* compatability */ case 0x01: reg_1284.done = parport_write_compat(out1buf,OUT1BC); OUT1BC = 0; break; /* nibble */ case 0x81: reg_1284.done = parport_read_nibble(in2buf, reg_1284.expected); IN2BC = reg_1284.done; break; /* epp read data */ case 0x83: reg_1284.done = parport_epp_read_data(in2buf, reg_1284.expected); IN2BC = reg_1284.done; break; /* epp write data */ case 0x03: reg_1284.done = parport_epp_write_data(out1buf, OUT1BC); OUT1BC = 0; break; /* epp read address */ case 0x84: reg_1284.done = parport_epp_read_addr(in2buf, reg_1284.expected); IN2BC = reg_1284.done; break; /* epp write address */ case 0x04: reg_1284.done = parport_epp_write_addr(out1buf, OUT1BC); OUT1BC = 0; break; default: reg_1284.done = 0; break; } reg_1284.main_state = 0; EUSB = 1; } if (reg_1284.irq_status){ byte sts; EUSB = 0; sts = parport_read_status(); reg_1284.status &= reg_1284.mask_status; reg_1284.old_status &= reg_1284.mask_status; if(reg_1284.status ^ reg_1284.old_status){ in4buf[0] = sts; IN4BC = 1; reg_1284.irq_status = 0; } reg_1284.old_status = sts; EUSB = 1; } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -