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() ...@@ -76,6 +76,44 @@ void SystemInit()
#define IOPFEN (22U) //IO port F #define IOPFEN (22U) //IO port F
#define TSCEN (24U) //touch sensing controller #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) void HardFault_Handler(void)
{ {
...@@ -830,7 +868,8 @@ typedef struct usbRequest_t{ ...@@ -830,7 +868,8 @@ typedef struct usbRequest_t{
uint16_t wValue; uint16_t wValue;
uint16_t wIndex; uint16_t wIndex;
uint16_t wLength; uint16_t wLength;
}__attribute((__packed__))usbRequest_t; }usbRequest_t;
//}__attribute((__packed__))usbRequest_t;
// bmRequestType // bmRequestType
//D7 Data Phase Transfer Direction //D7 Data Phase Transfer Direction
...@@ -930,10 +969,12 @@ void control_xfr_in(){ ...@@ -930,10 +969,12 @@ void control_xfr_in(){
//setup EP0R for transmit //setup EP0R for transmit
//to keep from affecting any bits one must: //to keep from affecting any bits one must:
//RMW the r/w fields, write 0 to toggle fields, write 1 to ctr bits //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_EP0R_TX_VALID();
& USB_EPREG_MASK ) //mask out toggle feilds making them zero //#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 //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; return;
} }
...@@ -1006,10 +1047,12 @@ void control_xfr_init( usbRequest_t *spacket ) { ...@@ -1006,10 +1047,12 @@ void control_xfr_init( usbRequest_t *spacket ) {
//to keep from affecting any bits one must: //to keep from affecting any bits one must:
//RMW the r/w fields, write 0 to toggle fields, write 1 to ctr bits //RMW the r/w fields, write 0 to toggle fields, write 1 to ctr bits
//then set any bits we'd like to toggle //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_EP0R_RX_VALID();
& USB_EPREG_MASK ) //mask out toggle feilds making them zero //#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 //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 //Now we've got the pointer to return data initialized
//and number of bytes the firmware would like to return //and number of bytes the firmware would like to return
...@@ -1077,17 +1120,19 @@ void USB_IRQHandler(void) ...@@ -1077,17 +1120,19 @@ void USB_IRQHandler(void)
//check for OUT/SETUP //check for OUT/SETUP
if ( USB->EP0R & USB_EP_CTR_RX ) { if ( USB->EP0R & USB_EP_CTR_RX ) {
//clear RX interrupt log ++;
//to keep from affecting any bits one must: if ( log >2) {
//RMW the r/w fields, write 0 to toggle fields, write 1 to ctr bits DEBUG_HI(); DEBUG_LO();
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 //clear RX interrupt leave everything else unaffected
& ~USB_EP_CTR_RX ); //clear rx bit removing active interrupt 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 //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 //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 //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 if ( USB->EP0R & USB_EP_SETUP ) { //SETUP packet
//usb_buff[LOG0] = USB->EP0R; //usb_buff[LOG0] = USB->EP0R;
//set pointer to usb buffer, type ensures 8/16bit accesses to usb_buff //set pointer to usb buffer, type ensures 8/16bit accesses to usb_buff
...@@ -1099,21 +1144,23 @@ void USB_IRQHandler(void) ...@@ -1099,21 +1144,23 @@ void USB_IRQHandler(void)
control_xfr_out(); control_xfr_out();
} }
DEBUG_HI(); DEBUG_LO();
} else if ( USB->EP0R & USB_EP_CTR_TX ) { } else if ( USB->EP0R & USB_EP_CTR_TX ) {
log ++; //DEBUG_HI(); DEBUG_LO();
// log ++;
//IN packet //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; //Servicing of the CTR_TX event starts clearing the interrupt bit;
//usb_buff[LOG4] = USB->EP0R; //usb_buff[LOG4] = USB->EP0R;
//clear TX interrupt //clear TX interrupt
USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX) //set rx field to keep from accidentally clearing EP0R_CLR_CTR_TX();
& USB_EPREG_MASK ) //mask out toggle feilds making them zero //USB->EP0R = (((USB->EP0R | USB_EP_CTR_RX) //set rx field to keep from accidentally clearing
& ~USB_EP_CTR_TX ); //clear tx bit removing active interrupt // & USB_EPREG_MASK ) //mask out toggle feilds making them zero
// & ~USB_EP_CTR_TX ); //clear tx bit removing active interrupt
// LED_ON(); // LED_ON();
//usb_buff[LOG8] = USB->EP0R; //usb_buff[LOG8] = USB->EP0R;
...@@ -1133,14 +1180,13 @@ DEBUG_HI(); DEBUG_LO(); ...@@ -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 //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 ) { if ( USB->ISTR & USB_ISTR_RESET ) {
//Anytime a reset condition occurs, the EPnR registers are cleared //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 //Must re-enable the USB function and setup EP0 after any reset condition within 10msec
usb_reset_recovery(); usb_reset_recovery();
USB->ISTR &= ~USB_ISTR_RESET; //handled in reset recovery USB->ISTR &= ~USB_ISTR_RESET;
//DEBUG_HI(); DEBUG_LO(); //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