Commit 98d61bc0 by Paul Molloy

Successfully completed very first SETUP transaction for initial device

descriptor request.  Reached second transaction which is set address.
Need to add support for set address to move forward.

Added some fancy macros for handling the uber annoying EP0R register
Would like to make some even fancier macros that work for all EPnR
registers taking the number as an arguement for the macro.

Might be good to start cleaning up the code a bit before getting too much
further.  Really feel like things are getting messy... Maybe don't need so
many copy pastes from the reference manual..?
parent da3c3a73
......@@ -76,6 +76,44 @@ void SystemInit()
#define IOPFEN (22U) //IO port F
#define TSCEN (24U) //touch sensing controller
//clear RX interrupt
//set tx field to keep from accidentally clearing //mask out toggle feilds making them zero //clear rx bit removing active interrupt
#define EP0R_CLR_CTR_RX() USB->EP0R = (((USB->EP0R | USB_EP_CTR_TX) & USB_EPREG_MASK ) & ~USB_EP_CTR_RX )
//clear TX interrupt
#define EP0R_CLR_CTR_TX() USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX) & USB_EPREG_MASK ) & ~USB_EP_CTR_TX )
//VALID need to get both status bits set
//XOR the current value of status bits with 1 to write back inverted value, gets all status bits set
// OR in bits that need set, AND in bits to keep or avail for XOR, XOR toggles to invert
#define USB_EP0R_RXTX_VALID() USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX)) ^ (USB_EPTX_STAT | USB_EPRX_STAT))
#define USB_EP0R_RX_VALID() USB->EP0R = ((((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX)) & (USB_EPREG_MASK | USB_EPRX_STAT)) ^ USB_EPRX_STAT )
#define USB_EP0R_TX_VALID() USB->EP0R = ((((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX)) & (USB_EPREG_MASK | USB_EPTX_STAT)) ^ USB_EPTX_STAT )
//DISABLE need to get both bits cleared
//write back current value of status bits to toggle all 1's to zeros
// OR in bits that need set AND in bits to keep or toggle from 1 to 0
#define USB_EP0R_RXTX_DIS() USB->EP0R = ((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX))
#define USB_EP0R_RX_DIS() USB->EP0R = ((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & (USB_EPREG_MASK | USB_EPRX_STAT))
#define USB_EP0R_TX_DIS() USB->EP0R = ((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & (USB_EPREG_MASK | USB_EPTX_STAT))
//NAK/STALL need to get one bit set, and the other cleared
//Easiest way would be to DISABLE, and then set desired bit, uses two accesses to EP0R
// DISABLE first OR in bits that need set AND in bits to keep or toggle
#define USB_EP0R_RX_NAK() USB_EP0R_RX_DIS(); USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & (USB_EPREG_MASK)) | USB_EP_RX_NAK)
#define USB_EP0R_TX_NAK() USB_EP0R_TX_DIS(); USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & (USB_EPREG_MASK)) | USB_EP_TX_NAK)
#define USB_EP0R_RXTX_NAK() USB_EP0R_RXTX_DIS(); USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & (USB_EPREG_MASK)) | (USB_EP_RX_NAK | USB_EP_TX_NAK))
#define USB_EP0R_RX_STALL() USB_EP0R_RX_DIS(); USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & (USB_EPREG_MASK)) | USB_EP_RX_STALL)
#define USB_EP0R_TX_STALL() USB_EP0R_TX_DIS(); USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & (USB_EPREG_MASK)) | USB_EP_TX_STALL)
#define USB_EP0R_RXTX_STALL() USB_EP0R_RXTX_DIS(); USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) & (USB_EPREG_MASK)) | (USB_EP_RX_STALL | USB_EP_TX_STALL))
//set bit(s) that would like to toggle
//set rx/tx field to keep from accidentally clearing
//mask out toggle feilds making them zero
//TODO fix assumption that we only need to go from TX_NAK to TX_VALID
void HardFault_Handler(void)
{
......@@ -830,7 +868,8 @@ typedef struct usbRequest_t{
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
}__attribute((__packed__))usbRequest_t;
}usbRequest_t;
//}__attribute((__packed__))usbRequest_t;
// bmRequestType
//D7 Data Phase Transfer Direction
......@@ -930,10 +969,12 @@ void control_xfr_in(){
//setup EP0R for transmit
//to keep from affecting any bits one must:
//RMW the r/w fields, write 0 to toggle fields, write 1 to ctr bits
USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) //set rx/tx field to keep from accidentally clearing
& USB_EPREG_MASK ) //mask out toggle feilds making them zero
USB_EP0R_TX_VALID();
//#define USB_EP0R_TX_VALID() USB->EP0R = ((((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX)) & (USB_EPREG_MASK | USB_EPTX_STAT)) ^ USB_EPTX_STAT )
// USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) //set rx/tx field to keep from accidentally clearing
// & USB_EPREG_MASK ) //mask out toggle feilds making them zero
//TODO fix assumption that we only need to go from TX_NAK to TX_VALID
| USB_EP_TX_NAK_TO_VALID ); //set bit that would like to toggle
// | USB_EP_TX_NAK_TO_VALID ); //set bit that would like to toggle
return;
}
......@@ -1006,10 +1047,12 @@ void control_xfr_init( usbRequest_t *spacket ) {
//to keep from affecting any bits one must:
//RMW the r/w fields, write 0 to toggle fields, write 1 to ctr bits
//then set any bits we'd like to toggle
USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) //set rx/tx field to keep from accidentally clearing
& USB_EPREG_MASK ) //mask out toggle feilds making them zero
USB_EP0R_RX_VALID();
//#define USB_EP0R_RX_VALID() USB->EP0R = ((((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX)) & (USB_EPREG_MASK | USB_EPRX_STAT)) ^ USB_EPRX_STAT )
// USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX | USB_EP_CTR_TX) //set rx/tx field to keep from accidentally clearing
// & USB_EPREG_MASK ) //mask out toggle feilds making them zero
//TODO fix assumption that we only need to go from TX_NAK to TX_VALID
| USB_EP_RX_NAK_TO_STALL ); //set bit(s) that would like to toggle
// | USB_EP_RX_NAK_TO_STALL ); //set bit(s) that would like to toggle
//Now we've got the pointer to return data initialized
//and number of bytes the firmware would like to return
......@@ -1077,17 +1120,19 @@ void USB_IRQHandler(void)
//check for OUT/SETUP
if ( USB->EP0R & USB_EP_CTR_RX ) {
//clear RX interrupt
//to keep from affecting any bits one must:
//RMW the r/w fields, write 0 to toggle fields, write 1 to ctr bits
USB->EP0R = (((USB->EP0R | USB_EP_CTR_TX) //set tx field to keep from accidentally clearing
& USB_EPREG_MASK ) //mask out toggle feilds making them zero
& ~USB_EP_CTR_RX ); //clear rx bit removing active interrupt
log ++;
if ( log >2) {
DEBUG_HI(); DEBUG_LO();
}
//clear RX interrupt leave everything else unaffected
EP0R_CLR_CTR_RX();
// USB->EP0R = (((USB->EP0R | USB_EP_CTR_TX) //set tx field to keep from accidentally clearing
// & USB_EPREG_MASK ) //mask out toggle feilds making them zero
// & ~USB_EP_CTR_RX ); //clear rx bit removing active interrupt
//Note: clearing CTR_RX on a control EP, is enough for another setup packet to be accepted
//this is true even if STAT_RX is STALL/NAK, so if the data needs retained it must be copied
//elsewhere, or set STAT_RX to DISABLED to keep it from being stomped by the next setup
//log = 0;
if ( USB->EP0R & USB_EP_SETUP ) { //SETUP packet
//usb_buff[LOG0] = USB->EP0R;
//set pointer to usb buffer, type ensures 8/16bit accesses to usb_buff
......@@ -1099,21 +1144,23 @@ void USB_IRQHandler(void)
control_xfr_out();
}
DEBUG_HI(); DEBUG_LO();
} else if ( USB->EP0R & USB_EP_CTR_TX ) {
log ++;
//DEBUG_HI(); DEBUG_LO();
// log ++;
//IN packet
// if (log >= 1) {
// LED_ON();
// }
//LED_ON();
// if (log >= 2) {
// LED_ON();
// }
//Servicing of the CTR_TX event starts clearing the interrupt bit;
//usb_buff[LOG4] = USB->EP0R;
//clear TX interrupt
USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX) //set rx field to keep from accidentally clearing
& USB_EPREG_MASK ) //mask out toggle feilds making them zero
& ~USB_EP_CTR_TX ); //clear tx bit removing active interrupt
EP0R_CLR_CTR_TX();
//USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX) //set rx field to keep from accidentally clearing
// & USB_EPREG_MASK ) //mask out toggle feilds making them zero
// & ~USB_EP_CTR_TX ); //clear tx bit removing active interrupt
// LED_ON();
//usb_buff[LOG8] = USB->EP0R;
......@@ -1133,14 +1180,13 @@ DEBUG_HI(); DEBUG_LO();
//I wasn't doing things in this order thinking that explains why I can't get a second transfer out
DEBUG_HI(); DEBUG_LO();
}
if ( USB->ISTR & USB_ISTR_RESET ) {
//Anytime a reset condition occurs, the EPnR registers are cleared
//Must re-enable the USB function and setup EP0 after any reset condition within 10msec
usb_reset_recovery();
USB->ISTR &= ~USB_ISTR_RESET;
//handled in reset recovery USB->ISTR &= ~USB_ISTR_RESET;
//DEBUG_HI(); DEBUG_LO();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment