USB Host Shield 2.0
AMBX.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2021 Aran Vink. All rights reserved.
2 
3  This software may be distributed and modified under the terms of the GNU
4  General Public License version 2 (GPL2) as published by the Free Software
5  Foundation and appearing in the file GPL2.TXT included in the packaging of
6  this file. Please note that GPL2 Section 2[b] requires that all works based
7  on this software must also be made publicly available under the terms of
8  the GPL2 ("Copyleft").
9 
10  Contact information
11  -------------------
12 
13  Aran Vink
14  e-mail : aranvink@gmail.com
15  */
16 
17 #include "AMBX.h"
18 // To enable serial debugging see "settings.h"
19 //#define EXTRADEBUG // Uncomment to get even more debugging data
20 
22 pUsb(p), // pointer to USB class instance - mandatory
23 bAddress(0) // device address - mandatory
24 {
25  for(uint8_t i = 0; i < AMBX_MAX_ENDPOINTS; i++) {
26  epInfo[i].epAddr = 0;
27  epInfo[i].maxPktSize = (i) ? 0 : 8;
28  epInfo[i].bmSndToggle = 0;
29  epInfo[i].bmRcvToggle = 0;
31  }
32 
33  if(pUsb) // register in USB subsystem
34  pUsb->RegisterDeviceClass(this); //set devConfig[] entry
35 }
36 
37 uint8_t AMBX::Init(uint8_t parent, uint8_t port, bool lowspeed) {
38  uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
39  USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
40  uint8_t rcode;
41  UsbDevice *p = NULL;
42  EpInfo *oldep_ptr = NULL;
43  uint16_t PID;
44  uint16_t VID;
45 
46  // get memory address of USB device address pool
47  AddressPool &addrPool = pUsb->GetAddressPool();
48 #ifdef EXTRADEBUG
49  Notify(PSTR("\r\nAMBX Init"), 0x80);
50 #endif
51  // check if address has already been assigned to an instance
52  if(bAddress) {
53 #ifdef DEBUG_USB_HOST
54  Notify(PSTR("\r\nAddress in use"), 0x80);
55 #endif
57  }
58 
59  // Get pointer to pseudo device with address 0 assigned
60  p = addrPool.GetUsbDevicePtr(0);
61 
62  if(!p) {
63 #ifdef DEBUG_USB_HOST
64  Notify(PSTR("\r\nAddress not found"), 0x80);
65 #endif
67  }
68 
69  if(!p->epinfo) {
70 #ifdef DEBUG_USB_HOST
71  Notify(PSTR("\r\nepinfo is null"), 0x80);
72 #endif
74  }
75 
76  // Save old pointer to EP_RECORD of address 0
77  oldep_ptr = p->epinfo;
78 
79  // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
80  p->epinfo = epInfo;
81 
82  p->lowspeed = lowspeed;
83 
84  // Get device descriptor
85  rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
86  // Restore p->epinfo
87  p->epinfo = oldep_ptr;
88 
89  if(rcode)
90  goto FailGetDevDescr;
91 
92  VID = udd->idVendor;
93  PID = udd->idProduct;
94 
95  if(VID != AMBX_VID || (PID != AMBX_PID))
96  goto FailUnknownDevice;
97 
98  // Allocate new address according to device class
99  bAddress = addrPool.AllocAddress(parent, false, port);
100 
101  if(!bAddress)
103 
104  // Extract Max Packet Size from device descriptor
105  epInfo[0].maxPktSize = udd->bMaxPacketSize0;
106 
107  // Assign new address to the device
108  rcode = pUsb->setAddr(0, 0, bAddress);
109  if(rcode) {
110  p->lowspeed = false;
111  addrPool.FreeAddress(bAddress);
112  bAddress = 0;
113 #ifdef DEBUG_USB_HOST
114  Notify(PSTR("\r\nsetAddr: "), 0x80);
115  D_PrintHex<uint8_t > (rcode, 0x80);
116 #endif
117  return rcode;
118  }
119 #ifdef EXTRADEBUG
120  Notify(PSTR("\r\nAddr: "), 0x80);
121  D_PrintHex<uint8_t > (bAddress, 0x80);
122 #endif
123 
124  p->lowspeed = false;
125 
126  //get pointer to assigned address record
127  p = addrPool.GetUsbDevicePtr(bAddress);
128  if(!p)
130 
131  p->lowspeed = lowspeed;
132 
133  // Assign epInfo to epinfo pointer - only EP0 is known
134  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
135  if(rcode)
136  goto FailSetDevTblEntry;
137 
138 
139  /* The application will work in reduced host mode, so we can save program and data
140  memory space. After verifying the PID and VID we will use known values for the
141  configuration values for device, interface, endpoints for the AMBX Controller */
142 
143  /* Initialize data structures for endpoints of device */
144  epInfo[ AMBX_OUTPUT_PIPE ].epAddr = AMBX_ENDPOINT_OUT; // AMBX output endpoint
146  epInfo[ AMBX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
150 
151  rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
152  if(rcode)
153  goto FailSetDevTblEntry;
154 
155  delay(200); //Give time for address change
156 
157  //For some reason this is need to make it work
158  rcode = pUsb->setConf(bAddress, epInfo[ AMBX_CONTROL_PIPE ].epAddr, 1);
159  if(rcode)
160  goto FailSetConfDescr;
161 
162  if(PID == AMBX_PID || PID) {
163  AMBXConnected = true;
164  }
165  onInit();
166 
167  Notify(PSTR("\r\n"), 0x80);
168  return 0; // Successful configuration
169 
170  /* Diagnostic messages */
171 FailGetDevDescr:
172 #ifdef DEBUG_USB_HOST
174  goto Fail;
175 #endif
176 
177 FailSetDevTblEntry:
178 #ifdef DEBUG_USB_HOST
180  goto Fail;
181 #endif
182 
183 FailSetConfDescr:
184 #ifdef DEBUG_USB_HOST
186 #endif
187  goto Fail;
188 
189 FailUnknownDevice:
190 #ifdef DEBUG_USB_HOST
191  NotifyFailUnknownDevice(VID, PID);
192 #endif
194 
195 Fail:
196 #ifdef DEBUG_USB_HOST
197  Notify(PSTR("\r\nAMBX Init Failed, error code: "), 0x80);
198  NotifyFail(rcode);
199 #endif
200  Release();
201  return rcode;
202 }
203 
204 /* Performs a cleanup after failed Init() attempt */
205 uint8_t AMBX::Release() {
206  AMBXConnected = false;
208  bAddress = 0;
209  return 0;
210 }
211 
212 uint8_t AMBX::Poll() {
213  return 0;
214 }
215 
216 void AMBX::Light_Command(uint8_t *data, uint16_t nbytes) {
217  #ifdef DEBUG_USB_HOST
218  Notify(PSTR("\r\nLight command "), 0x80);
219  #endif
220  pUsb->outTransfer(bAddress, epInfo[ AMBX_OUTPUT_PIPE ].epAddr, nbytes, data);
221 }
222 
223 void AMBX::setLight(uint8_t ambx_light, uint8_t r, uint8_t g, uint8_t b) {
224  writeBuf[0] = AMBX_PREFIX_COMMAND;
225  writeBuf[1] = ambx_light;
226  writeBuf[2] = AMBX_SET_COLOR_COMMAND;
227  writeBuf[3] = r;
228  writeBuf[4] = g;
229  writeBuf[5] = b;
230  Light_Command(writeBuf, AMBX_LIGHT_COMMAND_BUFFER_SIZE);
231 }
232 
233 void AMBX::setLight(AmbxLightsEnum ambx_light, AmbxColorsEnum color) { // Use this to set the Light with Color using the predefined in "AMBXEnums.h"
234  setLight(ambx_light, (uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
235 }
236 
237 void AMBX::setAllLights(AmbxColorsEnum color) { // Use this to set the Color using the predefined colors in "AMBXEnums.h"
238  setLight(Sidelight_left, (uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
239  setLight(Sidelight_right, (uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
240  setLight(Wallwasher_center, (uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
241  setLight(Wallwasher_left, (uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
242  setLight(Wallwasher_right, (uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
243 }
244 
245 void AMBX::onInit() {
246  #ifdef DEBUG_USB_HOST
247  Notify(PSTR("\r\nOnInit execute "), 0x80);
248  #endif
249  if(pFuncOnInit)
250  pFuncOnInit(); // Call the user function
251 }
#define AMBX_MAX_ENDPOINTS
Definition: AMBX.h:56
#define AMBX_EP_MAXPKTSIZE
Definition: AMBX.h:24
#define AMBX_VID
Definition: AMBX.h:32
#define AMBX_PID
Definition: AMBX.h:33
#define AMBX_ENDPOINT_OUT
Definition: AMBX.h:37
#define AMBX_OUTPUT_PIPE
Definition: AMBX.h:28
#define AMBX_LIGHT_COMMAND_BUFFER_SIZE
Definition: AMBX.h:53
#define AMBX_CONTROL_PIPE
Definition: AMBX.h:27
#define AMBX_SET_COLOR_COMMAND
Definition: AMBX.h:42
#define AMBX_PREFIX_COMMAND
Definition: AMBX.h:41
AmbxColorsEnum
Definition: AMBXEnums.h:21
AmbxLightsEnum
Definition: AMBXEnums.h:30
@ Sidelight_left
Definition: AMBXEnums.h:31
@ Sidelight_right
Definition: AMBXEnums.h:32
@ Wallwasher_left
Definition: AMBXEnums.h:33
@ Wallwasher_right
Definition: AMBXEnums.h:35
@ Wallwasher_center
Definition: AMBXEnums.h:34
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:95
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
Definition: UsbCore.h:100
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
Definition: UsbCore.h:92
#define USB_ERROR_EPINFO_IS_NULL
Definition: UsbCore.h:98
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
Definition: UsbCore.h:97
#define USB_NAK_MAX_POWER
Definition: address.h:34
#define USB_NAK_NOWAIT
Definition: address.h:36
uint8_t Poll()
Definition: AMBX.cpp:212
uint8_t Release()
Definition: AMBX.cpp:205
EpInfo epInfo[AMBX_MAX_ENDPOINTS]
Definition: AMBX.h:144
bool AMBXConnected
Definition: AMBX.h:133
USB * pUsb
Definition: AMBX.h:140
AMBX(USB *pUsb)
Definition: AMBX.cpp:21
uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
Definition: AMBX.cpp:37
uint8_t bAddress
Definition: AMBX.h:142
void setAllLights(AmbxColorsEnum color)
Definition: AMBX.cpp:237
void setLight(uint8_t ambx_light, uint8_t r, uint8_t g, uint8_t b)
Definition: AMBX.cpp:223
virtual void FreeAddress(uint8_t addr)=0
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub=false, uint8_t port=0)=0
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)=0
Definition: UsbCore.h:212
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr)
defined(USB_METHODS_INLINE)
Definition: Usb.cpp:801
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value)
Definition: Usb.cpp:845
uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr)
Definition: Usb.cpp:836
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
Definition: UsbCore.h:232
AddressPool & GetAddressPool()
Definition: UsbCore.h:228
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr)
Definition: Usb.cpp:64
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
Definition: Usb.cpp:303
#define NotifyFailSetConfDescr(...)
Definition: message.h:60
#define NotifyFailUnknownDevice(...)
Definition: message.h:61
#define NotifyFail(...)
Definition: message.h:62
#define Notify(...)
Definition: message.h:51
#define NotifyFailSetDevTblEntry(...)
Definition: message.h:58
#define NotifyFailGetDevDescr(...)
Definition: message.h:57
Definition: address.h:39
uint8_t epAttribs
Definition: address.h:44
uint8_t bmNakPower
Definition: address.h:49
uint8_t bmRcvToggle
Definition: address.h:48
uint8_t epAddr
Definition: address.h:40
uint8_t maxPktSize
Definition: address.h:41
uint8_t bmSndToggle
Definition: address.h:47
EpInfo * epinfo
Definition: address.h:83
bool lowspeed
Definition: address.h:86
#define USB_TRANSFER_TYPE_INTERRUPT
Definition: usb_ch9.h:93
#define PSTR(str)