Merge branch 'rn42' into merge_rn42
Conflicts: .gitignore common.mk common/debug_config.h common/print.h
This commit is contained in:
		
						commit
						363950982a
					
				
					 92 changed files with 4461 additions and 401 deletions
				
			
		| 
						 | 
				
			
			@ -148,10 +148,23 @@ static void Console_Task(void)
 | 
			
		|||
*/
 | 
			
		||||
void EVENT_USB_Device_Connect(void)
 | 
			
		||||
{
 | 
			
		||||
    /* For battery powered device */
 | 
			
		||||
    if (!USB_IsInitialized) {
 | 
			
		||||
        USB_Init();
 | 
			
		||||
        USB_Device_EnableSOFEvents();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EVENT_USB_Device_Disconnect(void)
 | 
			
		||||
{
 | 
			
		||||
    /* For battery powered device */
 | 
			
		||||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated. 
 | 
			
		||||
    if (USB_IsInitialized) {
 | 
			
		||||
        USB_Disable();  // Disable all interrupts
 | 
			
		||||
	USB_Controller_Enable();
 | 
			
		||||
        USB_INT_Enable(USB_INT_VBUSTI);
 | 
			
		||||
    }
 | 
			
		||||
*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EVENT_USB_Device_Reset(void)
 | 
			
		||||
| 
						 | 
				
			
			@ -574,7 +587,7 @@ int main(void)
 | 
			
		|||
    print("Keyboard start.\n");
 | 
			
		||||
    while (1) {
 | 
			
		||||
        while (USB_DeviceState == DEVICE_STATE_Suspended) {
 | 
			
		||||
            suspend_power_down();
 | 
			
		||||
            suspend_power_down(WDTO_120MS);
 | 
			
		||||
            if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
 | 
			
		||||
                    USB_Device_SendRemoteWakeup();
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										271
									
								
								protocol/mbed/HIDKeyboard.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								protocol/mbed/HIDKeyboard.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,271 @@
 | 
			
		|||
#include <stdint.h>
 | 
			
		||||
#include "USBHID.h"
 | 
			
		||||
#include "USBHID_Types.h"
 | 
			
		||||
#include "USBDescriptor.h"
 | 
			
		||||
#include "HIDKeyboard.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_CONFIGURATION (1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
HIDKeyboard::HIDKeyboard(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
 | 
			
		||||
{
 | 
			
		||||
    USBDevice::connect();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool HIDKeyboard::sendReport(report_keyboard_t report) {
 | 
			
		||||
    USBDevice::write(EP1IN, report.raw, sizeof(report), MAX_PACKET_SIZE_EP1);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t HIDKeyboard::leds() {
 | 
			
		||||
    return led_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
 | 
			
		||||
    if (configuration != DEFAULT_CONFIGURATION) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Configure endpoints > 0
 | 
			
		||||
    addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
 | 
			
		||||
    //addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
 | 
			
		||||
 | 
			
		||||
    // We activate the endpoint to be able to recceive data
 | 
			
		||||
    //readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t * HIDKeyboard::stringImanufacturerDesc() {
 | 
			
		||||
    static uint8_t stringImanufacturerDescriptor[] = {
 | 
			
		||||
        0x18,                                            /*bLength*/
 | 
			
		||||
        STRING_DESCRIPTOR,                               /*bDescriptorType 0x03*/
 | 
			
		||||
        't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0   /*bString iManufacturer*/
 | 
			
		||||
    };
 | 
			
		||||
    return stringImanufacturerDescriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t * HIDKeyboard::stringIproductDesc() {
 | 
			
		||||
    static uint8_t stringIproductDescriptor[] = {
 | 
			
		||||
        0x0a,                                                       /*bLength*/
 | 
			
		||||
        STRING_DESCRIPTOR,                                          /*bDescriptorType 0x03*/
 | 
			
		||||
        'm',0,'b',0,'e',0,'d',0                                     /*bString iProduct*/
 | 
			
		||||
    };
 | 
			
		||||
    return stringIproductDescriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t * HIDKeyboard::stringIserialDesc() {
 | 
			
		||||
    static uint8_t stringIserialDescriptor[] = {
 | 
			
		||||
        0x04,                                                           /*bLength*/
 | 
			
		||||
        STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
 | 
			
		||||
        '0',0                                                           /*bString iSerial*/
 | 
			
		||||
    };
 | 
			
		||||
    return stringIserialDescriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t * HIDKeyboard::reportDesc() {
 | 
			
		||||
    static uint8_t reportDescriptor[] = {
 | 
			
		||||
        USAGE_PAGE(1), 0x01,                    // Generic Desktop
 | 
			
		||||
        USAGE(1), 0x06,                         // Keyboard
 | 
			
		||||
        COLLECTION(1), 0x01,                    // Application
 | 
			
		||||
 | 
			
		||||
        USAGE_PAGE(1), 0x07,                    // Key Codes
 | 
			
		||||
        USAGE_MINIMUM(1), 0xE0,
 | 
			
		||||
        USAGE_MAXIMUM(1), 0xE7,
 | 
			
		||||
        LOGICAL_MINIMUM(1), 0x00,
 | 
			
		||||
        LOGICAL_MAXIMUM(1), 0x01,
 | 
			
		||||
        REPORT_SIZE(1), 0x01,
 | 
			
		||||
        REPORT_COUNT(1), 0x08,
 | 
			
		||||
        INPUT(1), 0x02,                         // Data, Variable, Absolute
 | 
			
		||||
 | 
			
		||||
        REPORT_COUNT(1), 0x01,
 | 
			
		||||
        REPORT_SIZE(1), 0x08,
 | 
			
		||||
        INPUT(1), 0x01,                         // Constant
 | 
			
		||||
 | 
			
		||||
        REPORT_COUNT(1), 0x05,
 | 
			
		||||
        REPORT_SIZE(1), 0x01,
 | 
			
		||||
        USAGE_PAGE(1), 0x08,                    // LEDs
 | 
			
		||||
        USAGE_MINIMUM(1), 0x01,
 | 
			
		||||
        USAGE_MAXIMUM(1), 0x05,
 | 
			
		||||
        OUTPUT(1), 0x02,                        // Data, Variable, Absolute
 | 
			
		||||
 | 
			
		||||
        REPORT_COUNT(1), 0x01,
 | 
			
		||||
        REPORT_SIZE(1), 0x03,
 | 
			
		||||
        OUTPUT(1), 0x01,                        // Constant
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        REPORT_COUNT(1), 0x06,
 | 
			
		||||
        REPORT_SIZE(1), 0x08,
 | 
			
		||||
        LOGICAL_MINIMUM(1), 0x00,
 | 
			
		||||
        LOGICAL_MAXIMUM(1), 0xFF,
 | 
			
		||||
        USAGE_PAGE(1), 0x07,                    // Key Codes
 | 
			
		||||
        USAGE_MINIMUM(1), 0x00,
 | 
			
		||||
        USAGE_MAXIMUM(1), 0xFF,
 | 
			
		||||
        INPUT(1), 0x00,                         // Data, Array
 | 
			
		||||
        END_COLLECTION(0),
 | 
			
		||||
    };
 | 
			
		||||
    reportLength = sizeof(reportDescriptor);
 | 
			
		||||
    return reportDescriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t HIDKeyboard::reportDescLength() {
 | 
			
		||||
    reportDesc();
 | 
			
		||||
    return reportLength;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
 | 
			
		||||
                               + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
 | 
			
		||||
                               + (1 * HID_DESCRIPTOR_LENGTH) \
 | 
			
		||||
                               + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
 | 
			
		||||
uint8_t * HIDKeyboard::configurationDesc() {
 | 
			
		||||
    static uint8_t configurationDescriptor[] = {
 | 
			
		||||
        CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
 | 
			
		||||
        CONFIGURATION_DESCRIPTOR,       // bDescriptorType
 | 
			
		||||
        LSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (LSB)
 | 
			
		||||
        MSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (MSB)
 | 
			
		||||
        0x01,                           // bNumInterfaces
 | 
			
		||||
        DEFAULT_CONFIGURATION,          // bConfigurationValue
 | 
			
		||||
        0x00,                           // iConfiguration
 | 
			
		||||
        C_RESERVED | C_REMOTE_WAKEUP,   // bmAttributes
 | 
			
		||||
        C_POWER(100),                   // bMaxPowerHello World from Mbed
 | 
			
		||||
 | 
			
		||||
        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
 | 
			
		||||
        INTERFACE_DESCRIPTOR,           // bDescriptorType
 | 
			
		||||
        0x00,                           // bInterfaceNumber
 | 
			
		||||
        0x00,                           // bAlternateSetting
 | 
			
		||||
        0x01,                           // bNumEndpoints
 | 
			
		||||
        HID_CLASS,                      // bInterfaceClass
 | 
			
		||||
        1,                              // bInterfaceSubClass (boot)
 | 
			
		||||
        1,                              // bInterfaceProtocol (keyboard)
 | 
			
		||||
        0x00,                           // iInterface
 | 
			
		||||
 | 
			
		||||
        HID_DESCRIPTOR_LENGTH,          // bLength
 | 
			
		||||
        HID_DESCRIPTOR,                 // bDescriptorType
 | 
			
		||||
        LSB(HID_VERSION_1_11),          // bcdHID (LSB)
 | 
			
		||||
        MSB(HID_VERSION_1_11),          // bcdHID (MSB)
 | 
			
		||||
        0x00,                           // bCountryCode
 | 
			
		||||
        0x01,                           // bNumDescriptors
 | 
			
		||||
        REPORT_DESCRIPTOR,              // bDescriptorType
 | 
			
		||||
        (uint8_t)(LSB(reportDescLength())),  // wDescriptorLength (LSB)
 | 
			
		||||
        (uint8_t)(MSB(reportDescLength())),  // wDescriptorLength (MSB)
 | 
			
		||||
 | 
			
		||||
        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
 | 
			
		||||
        ENDPOINT_DESCRIPTOR,            // bDescriptorType
 | 
			
		||||
        PHY_TO_DESC(EP1IN),             // bEndpointAddress
 | 
			
		||||
        E_INTERRUPT,                    // bmAttributes
 | 
			
		||||
        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
 | 
			
		||||
        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
 | 
			
		||||
        1,                           // bInterval (milliseconds)
 | 
			
		||||
    };
 | 
			
		||||
    return configurationDescriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
uint8_t * HIDKeyboard::deviceDesc() {
 | 
			
		||||
    static uint8_t deviceDescriptor[] = {
 | 
			
		||||
        DEVICE_DESCRIPTOR_LENGTH,       /* bLength */
 | 
			
		||||
        DEVICE_DESCRIPTOR,              /* bDescriptorType */
 | 
			
		||||
        LSB(USB_VERSION_2_0),           /* bcdUSB (LSB) */
 | 
			
		||||
        MSB(USB_VERSION_2_0),           /* bcdUSB (MSB) */
 | 
			
		||||
        0x00,                           /* bDeviceClass */
 | 
			
		||||
        0x00,                           /* bDeviceSubClass */
 | 
			
		||||
        0x00,                           /* bDeviceprotocol */
 | 
			
		||||
        MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
 | 
			
		||||
        (uint8_t)(LSB(0xfeed)),                 /* idVendor (LSB) */
 | 
			
		||||
        (uint8_t)(MSB(0xfeed)),                 /* idVendor (MSB) */
 | 
			
		||||
        (uint8_t)(LSB(0x1bed)),                /* idProduct (LSB) */
 | 
			
		||||
        (uint8_t)(MSB(0x1bed)),                /* idProduct (MSB) */
 | 
			
		||||
        (uint8_t)(LSB(0x0002)),           /* bcdDevice (LSB) */
 | 
			
		||||
        (uint8_t)(MSB(0x0002)),           /* bcdDevice (MSB) */
 | 
			
		||||
        0,    /* iManufacturer */
 | 
			
		||||
        0,         /* iProduct */
 | 
			
		||||
        0,          /* iSerialNumber */
 | 
			
		||||
        0x01                            /* bNumConfigurations */
 | 
			
		||||
    };
 | 
			
		||||
    return deviceDescriptor;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
bool HIDKeyboard::USBCallback_request() {
 | 
			
		||||
    bool success = false;
 | 
			
		||||
    CONTROL_TRANSFER * transfer = getTransferPtr();
 | 
			
		||||
    uint8_t *hidDescriptor;
 | 
			
		||||
 | 
			
		||||
    // Process additional standard requests
 | 
			
		||||
 | 
			
		||||
    if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
 | 
			
		||||
    {
 | 
			
		||||
        switch (transfer->setup.bRequest)
 | 
			
		||||
        {
 | 
			
		||||
            case GET_DESCRIPTOR:
 | 
			
		||||
                switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
 | 
			
		||||
                {
 | 
			
		||||
                    case REPORT_DESCRIPTOR:
 | 
			
		||||
                        if ((reportDesc() != NULL) \
 | 
			
		||||
                            && (reportDescLength() != 0))
 | 
			
		||||
                        {
 | 
			
		||||
                            transfer->remaining = reportDescLength();
 | 
			
		||||
                            transfer->ptr = reportDesc();
 | 
			
		||||
                            transfer->direction = DEVICE_TO_HOST;
 | 
			
		||||
                            success = true;
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    case HID_DESCRIPTOR:
 | 
			
		||||
                            // Find the HID descriptor, after the configuration descriptor
 | 
			
		||||
                            hidDescriptor = findDescriptor(HID_DESCRIPTOR);
 | 
			
		||||
                            if (hidDescriptor != NULL)
 | 
			
		||||
                            {
 | 
			
		||||
                                transfer->remaining = HID_DESCRIPTOR_LENGTH;
 | 
			
		||||
                                transfer->ptr = hidDescriptor;
 | 
			
		||||
                                transfer->direction = DEVICE_TO_HOST;
 | 
			
		||||
                                success = true;
 | 
			
		||||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
                     
 | 
			
		||||
                    default:
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Process class-specific requests
 | 
			
		||||
    if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
 | 
			
		||||
    {
 | 
			
		||||
        switch (transfer->setup.bRequest) {
 | 
			
		||||
            case SET_REPORT:
 | 
			
		||||
                // LED indicator
 | 
			
		||||
                // TODO: check Interface and Report length?
 | 
			
		||||
                // if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
 | 
			
		||||
                // if (transfer->setup.wLength == 1)
 | 
			
		||||
 | 
			
		||||
                transfer->remaining = 1;
 | 
			
		||||
                //transfer->ptr = ?? what ptr should be set when OUT(not used?)
 | 
			
		||||
                transfer->direction = HOST_TO_DEVICE;
 | 
			
		||||
                transfer->notify = true;    /* notify with USBCallback_requestCompleted */
 | 
			
		||||
                success = true;
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HIDKeyboard::USBCallback_requestCompleted(uint8_t * buf, uint32_t length)
 | 
			
		||||
{
 | 
			
		||||
    if (length > 0) {
 | 
			
		||||
        CONTROL_TRANSFER *transfer = getTransferPtr();
 | 
			
		||||
        if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
 | 
			
		||||
            switch (transfer->setup.bRequest) {
 | 
			
		||||
                case SET_REPORT:
 | 
			
		||||
                    led_state = buf[0];
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								protocol/mbed/HIDKeyboard.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								protocol/mbed/HIDKeyboard.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
#ifndef HIDKEYBOARD_H
 | 
			
		||||
 | 
			
		||||
#include "stdint.h"
 | 
			
		||||
#include "stdbool.h"
 | 
			
		||||
#include "USBHID.h"
 | 
			
		||||
#include "report.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HIDKeyboard : public USBDevice {
 | 
			
		||||
public:
 | 
			
		||||
    HIDKeyboard(uint16_t vendor_id = 0xFEED, uint16_t product_id = 0xabed, uint16_t product_release = 0x0001);
 | 
			
		||||
 | 
			
		||||
    bool sendReport(report_keyboard_t report);
 | 
			
		||||
    uint8_t leds(void);
 | 
			
		||||
protected:
 | 
			
		||||
    uint16_t reportLength;
 | 
			
		||||
    virtual bool USBCallback_setConfiguration(uint8_t configuration);
 | 
			
		||||
    virtual uint8_t * stringImanufacturerDesc();
 | 
			
		||||
    virtual uint8_t * stringIproductDesc();
 | 
			
		||||
    virtual uint8_t * stringIserialDesc();
 | 
			
		||||
    virtual uint16_t reportDescLength();
 | 
			
		||||
    virtual uint8_t * reportDesc();
 | 
			
		||||
    virtual uint8_t * configurationDesc();
 | 
			
		||||
    //virtual uint8_t * deviceDesc();
 | 
			
		||||
    virtual bool USBCallback_request();
 | 
			
		||||
    virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length);
 | 
			
		||||
private:
 | 
			
		||||
    uint8_t led_state;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										41
									
								
								protocol/mbed/mbed_driver.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								protocol/mbed/mbed_driver.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
#include "HIDKeyboard.h"
 | 
			
		||||
#include "host.h"
 | 
			
		||||
#include "host_driver.h"
 | 
			
		||||
#include "mbed_driver.h"
 | 
			
		||||
 | 
			
		||||
HIDKeyboard keyboard;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Host driver */
 | 
			
		||||
static uint8_t keyboard_leds(void);
 | 
			
		||||
static void send_keyboard(report_keyboard_t *report);
 | 
			
		||||
static void send_mouse(report_mouse_t *report);
 | 
			
		||||
static void send_system(uint16_t data);
 | 
			
		||||
static void send_consumer(uint16_t data);
 | 
			
		||||
 | 
			
		||||
host_driver_t mbed_driver = {
 | 
			
		||||
    keyboard_leds,
 | 
			
		||||
    send_keyboard,
 | 
			
		||||
    send_mouse,
 | 
			
		||||
    send_system,
 | 
			
		||||
    send_consumer
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint8_t keyboard_leds(void)
 | 
			
		||||
{
 | 
			
		||||
    return keyboard.leds();
 | 
			
		||||
}
 | 
			
		||||
static void send_keyboard(report_keyboard_t *report)
 | 
			
		||||
{
 | 
			
		||||
    keyboard.sendReport(*report);
 | 
			
		||||
}
 | 
			
		||||
static void send_mouse(report_mouse_t *report)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
static void send_system(uint16_t data)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
static void send_consumer(uint16_t data)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								protocol/mbed/mbed_driver.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								protocol/mbed/mbed_driver.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
#include "host_driver.h"
 | 
			
		||||
 | 
			
		||||
extern host_driver_t mbed_driver;
 | 
			
		||||
| 
						 | 
				
			
			@ -39,8 +39,9 @@ POSSIBILITY OF SUCH DAMAGE.
 | 
			
		|||
#define PS2_H
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <util/delay.h>
 | 
			
		||||
#include <avr/io.h>
 | 
			
		||||
#include "wait.h"
 | 
			
		||||
#include "ps2_io.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Primitive PS/2 Library for AVR
 | 
			
		||||
| 
						 | 
				
			
			@ -92,79 +93,27 @@ uint8_t ps2_host_recv(void);
 | 
			
		|||
void ps2_host_set_led(uint8_t usb_led);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Check port settings for clock and data line */
 | 
			
		||||
#if !(defined(PS2_CLOCK_PORT) && \
 | 
			
		||||
      defined(PS2_CLOCK_PIN) && \
 | 
			
		||||
      defined(PS2_CLOCK_DDR) && \
 | 
			
		||||
      defined(PS2_CLOCK_BIT))
 | 
			
		||||
#   error "PS/2 clock port setting is required in config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !(defined(PS2_DATA_PORT) && \
 | 
			
		||||
      defined(PS2_DATA_PIN) && \
 | 
			
		||||
      defined(PS2_DATA_DDR) && \
 | 
			
		||||
      defined(PS2_DATA_BIT))
 | 
			
		||||
#   error "PS/2 data port setting is required in config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*--------------------------------------------------------------------
 | 
			
		||||
 * static functions
 | 
			
		||||
 *------------------------------------------------------------------*/
 | 
			
		||||
static inline void clock_lo(void)
 | 
			
		||||
{
 | 
			
		||||
    PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_DDR  |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void clock_hi(void)
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    PS2_CLOCK_DDR  &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_PORT |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool clock_in(void)
 | 
			
		||||
{
 | 
			
		||||
    PS2_CLOCK_DDR  &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_PORT |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
    _delay_us(1);
 | 
			
		||||
    return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void data_lo(void)
 | 
			
		||||
{
 | 
			
		||||
    PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_DDR  |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline void data_hi(void)
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    PS2_DATA_DDR  &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_PORT |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
static inline bool data_in(void)
 | 
			
		||||
{
 | 
			
		||||
    PS2_DATA_DDR  &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_PORT |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
    _delay_us(1);
 | 
			
		||||
    return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint16_t wait_clock_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (clock_in()  && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    while (clock_in()  && us) { asm(""); wait_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_clock_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    while (!clock_in() && us) { asm(""); wait_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_lo(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    while (data_in() && us)  { asm(""); wait_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
static inline uint16_t wait_data_hi(uint16_t us)
 | 
			
		||||
{
 | 
			
		||||
    while (!data_in() && us)  { asm(""); _delay_us(1); us--; }
 | 
			
		||||
    while (!data_in() && us)  { asm(""); wait_us(1); us--; }
 | 
			
		||||
    return us;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,8 +40,9 @@ POSSIBILITY OF SUCH DAMAGE.
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <util/delay.h>
 | 
			
		||||
#include "wait.h"
 | 
			
		||||
#include "ps2.h"
 | 
			
		||||
#include "ps2_io.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,8 +59,11 @@ uint8_t ps2_error = PS2_ERR_NONE;
 | 
			
		|||
 | 
			
		||||
void ps2_host_init(void)
 | 
			
		||||
{
 | 
			
		||||
    clock_init();
 | 
			
		||||
    data_init();
 | 
			
		||||
 | 
			
		||||
    // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
 | 
			
		||||
    _delay_ms(2500);
 | 
			
		||||
    wait_ms(2500);
 | 
			
		||||
 | 
			
		||||
    inhibit();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +75,7 @@ uint8_t ps2_host_send(uint8_t data)
 | 
			
		|||
 | 
			
		||||
    /* terminate a transmission if we have */
 | 
			
		||||
    inhibit();
 | 
			
		||||
    _delay_us(100); // 100us [4]p.13, [5]p.50
 | 
			
		||||
    wait_us(100); // 100us [4]p.13, [5]p.50
 | 
			
		||||
 | 
			
		||||
    /* 'Request to Send' and Start bit */
 | 
			
		||||
    data_lo();
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +84,7 @@ uint8_t ps2_host_send(uint8_t data)
 | 
			
		|||
 | 
			
		||||
    /* Data bit */
 | 
			
		||||
    for (uint8_t i = 0; i < 8; i++) {
 | 
			
		||||
        _delay_us(15);
 | 
			
		||||
        wait_us(15);
 | 
			
		||||
        if (data&(1<<i)) {
 | 
			
		||||
            parity = !parity;
 | 
			
		||||
            data_hi();
 | 
			
		||||
| 
						 | 
				
			
			@ -92,13 +96,13 @@ uint8_t ps2_host_send(uint8_t data)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /* Parity bit */
 | 
			
		||||
    _delay_us(15);
 | 
			
		||||
    wait_us(15);
 | 
			
		||||
    if (parity) { data_hi(); } else { data_lo(); }
 | 
			
		||||
    WAIT(clock_hi, 50, 4);
 | 
			
		||||
    WAIT(clock_lo, 50, 5);
 | 
			
		||||
 | 
			
		||||
    /* Stop bit */
 | 
			
		||||
    _delay_us(15);
 | 
			
		||||
    wait_us(15);
 | 
			
		||||
    data_hi();
 | 
			
		||||
 | 
			
		||||
    /* Ack */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								protocol/ps2_io.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								protocol/ps2_io.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#ifndef PS2_IO_H
 | 
			
		||||
#define PS2_IO_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void clock_init(void);
 | 
			
		||||
void clock_lo(void);
 | 
			
		||||
void clock_hi(void);
 | 
			
		||||
bool clock_in(void);
 | 
			
		||||
 | 
			
		||||
void data_init(void);
 | 
			
		||||
void data_lo(void);
 | 
			
		||||
void data_hi(void);
 | 
			
		||||
bool data_in(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										74
									
								
								protocol/ps2_io_avr.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								protocol/ps2_io_avr.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,74 @@
 | 
			
		|||
#include <stdbool.h>
 | 
			
		||||
#include <util/delay.h>
 | 
			
		||||
 | 
			
		||||
/* Check port settings for clock and data line */
 | 
			
		||||
#if !(defined(PS2_CLOCK_PORT) && \
 | 
			
		||||
      defined(PS2_CLOCK_PIN) && \
 | 
			
		||||
      defined(PS2_CLOCK_DDR) && \
 | 
			
		||||
      defined(PS2_CLOCK_BIT))
 | 
			
		||||
#   error "PS/2 clock port setting is required in config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !(defined(PS2_DATA_PORT) && \
 | 
			
		||||
      defined(PS2_DATA_PIN) && \
 | 
			
		||||
      defined(PS2_DATA_DDR) && \
 | 
			
		||||
      defined(PS2_DATA_BIT))
 | 
			
		||||
#   error "PS/2 data port setting is required in config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Clock
 | 
			
		||||
 */
 | 
			
		||||
void clock_init(void)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clock_lo(void)
 | 
			
		||||
{
 | 
			
		||||
    PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_DDR  |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clock_hi(void)
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    PS2_CLOCK_DDR  &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_PORT |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool clock_in(void)
 | 
			
		||||
{
 | 
			
		||||
    PS2_CLOCK_DDR  &= ~(1<<PS2_CLOCK_BIT);
 | 
			
		||||
    PS2_CLOCK_PORT |=  (1<<PS2_CLOCK_BIT);
 | 
			
		||||
    _delay_us(1);
 | 
			
		||||
    return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Data
 | 
			
		||||
 */
 | 
			
		||||
void data_init(void)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void data_lo(void)
 | 
			
		||||
{
 | 
			
		||||
    PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_DDR  |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void data_hi(void)
 | 
			
		||||
{
 | 
			
		||||
    /* input with pull up */
 | 
			
		||||
    PS2_DATA_DDR  &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_PORT |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool data_in(void)
 | 
			
		||||
{
 | 
			
		||||
    PS2_DATA_DDR  &= ~(1<<PS2_DATA_BIT);
 | 
			
		||||
    PS2_DATA_PORT |=  (1<<PS2_DATA_BIT);
 | 
			
		||||
    _delay_us(1);
 | 
			
		||||
    return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								protocol/ps2_io_mbed.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								protocol/ps2_io_mbed.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
#include <stdbool.h>
 | 
			
		||||
#include "ps2_io.h"
 | 
			
		||||
#include "gpio_api.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static gpio_t clock;
 | 
			
		||||
static gpio_t data;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Clock
 | 
			
		||||
 */
 | 
			
		||||
void clock_init(void)
 | 
			
		||||
{
 | 
			
		||||
    gpio_init(&clock, P0_9);
 | 
			
		||||
    gpio_mode(&clock, OpenDrain|PullNone);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clock_lo(void)
 | 
			
		||||
{
 | 
			
		||||
    gpio_dir(&clock, PIN_OUTPUT);
 | 
			
		||||
    gpio_write(&clock, 0);
 | 
			
		||||
}
 | 
			
		||||
void clock_hi(void)
 | 
			
		||||
{
 | 
			
		||||
    gpio_dir(&clock, PIN_OUTPUT);
 | 
			
		||||
    gpio_write(&clock, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool clock_in(void)
 | 
			
		||||
{
 | 
			
		||||
    gpio_dir(&clock, PIN_INPUT);
 | 
			
		||||
    return gpio_read(&clock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Data
 | 
			
		||||
 */
 | 
			
		||||
void data_init(void)
 | 
			
		||||
{
 | 
			
		||||
    gpio_init(&data, P0_8);
 | 
			
		||||
    gpio_mode(&data, OpenDrain|PullNone);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void data_lo(void)
 | 
			
		||||
{
 | 
			
		||||
    gpio_dir(&data, PIN_OUTPUT);
 | 
			
		||||
    gpio_write(&data, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void data_hi(void)
 | 
			
		||||
{
 | 
			
		||||
    gpio_dir(&data, PIN_OUTPUT);
 | 
			
		||||
    gpio_write(&data, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool data_in(void)
 | 
			
		||||
{
 | 
			
		||||
    gpio_dir(&data, PIN_INPUT);
 | 
			
		||||
    return gpio_read(&data);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -41,13 +41,29 @@ POSSIBILITY OF SUCH DAMAGE.
 | 
			
		|||
#include "serial.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(SERIAL_UART_RTS_LO) && defined(SERIAL_UART_RTS_HI)
 | 
			
		||||
    // Buffer state
 | 
			
		||||
    //   Empty:           RBUF_SPACE == RBUF_SIZE(head==tail)
 | 
			
		||||
    //   Last 1 space:    RBUF_SPACE == 2
 | 
			
		||||
    //   Full:            RBUF_SPACE == 1(last cell of rbuf be never used.)
 | 
			
		||||
    #define RBUF_SPACE()   (rbuf_head < rbuf_tail ?  (rbuf_tail - rbuf_head) : (RBUF_SIZE - rbuf_head + rbuf_tail))
 | 
			
		||||
    // allow to send
 | 
			
		||||
    #define rbuf_check_rts_lo() do { if (RBUF_SPACE() > 2) SERIAL_UART_RTS_LO(); } while (0)
 | 
			
		||||
    // prohibit to send
 | 
			
		||||
    #define rbuf_check_rts_hi() do { if (RBUF_SPACE() <= 2) SERIAL_UART_RTS_HI(); } while (0)
 | 
			
		||||
#else
 | 
			
		||||
    #define rbuf_check_rts_lo()
 | 
			
		||||
    #define rbuf_check_rts_hi()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void serial_init(void)
 | 
			
		||||
{
 | 
			
		||||
    SERIAL_UART_INIT();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RX ring buffer
 | 
			
		||||
#define RBUF_SIZE   8
 | 
			
		||||
#define RBUF_SIZE   256
 | 
			
		||||
static uint8_t rbuf[RBUF_SIZE];
 | 
			
		||||
static uint8_t rbuf_head = 0;
 | 
			
		||||
static uint8_t rbuf_tail = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -61,6 +77,7 @@ uint8_t serial_recv(void)
 | 
			
		|||
 | 
			
		||||
    data = rbuf[rbuf_tail];
 | 
			
		||||
    rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
 | 
			
		||||
    rbuf_check_rts_lo();
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +90,7 @@ int16_t serial_recv2(void)
 | 
			
		|||
 | 
			
		||||
    data = rbuf[rbuf_tail];
 | 
			
		||||
    rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
 | 
			
		||||
    rbuf_check_rts_lo();
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -90,4 +108,5 @@ ISR(SERIAL_UART_RXD_VECT)
 | 
			
		|||
        rbuf[rbuf_head] = SERIAL_UART_DATA;
 | 
			
		||||
        rbuf_head = next;
 | 
			
		||||
    }
 | 
			
		||||
    rbuf_check_rts_hi();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue