📄 usbn960x.c
字号:
#IF USB_EP11_RX_ENABLE==1
usb_enable_endpoint(11,0,0); //endpoint 11, OUT
#ELIF USB_EP11_RX_ENABLE==2
usb_enable_endpoint(11,0,1); //endpoint 11, OUT, ISO
#ENDIF
//configure IN ep12
#IF USB_EP12_TX_ENABLE==1
usb_enable_endpoint(12,1,0); //endpoint 12, IN
#ELIF USB_EP12_TX_ENABLE==2
usb_enable_endpoint(12,1,1); //endpoint 12, IN, ISO
#ENDIF
//configure OUT ep12
#IF USB_EP12_RX_ENABLE==1
usb_enable_endpoint(12,0,0); //endpoint 12, OUT
#ELIF USB_EP12_RX_ENABLE==2
usb_enable_endpoint(12,0,1); //endpoint 12, OUT, ISO
#ENDIF
//configure IN ep13
#IF USB_EP13_TX_ENABLE==1
usb_enable_endpoint(13,1,0); //endpoint 13, IN
#ELIF USB_EP13_TX_ENABLE==2
usb_enable_endpoint(13,1,1); //endpoint 13, IN, ISO
#ENDIF
//configure OUT ep13
#IF USB_EP13_RX_ENABLE==1
usb_enable_endpoint(13,0,0); //endpoint 13, OUT
#ELIF USB_EP13_RX_ENABLE==2
usb_enable_endpoint(13,0,1); //endpoint 13, OUT, ISO
#ENDIF
//configure IN ep14
#IF USB_EP14_TX_ENABLE==1
usb_enable_endpoint(14,1,0); //endpoint 14, IN
#ELIF USB_EP14_TX_ENABLE==2
usb_enable_endpoint(14,1,1); //endpoint 14, IN, ISO
#ENDIF
//configure OUT ep14
#IF USB_EP14_RX_ENABLE==1
usb_enable_endpoint(14,0,0); //endpoint 14, OUT
#ELIF USB_EP14_RX_ENABLE==2
usb_enable_endpoint(14,0,1); //endpoint 14, OUT, ISO
#ENDIF
//configure IN ep15
#IF USB_EP15_TX_ENABLE==1
usb_enable_endpoint(15,1,0); //endpoint 15, IN
#ELIF USB_EP15_TX_ENABLE==2
usb_enable_endpoint(15,1,1); //endpoint 15, IN, ISO
#ENDIF
//configure OUT ep15
#IF USB_EP15_RX_ENABLE==1
usb_enable_endpoint(15,0,0); //endpoint 15, OUT
#ELIF USB_EP15_RX_ENABLE==2
usb_enable_endpoint(15,0,1); //endpoint 15, OUT, ISO
#ENDIF
}
//TODO: handle other configurations. Not provided by CCS.
else {
//un-configure OUT ep1
#IF USB_EP1_RX_ENABLE
usb_disable_endpoint(1, 0); //endpoint 1, OUT
#ENDIF
//un-configure IN ep1
#IF USB_EP1_TX_ENABLE
usb_disable_endpoint(1, 1); //endpoint 1, IN
#ENDIF
//un-configure OUT ep2
#IF USB_EP2_RX_ENABLE
usb_disable_endpoint(2, 0); //endpoint 2, OUT
#ENDIF
//un-configure IN ep2
#IF USB_EP2_TX_ENABLE
usb_disable_endpoint(2, 1); //endpoint 2, IN
#ENDIF
//un-configure OUT ep3
#IF USB_EP3_RX_ENABLE
usb_disable_endpoint(3, 0); //endpoint 3, OUT
#ENDIF
//un-configure IN ep3
#IF USB_EP3_TX_ENABLE
usb_disable_endpoint(3, 1); //endpoint 3, IN
#ENDIF
//un-configure OUT ep4
#IF USB_EP4_RX_ENABLE
usb_disable_endpoint(4, 0); //endpoint 4, OUT
#ENDIF
//un-configure IN ep4
#IF USB_EP4_TX_ENABLE
usb_disable_endpoint(4, 1); //endpoint 4, IN
#ENDIF
//un-configure OUT ep5
#IF USB_EP5_RX_ENABLE
usb_disable_endpoint(5, 0); //endpoint 5, OUT
#ENDIF
//un-configure IN ep5
#IF USB_EP5_TX_ENABLE
usb_disable_endpoint(5, 1); //endpoint 5, IN
#ENDIF
//un-configure OUT ep6
#IF USB_EP6_RX_ENABLE
usb_disable_endpoint(6, 0); //endpoint 6, OUT
#ENDIF
//un-configure IN ep6
#IF USB_EP6_TX_ENABLE
usb_disable_endpoint(6, 1); //endpoint 6, IN
#ENDIF
//un-configure OUT ep7
#IF USB_EP7_RX_ENABLE
usb_disable_endpoint(7, 0); //endpoint 7, OUT
#ENDIF
//un-configure IN ep7
#IF USB_EP7_TX_ENABLE
usb_disable_endpoint(7, 1); //endpoint 7, IN
#ENDIF
//un-configure OUT ep8
#IF USB_EP8_RX_ENABLE
usb_disable_endpoint(8, 0); //endpoint 8, OUT
#ENDIF
//un-configure IN ep8
#IF USB_EP8_TX_ENABLE
usb_disable_endpoint(8, 1); //endpoint 8, IN
#ENDIF
//un-configure OUT ep9
#IF USB_EP9_RX_ENABLE
usb_disable_endpoint(9, 0); //endpoint 9, OUT
#ENDIF
//un-configure IN ep9
#IF USB_EP9_TX_ENABLE
usb_disable_endpoint(9, 1); //endpoint 9, IN
#ENDIF
//un-configure OUT ep10
#IF USB_EP10_RX_ENABLE
usb_disable_endpoint(10, 0); //endpoint 10, OUT
#ENDIF
//un-configure IN ep10
#IF USB_EP10_TX_ENABLE
usb_disable_endpoint(10, 1); //endpoint 10, IN
#ENDIF
//un-configure OUT ep11
#IF USB_EP11_RX_ENABLE
usb_disable_endpoint(11, 0); //endpoint 11, OUT
#ENDIF
//un-configure IN ep11
#IF USB_EP11_TX_ENABLE
usb_disable_endpoint(11, 1); //endpoint 11, IN
#ENDIF
//un-configure OUT ep12
#IF USB_EP12_RX_ENABLE
usb_disable_endpoint(12, 0); //endpoint 12, OUT
#ENDIF
//un-configure IN ep2
#IF USB_EP12_TX_ENABLE
usb_disable_endpoint(12, 1); //endpoint 12, IN
#ENDIF
//un-configure OUT ep13
#IF USB_EP13_RX_ENABLE
usb_disable_endpoint(13, 0); //endpoint 13, OUT
#ENDIF
//un-configure IN ep13
#IF USB_EP13_TX_ENABLE
usb_disable_endpoint(13, 1); //endpoint 13, IN
#ENDIF
//un-configure OUT ep14
#IF USB_EP14_RX_ENABLE
usb_disable_endpoint(14, 0); //endpoint 14, OUT
#ENDIF
//un-configure IN ep14
#IF USB_EP14_TX_ENABLE
usb_disable_endpoint(14, 1); //endpoint 14, IN
#ENDIF
//un-configure OUT ep15
#IF USB_EP15_RX_ENABLE
usb_disable_endpoint(15, 0); //endpoint 15, OUT
#ENDIF
//un-configure IN ep15
#IF USB_EP15_TX_ENABLE
usb_disable_endpoint(15, 1); //endpoint 15, IN
#ENDIF
}
}
/*******************************************************************************
/* usb_wrongstate()
/*
/* Summary: Tells the host that they asked us to do something (either illegal or something
/* we don't support) by stalling EP0. When the host gets the idea it will
/* either reset the device or un-stall EP0.
/*
/********************************************************************************/
#inline
void usb_wrongstate() {
usb_stall_ep(0,0);
}
/// END Hardware layer functions required by USB.C
/// BEGIN USB Interrupt Service Routine
/*******************************************************************************
/* usb_isr()
/*
/* Summary: Checks the Main Event interrupt register, and acts upon USB interrupts.
/* ALT interrupt happens for the misc interrupts (reset, idle, wakeup, etc.)
/* NAK interrupt happens when the USBN device generated a NAK to an IN or OUT/SETUP token
/* TX interrupt happens when an IN token has happend (PIC -> HOST)
/* RX interrupt happens when an OUT/SETUP token has happened. (HOST -> PIC).
/* Majority of USB token handling is done through the RX event.
/*
/* If you choose to use a polling method instead of by interrupt then call
/* this function on any free time. Use great care if you choose to poll:
/* some USB requests require a response within a few milli-seconds.
/*
/********************************************************************************/
#int_ext NOCLEAR
void usb_isr(void) {
int8 maev;
int_ext_flag=0; //clear interrupt flag
do {
maev=usbn_read(USBN_MAEV) & usbn_read(USBN_MAMSK);
if (maev) {
debug(debug_txb,"\r\nI %X: ",maev);
if (bit_test(maev,6)) {usb_check_rxev();} //OUT/SETUP tokens to us //0x40
if (bit_test(maev,2)) {usb_check_txev();} //IN token was processed (set up new data?) //0x04
if (bit_test(maev,1)) {usb_check_alt();} //Resets, Idles, Suspends, etc. //0x02
if (bit_test(maev,4)) {usb_check_nak();} //PC tried to send us data, but 960x nak'd it //0x10
if (bit_test(maev,0)) {usb_check_warn();} //TODO: CCS does not provide this function //0x01
if (bit_test(maev,3)) {usb_check_frame();} //TODO: CCS does not provide this function //0x08
if (bit_test(maev,5)) {usb_check_uld();} //TODO: CCS does not provide this function //0x20
}
} while (maev != 0);
}
/*******************************************************************************
/* usb_check_warn()
/*
/* Summary: The WARN event happens when a USBN buffer reaches a desired state.
/* This requires the user to setup the WARN setting for each buffer.
/* This capability not provided by CCS.
/*
/********************************************************************************/
void usb_check_warn(void) {
debug_txb('W');
//TODO: add code to handle when FIFOs get near full / empty
//This interrupt not used by CCS
}
/*******************************************************************************
/* usb_check_frame()
/*
/* Summary: Handles a FRAME event interrupt. CCS does not handle this interrupt.
/* Only relevant to users using isochronous.
/*
/********************************************************************************/
void usb_check_frame(void) {
debug_txb('F');
//TODO: not used by CCS
}
/*******************************************************************************
/* usb_check_uld()
/*
/* Summary: Handles ULD interrupt. Not provided by CCS.
/*
/********************************************************************************/
void usb_check_uld(void) {
debug_txb('U');
//TODO: not used by CCS
}
/*******************************************************************************
/* usb_check_alt()
/*
/* Summary: This interrupt happens when an RESET, SUSPEND or RESUME event has happened.
/* RESET - USBN device is reset, USB token handling code is put into initial state
/* SUSPEND - Resume interrupt is enabled, USBN device put into suspended mode
/* RESUME - Suspend interrupt is enabled, USBN device put into operational state, EP0 reception enabled
/*
/********************************************************************************/
void usb_check_alt(void) {
int8 status;
status=usbn_read(USBN_ALTEV) & usbn_current_alt_mask;
debug(debug_txb,"A %X",status);
if (bit_test(status,2)) {} // DMA. //Not used by CCS
else if (bit_test(status,6)) {usb_check_alt_reset();} // RESET
else if ((bit_test(status,5)) || (bit_test(status,4))) { // SD5 or SD3
usbn_current_alt_mask=(usbn_current_alt_mask & 0xCF) | 0x80; //make sure resume interrupt is on, sd3/sd5 is off
usbn_write(USBN_ALTMSK, usbn_current_alt_mask);
usbn_write(USBN_NFSR, USBN_NFSR_SUSPEND);
}
else if (bit_test(status,7)) { // RESUME
usbn_current_alt_mask=usbn_current_alt_mask & 0x7F; //TURN ON ALL EXCEPT RESUME
usbn_write(USBN_ALTMSK, usbn_current_alt_mask);
usbn_write(USBN_NFSR, USBN_NFSR_OPERATIONAL);
usbn_write(USBN_RXC0, usbn_read(USBN_RXC0) | 0x01); //enable reception
}
else if (bit_test(status,3)) {} // EOP //resume sequence has been acknowledged and completed by host
else if (bit_test(status,1)) {} // WKUP
}
/*******************************************************************************
/* usb_check_alt_reset()
/*
/* Summary: This Alt event happens when the Host sends a reset signal. We reset the USBN and
/* put the USB token handling code back into initial state.
/*
/********************************************************************************/
void usb_check_alt_reset(void) {
usbn_write(USBN_EPC0, usbn_read(USBN_EPC0) & ~0x80); //CLEAR_STALL_EP0
usbn_write(USBN_NFSR, USBN_NFSR_RESET);
usbn_write(USBN_FAR, 0x80); //set default address
usbn_write(USBN_EPC0, 0x00); //enable ep0 only
usb_reset();
usbn_write(USBN_NFSR, USBN_NFSR_OPERATIONAL);
usbn_write(USBN_FAR, 0x80); //default un-addressed address
usbn_write(USBN_EPC0, 0x40); //default address
usbn_write(USBN_RXC0, 0x01); //enable reception
}
/*******************************************************************************
/* usb_check_nak()
/*
/* Summary: Handles a NAK event. This interrupt happens when the USBN960x device
/* generates a NAK. We only handle the RX NAK, which happens when the Host
/* tried sending us an OUT/SETUP (host -> pic) packet, but either the buffer
/* is full or EP0 reception is disabled or EP0 is transmitting. In all cases
/* we flush and reset the EP0 buffer.
/*
/* CCS does not provide code to handle NAKs on the other endpoints.
/*
/********************************************************************************/
void usb_check_nak(void) {
int8 status;
status=usbn_read(USBN_NAKEV) & USBN_NAKMSK_ENABLES;
debug(debug_txb,"N %X ",status);
if (bit_test(status,0)) {} //TODO: not handled by CCS
if (bit_test(status,1)) {} //TODO: not handled by CCS
if (bit_test(status,2)) {} //TODO: not handled by CCS
if (bit_test(status,3)) {} //TODO: not handled by CCS
if (bit_test(status,4)) {
usbn_write(USBN_TXC0, 0x08); //flush TX FIFO, disable TX
usbn_write(USBN_RXC0, 0x08); //flush RX FIFO, disable TX
usbn_write(USBN_RXC0, 0x01); //flush RX FIFO, re-enable reception
USB_dev_req=NONE; //previous token request state. init at none
}
if (bit_test(status,5)) {} //TODO: not handled by CCS
if (bit_test(status,6)) {} //TODO: not handled by CCS
if (bit_test(status,7)) {} //TODO: not handled by CCS
}
/*******************************************************************************
/* usb_check_txev()
/*
/* Summary: The TX interrupt happens whenever an IN token has been processed. (PIC -> HOST).
/* Since the IN token has been processed that means the TX buffer is empty.
/* CCS only handles TX event when EP0 is empty, meaning it's time to send the next packet
/* of the message if there is one.
/*
/* CCS does not handle an interrupt on EPC1-EPC3 because we suggest polling, using
/* repetitive usb_put_packet() calls. usb_put_packet() will return true if data was put into buffer,
/* false if the buffer was not ready for data (because it was still putting out the last packet).
/*
/********************************************************************************/
void usb_check_txev(void) {
int8 status, txs;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -