source: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/SAMD21_USBDevice.h@ 224

Last change on this file since 224 was 224, checked in by ertl-honda, 8 years ago

1.7.10のファイルに更新

File size: 9.5 KB
Line 
1/*
2 Copyright (c) 2015 Arduino LLC. All right reserved.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 See the GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18/*
19**Modified 04/04/2016 by Arduino.org development team
20*/
21
22#pragma once
23
24#include <Arduino.h>
25
26#include <stdlib.h>
27#include <stdio.h>
28#include <stdint.h>
29
30typedef uint8_t ep_t;
31
32class USBDevice_SAMD21G18x {
33public:
34 USBDevice_SAMD21G18x() : usb(USB->DEVICE) {
35 // Empty
36 }
37
38 // USB Device function mapping
39 // ---------------------------
40
41 // Reset USB Device
42 void reset();
43
44 // Enable
45 inline void enable() { usb.CTRLA.bit.ENABLE = 1; }
46 inline void disable() { usb.CTRLA.bit.ENABLE = 0; }
47
48 // USB mode (device/host)
49 inline void setUSBDeviceMode() { usb.CTRLA.bit.MODE = USB_CTRLA_MODE_DEVICE_Val; }
50 inline void setUSBHostMode() { usb.CTRLA.bit.MODE = USB_CTRLA_MODE_HOST_Val; }
51
52 inline void runInStandby() { usb.CTRLA.bit.RUNSTDBY = 1; }
53 inline void noRunInStandby() { usb.CTRLA.bit.RUNSTDBY = 0; }
54
55 // USB speed
56 inline void setFullSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_0_Val; }
57 inline void setLowSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_1_Val; }
58 inline void setHiSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_2_Val; }
59 inline void setHiSpeedTestMode() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_3_Val; }
60
61 // Authorize attach if Vbus is present
62 inline void attach() { usb.CTRLB.bit.DETACH = 0; }
63 inline void detach() { usb.CTRLB.bit.DETACH = 1; }
64
65 // USB Interrupts
66 inline bool isEndOfResetInterrupt() { return usb.INTFLAG.bit.EORST; }
67 inline void ackEndOfResetInterrupt() { usb.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; }
68 inline void enableEndOfResetInterrupt() { usb.INTENSET.bit.EORST = 1; }
69 inline void disableEndOfResetInterrupt() { usb.INTENCLR.bit.EORST = 1; }
70
71 inline bool isStartOfFrameInterrupt() { return usb.INTFLAG.bit.SOF; }
72 inline void ackStartOfFrameInterrupt() { usb.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; }
73 inline void enableStartOfFrameInterrupt() { usb.INTENSET.bit.SOF = 1; }
74 inline void disableStartOfFrameInterrupt() { usb.INTENCLR.bit.SOF = 1; }
75
76 // USB Address
77 inline void setAddress(uint32_t addr) { usb.DADD.bit.DADD = addr; usb.DADD.bit.ADDEN = 1; }
78 inline void unsetAddress() { usb.DADD.bit.DADD = 0; usb.DADD.bit.ADDEN = 0; }
79
80 // Frame number
81 inline uint16_t frameNumber() { return usb.FNUM.bit.FNUM; }
82
83 // Load calibration values
84 void calibrate();
85
86 // USB Device Endpoints function mapping
87 // -------------------------------------
88
89 // Config
90 inline void epBank0SetType(ep_t ep, uint8_t type) { usb.DeviceEndpoint[ep].EPCFG.bit.EPTYPE0 = type; }
91 inline void epBank1SetType(ep_t ep, uint8_t type) { usb.DeviceEndpoint[ep].EPCFG.bit.EPTYPE1 = type; }
92
93 // Interrupts
94 inline uint16_t epInterruptSummary() { return usb.EPINTSMRY.reg; }
95
96 inline bool epBank0IsSetupReceived(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.RXSTP; }
97 inline bool epBank0IsStalled(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.STALL0; }
98 inline bool epBank1IsStalled(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.STALL1; }
99 inline bool epBank0IsTransferComplete(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRCPT0; }
100 inline bool epBank1IsTransferComplete(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRCPT1; }
101
102 inline void epBank0AckSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP; }
103 inline void epBank0AckStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL(1); }
104 inline void epBank1AckStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL(2); }
105 inline void epBank0AckTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT(1); }
106 inline void epBank1AckTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT(2); }
107
108 inline void epBank0EnableSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.RXSTP = 1; }
109 inline void epBank0EnableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.STALL0 = 1; }
110 inline void epBank1EnableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.STALL1 = 1; }
111 inline void epBank0EnableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRCPT0 = 1; }
112 inline void epBank1EnableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRCPT1 = 1; }
113
114 inline void epBank0DisableSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.RXSTP = 1; }
115 inline void epBank0DisableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.STALL0 = 1; }
116 inline void epBank1DisableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.STALL1 = 1; }
117 inline void epBank0DisableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRCPT0 = 1; }
118 inline void epBank1DisableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRCPT1 = 1; }
119
120 // Status
121 inline bool epBank0IsReady(ep_t ep) { return usb.DeviceEndpoint[ep].EPSTATUS.bit.BK0RDY; }
122 inline bool epBank1IsReady(ep_t ep) { return usb.DeviceEndpoint[ep].EPSTATUS.bit.BK1RDY; }
123 inline void epBank0SetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.BK0RDY = 1; }
124 inline void epBank1SetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.BK1RDY = 1; }
125 inline void epBank0ResetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.BK0RDY = 1; }
126 inline void epBank1ResetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.BK1RDY = 1; }
127
128 inline void epBank0SetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.STALLRQ0 = 1; }
129 inline void epBank1SetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.STALLRQ1 = 1; }
130 inline void epBank0ResetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.STALLRQ0 = 1; }
131 inline void epBank1ResetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.STALLRQ1 = 1; }
132
133 // Packet
134 inline uint16_t epBank0ByteCount(ep_t ep) { return EP[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT; }
135 inline uint16_t epBank1ByteCount(ep_t ep) { return EP[ep].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT; }
136 inline void epBank0SetByteCount(ep_t ep, uint16_t bc) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = bc; }
137 inline void epBank1SetByteCount(ep_t ep, uint16_t bc) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = bc; }
138 inline void epBank0SetMultiPacketSize(ep_t ep, uint16_t s) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = s; }
139 inline void epBank1SetMultiPacketSize(ep_t ep, uint16_t s) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = s; }
140
141 inline void epBank0SetAddress(ep_t ep, void *addr) { EP[ep].DeviceDescBank[0].ADDR.reg = (uint32_t)addr; }
142 inline void epBank1SetAddress(ep_t ep, void *addr) { EP[ep].DeviceDescBank[1].ADDR.reg = (uint32_t)addr; }
143 inline void epBank0SetSize(ep_t ep, uint16_t size) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.SIZE = EP_PCKSIZE_SIZE(size); }
144 inline void epBank1SetSize(ep_t ep, uint16_t size) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.SIZE = EP_PCKSIZE_SIZE(size); }
145 inline uint8_t EP_PCKSIZE_SIZE(uint16_t size) {
146 switch (size) {
147 case 8: return 0;
148 case 16: return 1;
149 case 32: return 2;
150 case 64: return 3;
151 case 128: return 4;
152 case 256: return 5;
153 case 512: return 6;
154 case 1023: return 7;
155 default: return 0;
156 }
157 }
158
159 inline void epBank0DisableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.AUTO_ZLP = 0; }
160 inline void epBank1DisableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = 0; }
161 inline void epBank0EnableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.AUTO_ZLP = 1; }
162 inline void epBank1EnableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = 1; }
163
164private:
165 // USB Device registers
166 UsbDevice &usb;
167
168 // Endpoints descriptors table
169 __attribute__((__aligned__(4))) UsbDeviceDescriptor EP[USB_EPT_NUM];
170};
171
172void USBDevice_SAMD21G18x::reset() {
173 usb.CTRLA.bit.SWRST = 1;
174 memset(EP, 0, sizeof(EP));
175 while (usb.SYNCBUSY.bit.SWRST) {}
176 usb.DESCADD.reg = (uint32_t)(&EP);
177}
178
179void USBDevice_SAMD21G18x::calibrate() {
180 // Load Pad Calibration data from non-volatile memory
181 uint32_t *pad_transn_p = (uint32_t *) USB_FUSES_TRANSN_ADDR;
182 uint32_t *pad_transp_p = (uint32_t *) USB_FUSES_TRANSP_ADDR;
183 uint32_t *pad_trim_p = (uint32_t *) USB_FUSES_TRIM_ADDR;
184
185 uint32_t pad_transn = (*pad_transn_p & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos;
186 uint32_t pad_transp = (*pad_transp_p & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos;
187 uint32_t pad_trim = (*pad_trim_p & USB_FUSES_TRIM_Msk ) >> USB_FUSES_TRIM_Pos;
188
189 if (pad_transn == 0x1F) // maximum value (31)
190 pad_transn = 5;
191 if (pad_transp == 0x1F) // maximum value (31)
192 pad_transp = 29;
193 if (pad_trim == 0x7) // maximum value (7)
194 pad_trim = 3;
195
196 usb.PADCAL.bit.TRANSN = pad_transn;
197 usb.PADCAL.bit.TRANSP = pad_transp;
198 usb.PADCAL.bit.TRIM = pad_trim;
199}
200
Note: See TracBrowser for help on using the repository browser.