Changeset 4af90bf in avrstuff


Ignore:
Timestamp:
Jan 14, 2012, 9:11:20 PM (12 years ago)
Author:
Adrien Destugues <pulkomandy@…>
Branches:
main
Children:
e07597b
Parents:
1fabcce
Message:

work in progress CrO2:

  • USB configuration for a control endpoint with data payload
  • Timer setup for generating MFM stream

git-svn-id: svn://pulkomandy.tk/avrstuff@51 c6672c3c-f6b6-47f9-9001-1fd6b12fecbe

Location:
V-USB_Dev/firmwares/CrO2
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • V-USB_Dev/firmwares/CrO2/main.c

    r1fabcce r4af90bf  
    1010#include "usbdrv/usbdrv.h"
    1111
    12 #define DDRIN DDRB
    13 #define PORTIN PORTB
    14 #define PININ PINB
     12static uint8_t ioblock[275]; // Max. Size of an MO5 standard block including sync header
     13static uint8_t status; // status bits
     14static uint16_t writePos;
     15static uint16_t blksz;
    1516
    16 #define DDROUT DDRC
    17 #define PORTOUT PORTC
     17static uint16_t readPos;
     18static uint8_t bitpos;
     19static uint8_t bit; // Currently generated bit
    1820
    19 static uint8_t reportBuffer[5];
    20 static uint8_t buttons[6];
    21 static uint8_t idleRate;
     21int main() {
     22        // Init
     23        status = 0;
     24        writePos = 0;
     25        blksz = 0;
    2226
    23 void main() {
    2427        wdt_enable(WDTO_2S);
    2528
     
    2730        usbInit();
    2831        sei();
    29         bool doReport;
    3032
    31         DDROUT = 0; // Keyboard matrix out
    32         PORTOUT = 255; // Enable pull up
    33                 // We put all pins as input then output a 0 in only one at a time.
    34                 // All the other pins are high-Z to avoid short circuits when many
    35                 // buttons are pressed.
    36         DDRIN = 0; // Keyboard matrix in
    37         PORTIN = 255; // Enable pull up
     33        bit = 1;
     34        bitpos = 0;
     35        readPos = 0;
    3836
    39     // configure timer 0 for a rate of 16M/(256 * 256) = ~244Hz
    40     TCCR0 = 4;          // timer 0 prescaler: 256
     37        // Setup TIMER 1 for MFM pulses generation
     38        TCCR1A = (1<<COM1A0); // Enable OC1A output
     39        // CTC mode with OCR1A as MAXregister
     40        TCCR1B = (1<<WGM12) | (1<<CS10);
     41        OCR1A = 12800; // 800us bit clock
     42        OCR1B = 6400; // Half-clock for 1 bits
     43        TIMSK = (1 << OCIE1B) | (1 << OCIE1A); // interrupts on both timer matches.
    4144
    42         reportBuffer[0] = 0;
    43         doReport = false;
     45        // TODO only start the timer when actually needed (start of block)
     46        // and stop it when done.
     47        DDRB |= 2; // OC1A/PB1 as output
     48
    4449
    4550        while(1) {
     
    4752                usbPoll();
    4853
    49                 for(int i = 0; i != 6; i++) {
    50                         DDROUT = 1<<i;
    51                         PORTOUT = ~(1<<i);
    52                         _delay_us(63);
    53                         if (buttons[i] != ((~PININ)&0x3F))
    54                         {
    55                                 doReport = true;
    56                                 buttons[i] = (~PININ)&0x3F;
    57                         }
    58                 }
    59                 DDROUT = 0;
    60                 PORTOUT = 255;
    61 
    62                 // Copy lines 1 to 3 to the same lines in the report
    63                 for(int i=1; i != 4; i++) {
    64                         reportBuffer[i] = buttons[i];
    65                 }
    66 
    67                 // Dispatch line 0 to report 1,2,3 (2 buttons each)
    68                 reportBuffer[1] |= (buttons[0] << 4)&0xC0;
    69                 reportBuffer[2] |= (buttons[0] << 2)&0xC0;
    70                 reportBuffer[3] |= (buttons[0])&0xC0;
    71 
    72                 // Copy part line 6
    73                 reportBuffer[4] = buttons[5]; // 2 btns left here
    74                 //reportBuffer[0] = buttons[4]; // this line is unused anyway, report as
    75                                                                           // axis
    76 
    77                 if (doReport && usbInterruptIsReady()) {
    78                         usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
    79                         doReport = false;
    80                 }
     54                // TODO send data to tape !
    8155        }
    8256}
    8357
    8458
    85 static uint8_t protocolVer = 1;
    86 uint8_t expectReport = 0;
     59uint8_t usbFunctionSetup(uint8_t data[8]) {
     60        usbRequest_t *rq = (void *)data;
    8761
    88 
    89 char PROGMEM usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
    90         0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    91     0x09, 0x04,                    // USAGE (Joystick)
    92     0xa1, 0x01,                    // COLLECTION (Application)
    93     0xa1, 0x02,                    //   COLLECTION (Logical)
    94 
    95     0x75, 0x04,                    //     REPORT_SIZE (8)
    96     0x95, 0x02,                    //     REPORT_COUNT (2)
    97     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    98     0x25, 0x0F,                    //     LOGICAL_MAXIMUM (15)
    99     0x35, 0x00,                    //     PHYS_MINIMUM (0)
    100     0x45, 0x0F,                    //     PHYS_MAXIMUM (15)
    101     0x09, 0x30,                    //     USAGE (X)
    102     0x09, 0x31,                    //     USAGE (Y)
    103     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    104 
    105     0x75, 0x01,                    //     REPORT_SIZE (1)
    106     0x95, 0x20,                    //     REPORT_COUNT (32)
    107     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    108     0x45, 0x01,                    //     PHYSMAX (1)
    109     0x05, 0x09,                    //     USAGE_PAGE (Button)
    110     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    111     0x29, 0x20,                    //     USAGE_MAXIMUM (Button 32)
    112     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    113     0xc0,                          //   END_COLLECTION
    114     0xc0                           // END_COLLECTION
    115 };
    116 
    117 
    118 uint8_t usbFunctionSetup(uint8_t data[8]) {
    119     usbRequest_t *rq = (void *)data;
    120     usbMsgPtr = reportBuffer;
    121     if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
    122         // class request type
    123         if (rq->bRequest == USBRQ_HID_GET_REPORT) {
    124             // wValue: ReportType (highbyte), ReportID (lowbyte)
    125             // we only have one report type, so don't look at wValue
    126             return sizeof(reportBuffer);
    127         } else if (rq->bRequest == USBRQ_HID_SET_REPORT) {
    128             if (rq->wLength.word == 1) {
    129                 // We expect one byte reports
    130                 expectReport = 1;
    131                 return 0xff; // Call usbFunctionWrite with data
    132             }
    133         } else if (rq->bRequest == USBRQ_HID_GET_IDLE) {
    134             usbMsgPtr = &idleRate;
    135             return 1;
    136         } else if (rq->bRequest == USBRQ_HID_SET_IDLE) {
    137             idleRate = rq->wValue.bytes[1];
    138         } else if (rq->bRequest == USBRQ_HID_GET_PROTOCOL) {
    139             if (rq->wValue.bytes[1] < 1) {
    140                 protocolVer = rq->wValue.bytes[1];
    141             }
    142         } else if(rq->bRequest == USBRQ_HID_SET_PROTOCOL) {
    143             usbMsgPtr = &protocolVer;
    144             return 1;
    145         }
    146     } else {
    147         // no vendor specific requests implemented
    148     }
    149     return 0;
     62        usbMsgPtr = ioblock;
     63        switch(rq->bRequest)
     64        {
     65                case 0:
     66                        {  /* CONFIGURE */
     67                                status = rq->wValue.bytes[0];
     68                                return 0;
     69                        }
     70                case 1:
     71                        {  /* RECEIVE/POLL DATA (TAPE > USB) */
     72                                return 254;
     73                        }
     74                case 2:
     75                        {
     76                                /* SEND DATA (USB > TAPE) */
     77                                /* Get ready, actual data will come in usbFunctionWrite */
     78                                // TODO store type of MO5 block + size in ioblock
     79                                writePos = 0;
     80                                blksz = rq->wLength.word;
     81                                return USB_NO_MSG; // Call usbFunctionWrite to send the data
     82                        }
     83        }
     84        return 0;
    15085}
    15186
    152 uint8_t usbFunctionWrite(uchar *data, uchar len) {
    153     expectReport = 0;
    154     return 0x01;
     87uint8_t usbFunctionWrite(uint8_t* data, uint8_t len)
     88{
     89        // The data for a single request will be sent as slices of up to 8 bytes.
     90        for (int i = 0; i < len; i++)
     91        {
     92                // TODO leave place for sync header and block type+size
     93                ioblock[writePos++] = data[i];
     94        }
     95
     96        // TODO compute checksum as we go
     97
     98        return writePos>= blksz ? 1:0;
     99        // returns 0: "needs more data"
     100        // returns 1: "done"
     101        // returns FF: "error"
    155102}
    156103
     104ISR (TIMER1_COMPA_vect)
     105{
     106        // generate next bit
     107        bit = (ioblock[readPos] >> bitpos) & 1;
     108        bitpos++;
     109        if (bitpos > 7)
     110        {
     111                bitpos = 0;
     112                readPos++;
     113                if (readPos > 270)
     114                        readPos = 0; // TODO stop timer
     115        }
     116}
     117
     118ISR (TIMER1_COMPB_vect)
     119{
     120        TCCR1A |= (bit << FOC1A); // Force toggle of A on B compare when generating a 1 bit
     121}
  • V-USB_Dev/firmwares/CrO2/usbconfig.h

    r1fabcce r4af90bf  
    5252 * default control endpoint 0 and an interrupt-in endpoint 1.
    5353 */
    54 #define USB_CFG_HAVE_INTRIN_ENDPOINT    1
     54#define USB_CFG_HAVE_INTRIN_ENDPOINT    0
    5555/** Define this to 1 if you want to compile a version with three endpoints: The
    5656 * default control endpoint 0, an interrupt-in endpoint 1 and an interrupt-in
     
    7272 * device is powered from the USB bus.
    7373 */
    74 #define USB_CFG_IS_SELF_POWERED         0
     74#define USB_CFG_IS_SELF_POWERED         1
    7575/** Set this variable to the maximum USB bus power consumption of your device.
    7676 * The value is in milliamperes. [It will be divided by two since USB
    7777 * communicates power requirements in units of 2 mA.]
    7878 */
    79 #define USB_CFG_MAX_BUS_POWER           100
     79#define USB_CFG_MAX_BUS_POWER           20
    8080/** Set this to 1 if you want usbFunctionWrite() to be called for control-out
    8181 * transfers. Set it to 0 if you don't need it and want to save a couple of
    8282 * bytes.
    8383 */
    84 #define USB_CFG_IMPLEMENT_FN_WRITE      0
     84#define USB_CFG_IMPLEMENT_FN_WRITE      1
    8585/** Set this to 1 if you need to send control replies which are generated
    8686 * "on the fly" when usbFunctionRead() is called. If you only want to send
     
    102102/* -------------------------- Device Description --------------------------- */
    103103
    104 /** We cannot use Obdev's free shared VID/PID pair because this is a HID.
    105  * We use John Hyde's VID (author of the book "USB Design By Example") for
    106  * this example instead. John has offered this VID for use by students for
    107  * non-commercial devices. Well... This example is for demonstration and
    108  * education only... DO NOT LET DEVICES WITH THIS VID ESCAPE YOUR LAB!
    109  * The Product-ID is a random number.
    110  *
     104/*
    111105 * USB vendor ID for the device, low byte first. If you have registered your
    112106 * own Vendor ID, define it here. Otherwise you use obdev's free shared
    113107 * VID/PID pair. Be sure to read USBID-License.txt for rules!
    114108 */
    115 #define  USB_CFG_VENDOR_ID       0x42, 0x42
     109#define  USB_CFG_VENDOR_ID       0xC0, 0x16
    116110/** This is the ID of the product, low byte first. It is interpreted in the
    117111 * scope of the vendor ID. If you have registered your own VID with usb.org
     
    120114 * USBID-License.txt!
    121115 */
    122 #define  USB_CFG_DEVICE_ID       0x31, 0x17
     116#define  USB_CFG_DEVICE_ID       0xDC, 0x05
    123117/** Version number of the device: Minor number first, then major number.
    124118 */
     
    139133 * the macros. See the file USBID-License.txt before you assign a name.
    140134 */
    141 #define USB_CFG_DEVICE_NAME     'S','t','a','r','k','a','d','r','o','i','d'
     135#define USB_CFG_DEVICE_NAME     'C','r','O','2'
    142136/** Length of USB_CFG_DEVICE_NAME
    143137 */
    144 #define USB_CFG_DEVICE_NAME_LEN 11
     138#define USB_CFG_DEVICE_NAME_LEN 4
    145139/** See USB specification if you want to conform to an existing device class.
    146140 * This setting means to specify the class at the interface level.
    147141 */
    148 #define USB_CFG_DEVICE_CLASS    0
     142#define USB_CFG_DEVICE_CLASS    0xFF
    149143/** See USB specification if you want to conform to an existing device subclass.
    150144 */
     
    153147 * protocol. This is HID class.
    154148 */
    155 #define USB_CFG_INTERFACE_CLASS     0x03
     149#define USB_CFG_INTERFACE_CLASS     0x0
    156150/** See USB specification if you want to conform to an existing device class or
    157151 * protocol. This is not a boot device.
     
    165159 * an HID device. Otherwise don't define it or define it to 0.
    166160 */
    167 #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    44
     161#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    0
    168162
    169163/* ------------------- Fine Control over USB Descriptors ------------------- */
Note: See TracChangeset for help on using the changeset viewer.