diff options
Diffstat (limited to 'libmaple')
-rw-r--r-- | libmaple/timers.h | 224 | ||||
-rw-r--r-- | libmaple/usb/usb_callbacks.c | 468 |
2 files changed, 440 insertions, 252 deletions
diff --git a/libmaple/timers.h b/libmaple/timers.h index 1d929db..7589283 100644 --- a/libmaple/timers.h +++ b/libmaple/timers.h @@ -144,7 +144,7 @@ typedef enum TimerMode { TIMER_PWM, /**< This is the default mode for pins after initialization. */ TIMER_OUTPUTCOMPARE, /**< In this mode, the timer counts from 0 to - the overflow value repeatedly; every time + its reload value repeatedly; every time the counter value reaches one of the channel compare values, the corresponding interrupt is fired. */ @@ -225,51 +225,239 @@ struct timer_dev { extern struct timer_dev timer_dev_table[]; -/* Turn on timer with prescale as the divisor - * void timer_init(uint32 timer, uint16 prescale) - * timer -> {1-4} - * prescale -> {1-65535} +/** + * Initializes timer with prescale as the clock divisor. + * + * @param timer Timer number. Valid values are TIMER1, TIMER2, + * TIMER3, TIMER4, and (on high-density devices) TIMER5, TIMER8. + * + * @param prescale value in the range 1--65535 to use as a prescaler + * for timer counter increment frequency. + * + * @see timer_set_prescaler() + * @see timer_set_mode() */ void timer_init(timer_dev_num, uint16); + +/** + * Quickly disable all timers. Calling this function is faster than, + * e.g., calling timer_set_mode() for all available timers/channels. + */ void timer_disable_all(void); +/** + * Returns the timer's counter value. Due to function call overhead, + * this value is likely to be inaccurate if the counter is running + * with a low prescaler. + * + * @param timer the timer whose counter to return. + * + * @pre Timer has been initialized. + */ uint16 timer_get_count(timer_dev_num); + +/** + * Sets the counter value for the given timer. + * + * @param timer the timer whose counter to set. + * + * @param value the new counter value. + * + * @pre Timer has been initialized. + */ void timer_set_count(timer_dev_num,uint16); +/** + * Stops the timer's counter from incrementing. Does not modify the + * timer's mode or settings. + * + * @param timer the timer to pause. + * + * @see timer_resume() + * + * @pre Timer has been initialized. + */ void timer_pause(timer_dev_num); + +/** + * Starts the counter for the given timer. Does not modify the + * timer's mode or settings. The timer will begin counting on the + * first rising clock cycle after it has been re-enabled using this + * function. + * + * @param timer the timer to resume. + * + * @see timer_pause() + * + * @pre Timer has been initialized. + */ void timer_resume(timer_dev_num); +/** + * Returns the prescaler for the given timer. + * + * @see timer_set_prescaler() + * + * @pre Timer has been initialized. + */ uint16 timer_get_prescaler(timer_dev_num timer_num); + +/** + * Sets the prescaler for the given timer. This value goes into the + * PSC register, so it's 0-based (i.e., a prescale of 0 counts 1 tick + * per clock cycle). This prescale does not take effect until the + * next update event. + * + * @param timer the timer whose prescaler to set. + * + * @param prescale the new prescaler. + * + * @pre Timer has been initialized. + */ void timer_set_prescaler(timer_dev_num timer_num, uint16 prescale); +/** + * Gets the reload value for the timer. + * + * @see timer_set_reload() + * + * @pre Timer has been initialized. + */ uint16 timer_get_reload(timer_dev_num timer_num); + +/** + * Sets the reload value for the timer. + * + * After this function returns, the timer's counter will reset to 0 + * after it has reached the value max_reload. + * + * @param timer the timer whose reload to set. + * + * @param max_reload the new reload value. + * + * @pre Timer has been initialized. + */ void timer_set_reload(timer_dev_num timer_num, uint16 max_reload); /* TODO: timer_get_mode */ + +/** + * Set the mode of an individual timer channel. + * + * @param timer the timer whose channel mode to set. + * + * @param channel the channel whose mode to set (1 <= channel <= 4). + * + * @param mode the new mode value. Currently acceptable values + * include TIMER_DISABLED, TIMER_PWM, and TIMER_OUTPUTCOMPARE. Note + * that timer_disable_all() will disable all timers and all channels + * much more quickly than repeated calls to this function with mode + * TIMER_DISABLED. + * + * @see TimerMode + * + * @see timer_disable_all() + * + * @pre Timer has been initialized. + */ void timer_set_mode(timer_dev_num timer_num, uint8 channel_num, uint8 mode); +/** + * Get the compare value for the given timer channel. + * @see timer_set_compare_value() + * + * @pre Timer has been initialized. + */ uint16 timer_get_compare_value(timer_dev_num timer_num, uint8 channel_num); -void timer_set_compare_value(timer_dev_num timer_num, uint8 channel_num, uint16 value); +/** + * Sets the compare value for a given timer channel. Useful for + * scheduling when interrupt handlers will be called. + * + * @param timer the timer whose channel compare to set. + * + * @param channel the channel whose compare to set (1 <= channel <= 4). + * + * @param compare the new compare value. This new value must be less + * than or equal to the timer's reload value. + * + * @see timer_attach_interrupt() + * + * @see timer_detach_interrupt() + * + * @see timer_set_reload() + * + * @pre Timer has been initialized. + */ +void timer_set_compare_value(timer_dev_num timer_num, uint8 channel_num, + uint16 value); + +/** + * Detach the interrupt handler for the given timer channel, if any. + * After this function returns, any handler attached to the given + * channel will no longer be called. + * + * @param timer the timer whose channel to detach the interrupt + * handler from. + * + * @param channel the channel from which to detach the interrupt handler. + * + * @see timer_attach_interrupt() + * + * @pre Timer has been initialized. + */ +void timer_detach_interrupt(timer_dev_num timer_num, uint8 channel_num); + +/** + * Attach an interrupt handler for the given timer and channel. The + * handler will be called whenever the timer's counter reaches the + * compare value for the given timer and channel. + * + * @param timer the timer whose channel to register with an interrupt handler. + * + * @param channel the channel with which the new handler will be + * associated. timer_set_compare_value() can be used to set the value + * which the timer's counter must reach before handler is called (1 <= + * channel <= 4). + * + * @param handler the interrupt handler to call once the timer reaches + * the given channel's compare value. + * + * @pre The channel's mode must be set to TIMER_OUTPUTCOMPARE, or the + * interrupt handler will not get called. + * + * @see timer_set_compare_value() + * + * @see timer_detach_interrupt() + * + * @see timer_set_mode() + * + * @pre Timer has been initialized. + */ void timer_attach_interrupt(timer_dev_num timer_num, uint8 channel_num, voidFuncPtr handler); -void timer_detach_interrupt(timer_dev_num timer_num, uint8 channel_num); -/* generate UEV */ +/** + * Programmatically generate an update event on the given timer. This + * updates the prescaler, reloads the compare value (in upcounting + * mode, etc.). + * + * @pre Timer has been initialized. + */ void timer_generate_update(timer_dev_num timer_num); -/* Turn on PWM with duty_cycle on the specified channel in timer. - * This function takes in a pointer to the corresponding CCR - * register for the pin cause it saves pwmWrite() a couple of - * cycles. +/** + * Turn on PWM with duty_cycle. + * + * @param channel TIMERx_CHn_CCR, where x goes from 1 to NR_TIMERS, + * and n goes from 1 to 4. + * + * @param duty_cycle 0--65535. duty_cycle=0 means always off; + * duty_cycle=65535 means always on. * - * void timer_pwm(uint8 channel, uint8 duty_cycle); - * channel -> {TIMERx_CHn_CCR} - * duty_cycle -> {0-65535} + * @pre Pin has been set to alternate function output. * - * PRECONDITIONS: - * pin has been set to alternate function output - * timer has been initialized + * @pre Timer has been initialized. */ static inline void timer_pwm_write_ccr(TimerCCR CCR, uint16 duty_cycle) { *CCR = duty_cycle; diff --git a/libmaple/usb/usb_callbacks.c b/libmaple/usb/usb_callbacks.c index 4cdaf73..250acea 100644 --- a/libmaple/usb/usb_callbacks.c +++ b/libmaple/usb/usb_callbacks.c @@ -8,19 +8,19 @@ #include "usb_hardware.h" ONE_DESCRIPTOR Device_Descriptor = { - (uint8*)&usbVcomDescriptor_Device, - sizeof(USB_Descriptor_Device) + (uint8*)&usbVcomDescriptor_Device, + sizeof(USB_Descriptor_Device) }; ONE_DESCRIPTOR Config_Descriptor = { - (uint8*)&usbVcomDescriptor_Config, - 0x43//sizeof(USB_Descriptor_Config) + (uint8*)&usbVcomDescriptor_Config, + 0x43//sizeof(USB_Descriptor_Config) }; ONE_DESCRIPTOR String_Descriptor[3] = { - {(uint8*)&usbVcomDescriptor_LangID, USB_DESCRIPTOR_STRING_LEN(1)}, - {(uint8*)&usbVcomDescriptor_iManufacturer,USB_DESCRIPTOR_STRING_LEN(8)}, - {(uint8*)&usbVcomDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(8)} + {(uint8*)&usbVcomDescriptor_LangID, USB_DESCRIPTOR_STRING_LEN(1)}, + {(uint8*)&usbVcomDescriptor_iManufacturer,USB_DESCRIPTOR_STRING_LEN(8)}, + {(uint8*)&usbVcomDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(8)} }; uint8 last_request = 0; @@ -42,12 +42,12 @@ RESET_STATE reset_state = DTR_UNSET; uint8 line_dtr_rts = 0; void vcomDataTxCb(void) { - /* do whatever after data has been sent to host */ + /* do whatever after data has been sent to host */ - /* allows usbSendBytes to stop blocking */ + /* allows usbSendBytes to stop blocking */ - countTx = 0; + countTx = 0; } /* we could get arbitrarily complicated here for speed purposes @@ -56,296 +56,296 @@ void vcomDataTxCb(void) { in the fifo. this number will be reincremented after calls to usbReceiveBytes */ void vcomDataRxCb(void) { - /* do whatever after data has been received from host */ - - /* setEPRxCount on the previous cycle should garuntee - we havnt received more bytes than we can fit */ - uint8 newBytes = GetEPRxCount(VCOM_RX_ENDP); - /* assert (newBytes <= maxNewBytes); */ - - /* todo, not checking very carefully for edge cases. USUALLY, - if we emit the reset pulse and send 4 bytes, then newBytes - should be 4. But its POSSIBLE that this would be violated - in some cases */ - - /* magic number, {0x31, 0x45, 0x41, 0x46} is "1EAF" */ - char chkBuf[4]; - char cmpBuf[4] = {0x31, 0x45, 0x41, 0x46}; - if (reset_state == DTR_NEGEDGE) { - reset_state = DTR_LOW; - - if (newBytes >= 4) { - unsigned int target = (unsigned int)usbWaitReset | 0x1; - - PMAToUserBufferCopy(chkBuf,VCOM_RX_ADDR,4); - - int i; - USB_Bool cmpMatch = TRUE; - for (i=0; i<4; i++) { - if (chkBuf[i] != cmpBuf[i]) { - cmpMatch = FALSE; - } - } - - if (cmpMatch) { - asm volatile("mov r0, %[stack_top] \n\t" // Reset the stack - "mov sp, r0 \n\t" - "mov r0, #1 \n\t" - "mov r1, %[target_addr] \n\t" - "mov r2, %[cpsr] \n\t" - "push {r2} \n\t" // Fake xPSR - "push {r1} \n\t" // Target address for PC - "push {r0} \n\t" // Fake LR - "push {r0} \n\t" // Fake R12 - "push {r0} \n\t" // Fake R3 - "push {r0} \n\t" // Fake R2 - "push {r0} \n\t" // Fake R1 - "push {r0} \n\t" // Fake R0 - "mov lr, %[exc_return] \n\t" - "bx lr" - : - : [stack_top] "r" (STACK_TOP), - [target_addr] "r" (target), - [exc_return] "r" (EXC_RETURN), - [cpsr] "r" (DEFAULT_CPSR) - : "r0", "r1", "r2"); - /* should never get here */ - } + /* do whatever after data has been received from host */ + + /* setEPRxCount on the previous cycle should garuntee + we havnt received more bytes than we can fit */ + uint8 newBytes = GetEPRxCount(VCOM_RX_ENDP); + /* assert (newBytes <= maxNewBytes); */ + + /* todo, not checking very carefully for edge cases. USUALLY, + if we emit the reset pulse and send 4 bytes, then newBytes + should be 4. But its POSSIBLE that this would be violated + in some cases */ + + /* magic number, {0x31, 0x45, 0x41, 0x46} is "1EAF" */ + char chkBuf[4]; + char cmpBuf[4] = {0x31, 0x45, 0x41, 0x46}; + if (reset_state == DTR_NEGEDGE) { + reset_state = DTR_LOW; + + if (newBytes >= 4) { + unsigned int target = (unsigned int)usbWaitReset | 0x1; + + PMAToUserBufferCopy(chkBuf,VCOM_RX_ADDR,4); + + int i; + USB_Bool cmpMatch = TRUE; + for (i=0; i<4; i++) { + if (chkBuf[i] != cmpBuf[i]) { + cmpMatch = FALSE; + } + } + + if (cmpMatch) { + asm volatile("mov r0, %[stack_top] \n\t" // Reset the stack + "mov sp, r0 \n\t" + "mov r0, #1 \n\t" + "mov r1, %[target_addr] \n\t" + "mov r2, %[cpsr] \n\t" + "push {r2} \n\t" // Fake xPSR + "push {r1} \n\t" // Target address for PC + "push {r0} \n\t" // Fake LR + "push {r0} \n\t" // Fake R12 + "push {r0} \n\t" // Fake R3 + "push {r0} \n\t" // Fake R2 + "push {r0} \n\t" // Fake R1 + "push {r0} \n\t" // Fake R0 + "mov lr, %[exc_return] \n\t" + "bx lr" + : + : [stack_top] "r" (STACK_TOP), + [target_addr] "r" (target), + [exc_return] "r" (EXC_RETURN), + [cpsr] "r" (DEFAULT_CPSR) + : "r0", "r1", "r2"); + /* should never get here */ + } + } } - } - if (recvBufIn + newBytes < VCOM_RX_EPSIZE) { - PMAToUserBufferCopy(&vcomBufferRx[recvBufIn],VCOM_RX_ADDR,newBytes); - recvBufIn += newBytes; - } else { - /* we have to copy the data in two chunks because we roll over - the edge of the circular buffer */ - uint8 tailBytes = VCOM_RX_EPSIZE - recvBufIn; - uint8 remaining = newBytes - tailBytes; + if (recvBufIn + newBytes < VCOM_RX_EPSIZE) { + PMAToUserBufferCopy(&vcomBufferRx[recvBufIn],VCOM_RX_ADDR,newBytes); + recvBufIn += newBytes; + } else { + /* we have to copy the data in two chunks because we roll over + the edge of the circular buffer */ + uint8 tailBytes = VCOM_RX_EPSIZE - recvBufIn; + uint8 remaining = newBytes - tailBytes; - PMAToUserBufferCopy(&vcomBufferRx[recvBufIn],VCOM_RX_ADDR,tailBytes); - PMAToUserBufferCopy(&vcomBufferRx[0], VCOM_RX_ADDR,remaining); + PMAToUserBufferCopy(&vcomBufferRx[recvBufIn],VCOM_RX_ADDR,tailBytes); + PMAToUserBufferCopy(&vcomBufferRx[0], VCOM_RX_ADDR,remaining); - recvBufIn = (recvBufIn + newBytes ) % VCOM_RX_EPSIZE; - } + recvBufIn = (recvBufIn + newBytes ) % VCOM_RX_EPSIZE; + } - maxNewBytes -= newBytes; - SetEPRxCount(VCOM_RX_ENDP,maxNewBytes); - SetEPRxValid(VCOM_RX_ENDP); + maxNewBytes -= newBytes; + SetEPRxCount(VCOM_RX_ENDP,maxNewBytes); + SetEPRxValid(VCOM_RX_ENDP); } void vcomManagementCb(void) { -/* unused. This enpoint would callback if we had sent a linestate - changed notification */ + /* unused. This enpoint would callback if we had sent a linestate + changed notification */ } u8* vcomGetSetLineCoding(uint16 length) { - if (length == 0) { - pInformation->Ctrl_Info.Usb_wLength = sizeof(USB_Line_Coding); - } - return (uint8*)&line_coding; + if (length == 0) { + pInformation->Ctrl_Info.Usb_wLength = sizeof(USB_Line_Coding); + } + return (uint8*)&line_coding; } vcomSetLineState(void) { } void usbInit(void) { - pInformation->Current_Configuration = 0; - usbPowerOn(); + pInformation->Current_Configuration = 0; + usbPowerOn(); - _SetISTR(0); - wInterrupt_Mask = ISR_MSK; - _SetCNTR(wInterrupt_Mask); + _SetISTR(0); + wInterrupt_Mask = ISR_MSK; + _SetCNTR(wInterrupt_Mask); - usbEnbISR(); - bDeviceState = UNCONNECTED; + usbEnbISR(); + bDeviceState = UNCONNECTED; } void usbReset(void) { - pInformation->Current_Configuration = 0; + pInformation->Current_Configuration = 0; - /* current feature is current bmAttributes */ - pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELF_POWERED); + /* current feature is current bmAttributes */ + pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELF_POWERED); - _SetBTABLE(USB_BTABLE_ADDRESS); + _SetBTABLE(USB_BTABLE_ADDRESS); - /* setup control endpoint 0 */ - _SetEPType(ENDP0, EP_CONTROL); - _SetEPTxStatus(ENDP0, EP_TX_STALL); - _SetEPRxAddr(ENDP0,VCOM_CTRL_RX_ADDR); - _SetEPTxAddr(ENDP0,VCOM_CTRL_TX_ADDR); - Clear_Status_Out(ENDP0); + /* setup control endpoint 0 */ + _SetEPType(ENDP0, EP_CONTROL); + _SetEPTxStatus(ENDP0, EP_TX_STALL); + _SetEPRxAddr(ENDP0,VCOM_CTRL_RX_ADDR); + _SetEPTxAddr(ENDP0,VCOM_CTRL_TX_ADDR); + Clear_Status_Out(ENDP0); - SetEPRxCount(ENDP0, pProperty->MaxPacketSize); - SetEPRxValid(ENDP0); - - /* setup management endpoint 1 */ - SetEPType (VCOM_NOTIFICATION_ENDP, EP_INTERRUPT); - SetEPTxAddr (VCOM_NOTIFICATION_ENDP, VCOM_NOTIFICATION_ADDR); - SetEPTxStatus (VCOM_NOTIFICATION_ENDP, EP_TX_NAK); - SetEPRxStatus (VCOM_NOTIFICATION_ENDP, EP_RX_DIS); - - /* setup data endpoint OUT (rx) */ -/* SetEPType (VCOM_RX_ENDP, EP_BULK); */ -/* SetEPRxAddr (VCOM_RX_ENDP, VCOM_RX_ADDR); */ -/* SetEPRxCount (VCOM_RX_ENDP, VCOM_RX_EPSIZE); */ -/* // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS); */ -/* SetEPRxStatus (VCOM_RX_ENDP, EP_RX_VALID); */ - - SetEPType (3, EP_BULK); - SetEPRxAddr (3, 0x110); - SetEPRxCount (3,64); - // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS); - SetEPRxStatus (3, EP_RX_VALID); - - /* setup data endpoint IN (tx) */ - SetEPType (VCOM_TX_ENDP, EP_BULK); - SetEPTxAddr (VCOM_TX_ENDP, VCOM_TX_ADDR); - SetEPTxStatus (VCOM_TX_ENDP, EP_TX_NAK); - SetEPRxStatus (VCOM_TX_ENDP, EP_RX_DIS); - - bDeviceState = ATTACHED; - SetDeviceAddress(0); - - /* reset the rx fifo */ - recvBufIn = 0; - recvBufOut = 0; - maxNewBytes = VCOM_RX_EPSIZE; - countTx = 0; + SetEPRxCount(ENDP0, pProperty->MaxPacketSize); + SetEPRxValid(ENDP0); + + /* setup management endpoint 1 */ + SetEPType (VCOM_NOTIFICATION_ENDP, EP_INTERRUPT); + SetEPTxAddr (VCOM_NOTIFICATION_ENDP, VCOM_NOTIFICATION_ADDR); + SetEPTxStatus (VCOM_NOTIFICATION_ENDP, EP_TX_NAK); + SetEPRxStatus (VCOM_NOTIFICATION_ENDP, EP_RX_DIS); + + /* setup data endpoint OUT (rx) */ + /* SetEPType (VCOM_RX_ENDP, EP_BULK); */ + /* SetEPRxAddr (VCOM_RX_ENDP, VCOM_RX_ADDR); */ + /* SetEPRxCount (VCOM_RX_ENDP, VCOM_RX_EPSIZE); */ + /* // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS); */ + /* SetEPRxStatus (VCOM_RX_ENDP, EP_RX_VALID); */ + + SetEPType (3, EP_BULK); + SetEPRxAddr (3, 0x110); + SetEPRxCount (3,64); + // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS); + SetEPRxStatus (3, EP_RX_VALID); + + /* setup data endpoint IN (tx) */ + SetEPType (VCOM_TX_ENDP, EP_BULK); + SetEPTxAddr (VCOM_TX_ENDP, VCOM_TX_ADDR); + SetEPTxStatus (VCOM_TX_ENDP, EP_TX_NAK); + SetEPRxStatus (VCOM_TX_ENDP, EP_RX_DIS); + + bDeviceState = ATTACHED; + SetDeviceAddress(0); + + /* reset the rx fifo */ + recvBufIn = 0; + recvBufOut = 0; + maxNewBytes = VCOM_RX_EPSIZE; + countTx = 0; } void usbStatusIn(void) { - /* adjust the usart line coding - if we wish to couple the CDC line coding - with the real usart port */ + /* adjust the usart line coding + if we wish to couple the CDC line coding + with the real usart port */ } void usbStatusOut(void) { } RESULT usbDataSetup(uint8 request) { - uint8 *(*CopyRoutine)(uint16); - CopyRoutine = NULL; - - if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { - switch (request) { - case (GET_LINE_CODING): - CopyRoutine = vcomGetSetLineCoding; - last_request = GET_LINE_CODING; - break; - case (SET_LINE_CODING): - CopyRoutine = vcomGetSetLineCoding; - last_request = SET_LINE_CODING; - break; - default: break; + uint8 *(*CopyRoutine)(uint16); + CopyRoutine = NULL; + + if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { + switch (request) { + case (GET_LINE_CODING): + CopyRoutine = vcomGetSetLineCoding; + last_request = GET_LINE_CODING; + break; + case (SET_LINE_CODING): + CopyRoutine = vcomGetSetLineCoding; + last_request = SET_LINE_CODING; + break; + default: break; + } } - } - if (CopyRoutine == NULL) { - return USB_UNSUPPORT; - } + if (CopyRoutine == NULL) { + return USB_UNSUPPORT; + } - pInformation->Ctrl_Info.CopyData = CopyRoutine; - pInformation->Ctrl_Info.Usb_wOffset = 0; - (*CopyRoutine)(0); - return USB_SUCCESS; + pInformation->Ctrl_Info.CopyData = CopyRoutine; + pInformation->Ctrl_Info.Usb_wOffset = 0; + (*CopyRoutine)(0); + return USB_SUCCESS; } RESULT usbNoDataSetup(u8 request) { - uint8 new_signal; - - /* we support set com feature but dont handle it */ - if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { - - switch (request) { - case (SET_COMM_FEATURE): - return USB_SUCCESS; - case (SET_CONTROL_LINE_STATE): - /* to reset the board, pull both dtr and rts low - then pulse dtr by itself */ - new_signal = pInformation->USBwValues.bw.bb0 & (CONTROL_LINE_DTR | CONTROL_LINE_RTS); - line_dtr_rts = new_signal & 0x03; - - switch (reset_state) { - /* no default, covered enum */ - case DTR_UNSET: - if ((new_signal & CONTROL_LINE_DTR) == 0 ) { - reset_state = DTR_LOW; - } else { - reset_state = DTR_HIGH; - } - break; - - case DTR_HIGH: - if ((new_signal & CONTROL_LINE_DTR) == 0 ) { - reset_state = DTR_NEGEDGE; - } else { - reset_state = DTR_HIGH; - } - break; - - case DTR_NEGEDGE: - if ((new_signal & CONTROL_LINE_DTR) == 0 ) { - reset_state = DTR_LOW; - } else { - reset_state = DTR_HIGH; - } - break; - - case DTR_LOW: - if ((new_signal & CONTROL_LINE_DTR) == 0 ) { - reset_state = DTR_LOW; - } else { - reset_state = DTR_HIGH; - } - break; - } - - return USB_SUCCESS; + uint8 new_signal; + + /* we support set com feature but dont handle it */ + if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { + + switch (request) { + case (SET_COMM_FEATURE): + return USB_SUCCESS; + case (SET_CONTROL_LINE_STATE): + /* to reset the board, pull both dtr and rts low + then pulse dtr by itself */ + new_signal = pInformation->USBwValues.bw.bb0 & (CONTROL_LINE_DTR | CONTROL_LINE_RTS); + line_dtr_rts = new_signal & 0x03; + + switch (reset_state) { + /* no default, covered enum */ + case DTR_UNSET: + if ((new_signal & CONTROL_LINE_DTR) == 0 ) { + reset_state = DTR_LOW; + } else { + reset_state = DTR_HIGH; + } + break; + + case DTR_HIGH: + if ((new_signal & CONTROL_LINE_DTR) == 0 ) { + reset_state = DTR_NEGEDGE; + } else { + reset_state = DTR_HIGH; + } + break; + + case DTR_NEGEDGE: + if ((new_signal & CONTROL_LINE_DTR) == 0 ) { + reset_state = DTR_LOW; + } else { + reset_state = DTR_HIGH; + } + break; + + case DTR_LOW: + if ((new_signal & CONTROL_LINE_DTR) == 0 ) { + reset_state = DTR_LOW; + } else { + reset_state = DTR_HIGH; + } + break; + } + + return USB_SUCCESS; + } } - } - return USB_UNSUPPORT; + return USB_UNSUPPORT; } RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) { - if (alt_setting > 0) { - return USB_UNSUPPORT; - } else if (interface > 1) { - return USB_UNSUPPORT; - } + if (alt_setting > 0) { + return USB_UNSUPPORT; + } else if (interface > 1) { + return USB_UNSUPPORT; + } - return USB_SUCCESS; + return USB_SUCCESS; } u8* usbGetDeviceDescriptor(u16 length) { - return Standard_GetDescriptorData(length, &Device_Descriptor); + return Standard_GetDescriptorData(length, &Device_Descriptor); } u8* usbGetConfigDescriptor(u16 length) { - return Standard_GetDescriptorData(length, &Config_Descriptor); + return Standard_GetDescriptorData(length, &Config_Descriptor); } u8* usbGetStringDescriptor(u16 length) { - uint8 wValue0 = pInformation->USBwValue0; + uint8 wValue0 = pInformation->USBwValue0; - if (wValue0 > 2) { - return NULL; - } - return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]); + if (wValue0 > 2) { + return NULL; + } + return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]); } /* internal callbacks to respond to standard requests */ void usbSetConfiguration(void) { - if (pInformation->Current_Configuration != 0) { - bDeviceState = CONFIGURED; - } + if (pInformation->Current_Configuration != 0) { + bDeviceState = CONFIGURED; + } } void usbSetDeviceAddress(void) { - bDeviceState = ADDRESSED; + bDeviceState = ADDRESSED; } |