Date:2011-09-06 09:10:37 (8 years 14 days ago)
Author:Werner Almesberger
Commit:c4b1dd425e044f8d4061e68cc653188266728441
Message:labsw/fw/: added EP0 commands; main loop now toggles

Files: labsw/fw/Makefile (1 diff)
labsw/fw/config.h (1 diff)
labsw/fw/ep0.c (1 diff)
labsw/fw/include/labsw/ep0.h (1 diff)
labsw/fw/include/labsw/usb-id.h (1 diff)
labsw/fw/labsw.c (2 diffs)
labsw/fw/usb-id.h (1 diff)

Change Details

labsw/fw/Makefile
1212
1313
1414MAIN = labsw
15OBJS = $(MAIN) usb descr version # ep0
15OBJS = $(MAIN) usb descr version ep0
1616
1717F32XBASE = ../../../f32xbase
1818
1919include $(F32XBASE)/fw/common/Makefile.system
2020include $(F32XBASE)/fw/common/Makefile.common
2121
22CFLAGS += -I../common -I../include
22CFLAGS += -Iinclude
2323LDFLAGS += --code-size $(PAYLOAD_SIZE) --code-loc $(PAYLOAD_START)
2424
2525USB_ID = $(shell \
labsw/fw/config.h
1#include "usb-id.h"
1#include "labsw/usb-id.h"
22#include "io-parts.h"
labsw/fw/ep0.c
1/*
2 * labsw/ep0.c - EP0 extension protocol
3 *
4 * Written 2008-2011 by Werner Almesberger
5 * Copyright 2008-2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdint.h>
15
16#ifndef NULL
17#define NULL 0
18#endif
19
20#include "regs.h"
21#include "usb.h"
22#include "labsw/ep0.h"
23#include "io.h"
24#include "version.h"
25
26
27extern int local;
28
29
30/*
31 * SDCC 2.8.0 had a number of code generation bugs that appeared in the big
32 * switch statement of my_setup. SDCC_FORCE_UPDATE forced the value of the
33 * "size" variable to be written to memory. This work-around doesn't seem
34 * to be necessary with 2.9.0, but we keep it around, just in case.
35 *
36 * Unfortunately, the setup->bRequest garbling bug is still with us. Without
37 * the evaluation forced with SDCC_FORCE_EVAL, sdcc gets confused about the
38 * value of setup->bRequest and then rejects all SETUP requests.
39 */
40
41#define SDCC_FORCE_EVAL(type, value) \
42    do { \
43    static volatile type foo; \
44    foo = value; \
45    } while (0)
46
47#define SDCC_FORCE_UPDATE(type, var) \
48    do { \
49    volatile type foo; \
50    foo = var; \
51    var = foo; \
52    } while (0)
53
54
55static uint8_t id[3] = {
56    EP0LABSW_MAJOR, EP0LABSW_MINOR,
57    /* hw type is set at run time */
58};
59
60static __xdata uint8_t buf[128];
61
62
63#define BUILD_OFFSET 7 /* '#' plus "65535" plus ' ' */
64
65
66static __bit my_setup(struct setup_request *setup) __reentrant
67{
68    uint32_t tmp;
69    uint8_t size, i;
70
71    switch (setup->bmRequestType | setup->bRequest << 8) {
72    case LABSW_FROM_DEV(LABSW_ID):
73        size = setup->wLength;
74        if (size > 3)
75            size = 3;
76        id[2] = 0; /* hardware type */
77        usb_send(&ep0, id, size, NULL, NULL);
78        return 1;
79    case LABSW_FROM_DEV(LABSW_BUILD):
80        tmp = build_number;
81        for (i = BUILD_OFFSET-2; tmp; i--) {
82            buf[i] = (tmp % 10)+'0';
83            tmp /= 10;
84        }
85        buf[i] = '#';
86        buf[BUILD_OFFSET-1] = ' ';
87        for (size = 0; build_date[size]; size++)
88            buf[BUILD_OFFSET+size] = build_date[size];
89        size += BUILD_OFFSET-i+1;
90        SDCC_FORCE_EVAL(uint8_t, setup->bRequest);
91        if (size > setup->wLength)
92            return 0;
93        usb_send(&ep0, buf+i, size, NULL, NULL);
94        return 1;
95
96    case LABSW_TO_DEV(LABSW_RESET):
97        RSTSRC = SWRSF;
98        while (1);
99
100    case LABSW_FROM_DEV(LABSW_GET):
101        size = setup->wLength;
102        if (size > 2)
103            size = 2;
104        buf[0] =
105            (IN_1 ? 0 : LABSW_IN1) |
106            (IN_2 ? 0 : LABSW_IN2) |
107            (IN_3 ? 0 : LABSW_IN3) |
108            (IN_4 ? 0 : LABSW_IN4);
109        buf[1] =
110            (BUT_MAIN ? 0 : LABSW_BUT_MAIN) |
111            (BUT_CH1 ? 0 : LABSW_BUT_CH1) |
112            (BUT_CH2 ? 0 : LABSW_BUT_CH2);
113        usb_send(&ep0, buf, size, NULL, NULL);
114        return 1;
115
116    case LABSW_TO_DEV(LABSW_SET):
117        local = !setup->wIndex;
118
119        if (setup->wIndex & LABSW_CH1_RELAY)
120            CH1_RELAY = setup->wValue & LABSW_CH1_RELAY ? 1 : 0;
121        if (setup->wIndex & LABSW_CH1_OPT)
122            CH1_OPT = setup->wValue & LABSW_CH1_OPT ? 0 : 1;
123        if (setup->wIndex & LABSW_CH2_RELAY)
124            CH2_RELAY = setup->wValue & LABSW_CH2_RELAY ? 1 : 0;
125        if (setup->wIndex & LABSW_CH2_OPT)
126            CH2_OPT = setup->wValue & LABSW_CH2_OPT ? 0 : 1;
127
128        if (setup->wIndex & LABSW_OUT1)
129            OUT_1 = setup->wValue & LABSW_OUT1 ? 0 : 1;
130        if (setup->wIndex & LABSW_OUT2)
131            OUT_2 = setup->wValue & LABSW_OUT2 ? 0 : 1;
132        if (setup->wIndex & LABSW_OUT3)
133            OUT_3 = setup->wValue & LABSW_OUT3 ? 0 : 1;
134        if (setup->wIndex & LABSW_OUT4)
135            OUT_4 = setup->wValue & LABSW_OUT4 ? 0 : 1;
136
137        if (setup->wIndex & LABSW_MAIN_R)
138            LED_MAIN_R = setup->wValue & LABSW_MAIN_R ? 1 : 0;
139        if (setup->wIndex & LABSW_MAIN_G)
140            LED_MAIN_G = setup->wValue & LABSW_MAIN_G ? 1 : 0;
141        if (setup->wIndex & LABSW_CH1_R)
142            LED_CH1_R = setup->wValue & LABSW_CH1_R ? 1 : 0;
143        if (setup->wIndex & LABSW_CH1_G)
144            LED_CH1_G = setup->wValue & LABSW_CH1_G ? 1 : 0;
145        if (setup->wIndex & LABSW_CH2_R)
146            LED_CH2_R = setup->wValue & LABSW_CH2_R ? 1 : 0;
147        if (setup->wIndex & LABSW_CH2_G)
148            LED_CH2_G = setup->wValue & LABSW_CH2_G ? 1 : 0;
149        return 1;
150
151    default:
152        return 0;
153    }
154}
155
156
157void ep0_init(void)
158{
159    user_setup = my_setup;
160}
labsw/fw/include/labsw/ep0.h
1/*
2 * include/labsw/ep0.h - EP0 extension protocol
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#ifndef EP0_H
15#define EP0_H
16
17/*
18 * Direction bRequest wValue wIndex wLength
19 *
20 * ->host LABSW_ID - - 3
21 * ->host LABSW_BUILD - - #bytes
22 * host-> LABSW_RESET - - 0
23 *
24 * ->host LABSW_GET - - 2
25 * host-> LABSW_SET values mask 0
26 */
27
28/*
29 * EP0 protocol:
30 *
31 * 0.0 initial release
32 */
33
34#define EP0LABSW_MAJOR 0 /* EP0 protocol, major revision */
35#define EP0LABSW_MINOR 0 /* EP0 protocol, minor revision */
36
37/*
38 * bmRequestType:
39 *
40 * D7 D6..5 D4...0
41 * | | |
42 * direction (0 = host->dev)
43 * type (2 = vendor)
44 * recipient (0 = device)
45 */
46
47
48#define LABSW_TO_DEV(req) (0x40 | (req) << 8)
49#define LABSW_FROM_DEV(req) (0xc0 | (req) << 8)
50
51
52enum cntr_requests {
53    LABSW_ID = 0x00,
54    LABSW_BUILD,
55    LABSW_RESET,
56    LABSW_GET = 0x10,
57    LABSW_SET,
58};
59
60/*
61 * LABSW_GET encoding:
62 *
63 * byte 0 byte 1
64 * 76543210 76543210
65 * 0000|||IN_1 00000||BUT_MAIN
66 * ||IN_2 |BUT_CH1
67 * |IN_3 BUT_CH2
68 * IN_4
69 *
70 * LABSW_SET encoding:
71 *
72 * value/mask
73 * fedc.ba98.7654.3210
74 * 00|| |||| |||| |||CH1_RELAY
75 * || |||| |||| ||CH1_OPT
76 * || |||| |||| |CH2_RELAY
77 * || |||| |||| CH2_OPT
78 * || |||| |||OUT_1
79 * || |||| ||OUT_2
80 * || |||| |OUT_3
81 * || |||| OUT_4
82 * || |||LED_MAIN_R
83 * || ||LED_MAIN_G
84 * || |LED_CH1_R
85 * || LED_CH1_G
86 * |LED_CH2_R
87 * LED_CH2_G
88 */
89
90enum labsw_bit_get0 {
91    LABSW_IN1 = 1,
92    LABSW_IN2 = 2,
93    LABSW_IN3 = 4,
94    LABSW_IN4 = 8,
95};
96
97enum labsw_bit_get1 {
98    LABSW_BUT_MAIN = 1,
99    LABSW_BUT_CH1 = 2,
100    LABSW_BUT_CH2 = 4,
101};
102
103enum labsw_bit_set {
104    LABSW_CH1_RELAY = 0x0001,
105    LABSW_CH1_OPT = 0x0002,
106    LABSW_CH2_RELAY = 0x0004,
107    LABSW_CH2_OPT = 0x0008,
108    LABSW_OUT1 = 0x0010,
109    LABSW_OUT2 = 0x0020,
110    LABSW_OUT3 = 0x0040,
111    LABSW_OUT4 = 0x0080,
112    LABSW_MAIN_R = 0x0100,
113    LABSW_MAIN_G = 0x0200,
114    LABSW_CH1_R = 0x0400,
115    LABSW_CH1_G = 0x0800,
116    LABSW_CH2_R = 0x1000,
117    LABSW_CH2_G = 0x2000,
118};
119
120void ep0_init(void);
121
122#endif /* !EP0_H */
labsw/fw/include/labsw/usb-id.h
1/*
2 * labsw/usb-id.h - USB vendor and product ID
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#ifndef USB_ID_H
15#define USB_ID_H
16
17/*
18 * Platform-specific settings
19 *
20 * USB_VENDOR = Qi Hardware
21 * USB_PRODUCT = 7ab5
22 *
23 * 7ab5 is "LABS" in "leet", http://en.wikipedia.org/wiki/Leet
24 */
25
26#define USB_VENDOR 0x20b7 /* Qi Hardware */
27#define USB_PRODUCT 0x7ab5 /* Lab Switch */
28
29#endif /* !USB_ID_H */
labsw/fw/labsw.c
1818
1919#include "config.h"
2020#include "io.h"
21#include "labsw/ep0.h"
22
23
24int local = 1;
25
26
27#define DEBOUNCE_CYCLES 10
28
29
30#define IS_ON(ch) (CH##ch##_RELAY || !CH##ch##_OPT)
31
32#define LED_R_COLOR_R 1
33#define LED_R_COLOR_G 0
34#define LED_R_COLOR_OFF 0
35#define LED_G_COLOR_R 0
36#define LED_G_COLOR_G 1
37#define LED_G_COLOR_OFF 0
38
39#define LED(ch, color) \
40    do { \
41        LED_##ch##_R = LED_R_COLOR_##color; \
42        LED_##ch##_G = LED_G_COLOR_##color; \
43    } while (0)
44
45#define TURN(ch, on) \
46    do { \
47        CH##ch##_RELAY = on; \
48        CH##ch##_OPT = !on; \
49        if (on) \
50            LED(CH##ch, R); \
51        else \
52            LED(CH##ch, G); \
53    } while (0)
2154
2255
2356static void init_io(void)
...... 
2659    P1SKIP = 0xff;
2760    P2SKIP = 0xff;
2861
62    /* @@@ we need this while using the boot loader of cntr */
63    P0MDOUT = 0;
64    P1MDOUT = 0;
65    P2MDOUT = 0;
66
2967    LED_MAIN_R_MODE |= 1 << LED_MAIN_R_BIT;
3068    LED_MAIN_G_MODE |= 1 << LED_MAIN_G_BIT;
3169    LED_CH1_R_MODE |= 1 << LED_CH1_R_BIT;
3270    LED_CH1_G_MODE |= 1 << LED_CH1_G_BIT;
3371    LED_CH2_R_MODE |= 1 << LED_CH2_R_BIT;
3472    LED_CH2_G_MODE |= 1 << LED_CH2_G_BIT;
73
3574    CH1_RELAY = 0;
3675    CH2_RELAY = 0;
3776    CH1_RELAY_MODE |= 1 << CH1_RELAY_BIT;
3877    CH2_RELAY_MODE |= 1 << CH2_RELAY_BIT;
39
40    /* @@@ we need this while using the boot loader of cntr */
41    CH1_OPT_MODE &= ~(1 << CH1_OPT_BIT);
42    CH2_OPT_MODE &= ~(1 << CH2_OPT_BIT);
4378}
4479
4580
4681void main(void)
4782{
83    int debounce_main = 0, last_main = 0, but_main = 0;
84    int debounce_ch1 = 0, last_ch1 = 0, but_ch1 = 0;
85    int debounce_ch2 = 0, last_ch2 = 0, but_ch2 = 0;
4886    init_io();
4987
5088    usb_init();
51// ep0_init();
89    ep0_init();
90
91    LED(MAIN, G);
92    TURN(1, 0);
93    TURN(2, 0);
5294
5395    while (1) {
54        if (!BUT_MAIN) {
55            LED_MAIN_R = 1;
56            LED_MAIN_G = 0;
57        } else {
58            LED_MAIN_R = 0;
59            LED_MAIN_G = 1;
96        if (debounce_main)
97            debounce_main--;
98        else {
99            last_main = but_main;
100            but_main = !BUT_MAIN;
101            if (last_main != but_main)
102                debounce_main = DEBOUNCE_CYCLES;
60103        }
61        if (!BUT_CH1) {
62            LED_CH1_R = 1;
63            LED_CH1_G = 0;
64            CH1_RELAY = 1;
65            CH1_OPT = 0;
66        } else {
67            LED_CH1_R = 0;
68            LED_CH1_G = 1;
69            CH1_RELAY = 0;
70            CH1_OPT = 1;
104
105        if (debounce_ch1)
106            debounce_ch1--;
107        else {
108            last_ch1 = but_ch1;
109            but_ch1 = !BUT_CH1;
110            if (last_ch1 != but_ch1)
111                debounce_ch1 = DEBOUNCE_CYCLES;
112        }
113
114        if (debounce_ch2)
115            debounce_ch2--;
116        else {
117            last_ch2 = but_ch2;
118            but_ch2 = !BUT_CH2;
119            if (last_ch2 != but_ch2)
120                debounce_ch2 = DEBOUNCE_CYCLES;
71121        }
72        if (!BUT_CH2) {
73            LED_CH2_R = 1;
74            LED_CH2_G = 0;
75            CH2_RELAY = 1;
76            CH2_OPT = 0;
77        } else {
78            LED_CH2_R = 0;
79            LED_CH2_G = 1;
80            CH2_RELAY = 0;
81            CH2_OPT = 1;
122
123        if (but_main && !last_main) {
124            if (local) {
125                TURN(1, 0);
126                TURN(2, 0);
127            }
128            local = 1;
129        }
130
131        if (local) {
132            LED(MAIN, G);
133            if (IS_ON(1))
134                TURN(1, 1);
135            else
136                TURN(1, 0);
137            if (IS_ON(2))
138                TURN(2, 1);
139            else
140                TURN(2, 0);
141        }
142
143        if (local) {
144            if (but_ch1 && !last_ch1)
145                TURN(1, !IS_ON(1));
146            if (but_ch2 && !last_ch2)
147                TURN(2, !IS_ON(2));
82148        }
149
83150        usb_poll();
84151    }
85152}
labsw/fw/usb-id.h
1/*
2 * labsw/usb-id.h - USB vendor and product ID
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#ifndef USB_ID_H
15#define USB_ID_H
16
17/*
18 * Platform-specific settings
19 *
20 * USB_VENDOR = Qi Hardware
21 * USB_PRODUCT = 7ab5
22 *
23 * 7ab5 is "LABS" in "leet", http://en.wikipedia.org/wiki/Leet
24 */
25
26#define USB_VENDOR 0x20b7 /* Qi Hardware */
27#define USB_PRODUCT 0x7ab5 /* Lab Switch */
28
29#endif /* !USB_ID_H */

Archive Download the corresponding diff file

Branches:
master



interactive