|
- import codecs
- import construct
- import importlib
- import sys
-
- from usb_protocol.types.descriptors.standard import ConfigurationDescriptor, DescriptorFormat, EndpointDescriptor, InterfaceDescriptor, StandardDescriptorNumbers
- from string import Template
-
- # Note this file is under the following copyright:
- copyright = '''/*-
- * Copyright 2022 John-Mark Gurney.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. If you are STMicroelectronics N.V., one of it's subsidiaries, a
- * subsidiary of an owner of STMicroelectronics N.V., or an employee,
- * contractor, or agent of any of the preceeding entities, you are not
- * allowed to use this code, in either source or binary forms.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
- '''
-
- UniDesc = DescriptorFormat(
- "bLength" / construct.Int8ul,
- "bDescriptorType" / construct.Int8ul,
- )
-
- descparsers = {
- StandardDescriptorNumbers.INTERFACE: InterfaceDescriptor.parse,
- StandardDescriptorNumbers.ENDPOINT: EndpointDescriptor.parse,
- }
-
- def getepdescs(confdesc):
- ret = []
-
- lastdesc = ConfigurationDescriptor.parse(confdesc)
- pos = lastdesc.bLength
-
- while pos < len(confdesc):
- descparser = descparsers.get(confdesc[pos + 1], UniDesc.parse)
- desc = descparser(confdesc[pos:])
-
- if confdesc[pos + 1] == StandardDescriptorNumbers.ENDPOINT:
- ret.append(desc)
-
- lastdesc = desc
-
- pos += lastdesc.bLength
-
- return ret
-
- if __name__ == '__main__':
- usbname = sys.argv[1]
-
- mod = importlib.import_module(usbname)
- collection = mod.collection
-
- sorteddesc = sorted(collection)
- descs = { (x, y): z for x, y, z in collection }
-
- for value, index, raw in sorteddesc:
- print(int(value), repr(index), codecs.encode(raw, 'hex'))
-
- p = lambda *args, **kwargs: print(*args, **kwargs, file=fp)
-
- with open('%s_base.h' % usbname, 'w') as fp:
- p(Template('''${copyright}
-
- #include <usbd_core.h>
-
- extern USBD_ClassTypeDef ${usbname}_def;
-
- void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
-
- void ${usbname}_init(void);
- void ${usbname}_epopen(USBD_HandleTypeDef *pdev);
- void ${usbname}_epclose(USBD_HandleTypeDef *pdev);
- ''').substitute(locals()))
-
- with open('%s_base.c' % usbname, 'w') as fp:
- descstrings = '\n'.join('const uint8_t desc_%d_%d[] = { %s };' % (x, y, ', '.join(hex(w) for w in z)) for x, y, z in sorteddesc)
- descstructs = '\n'.join('\t{ .type = %d, .subnumb = %d, .datalen = %d, .data = desc_%d_%d },' % (x, y, len(z), x, y) for x, y, z in sorteddesc)
-
- epdescs = getepdescs(descs[(2, 0)])
- print(repr(epdescs))
- epopencode = '\n\t'.join(sum(([
- 'USBD_LL_OpenEP(pdev, %#x, %d, %d);' % (ep.bEndpointAddress, ep.bmAttributes & 0x3, ep.wMaxPacketSize),
- 'pdev->%s[%#x & 0xFU].is_used = 1;' % ('ep_in' if ep.bEndpointAddress & 0x80 else 'ep_out', ep.bEndpointAddress)
- ] for ep in epdescs), []))
- epclosecode = '\n\t'.join(sum(([
- 'USBD_LL_CloseEP(pdev, %#x);' % (ep.bEndpointAddress),
- 'pdev->%s[%#x & 0xFU].is_used = 0;' % ('ep_in' if ep.bEndpointAddress & 0x80 else 'ep_out', ep.bEndpointAddress)
- ] for ep in epdescs), []))
- print(repr(epopencode))
-
- p(Template('''${copyright}
- #include "${usbname}_base.h"
-
- #include <sysinit.h>
-
- #include <usbd_core.h>
- /* #include <usbd_desc.h> */
- /* #include <usbd_conf.h> */
-
- static USBD_HandleTypeDef usbd_inst;
-
- void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
-
- ${descstrings}
-
- static const struct {
- uint8_t type;
- uint8_t subnumb;
- uint8_t datalen;
- const uint8_t *data;
- } descriptors[] = {
- ${descstructs}
- };
-
- void
- USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
- {
- uint8_t const *buf;
- uint8_t buflen;
- uint8_t type, subnumb;
- int i;
-
- type = req->wValue >> 8;
- subnumb = req->wValue & 0xff;
-
- for (i = 0; i < sizeof descriptors / sizeof *descriptors; i++) {
- if (descriptors[i].type == type && descriptors[i].subnumb == subnumb) {
- buf = descriptors[i].data;
- buflen = descriptors[i].datalen;
- if ((buflen != 0U) && (req->wLength != 0U)) {
- buflen = MIN(buflen, req->wLength);
- USBD_CtlSendData(pdev, (uint8_t *)(uintptr_t)buf, buflen);
- }
-
- if(req->wLength == 0U) {
- USBD_CtlSendStatus(pdev);
- }
- return;
- }
- }
-
- USBD_CtlError(pdev , req);
- }
-
- void
- ${usbname}_init(void)
- {
-
- if (USBD_Init(&usbd_inst, NULL/*Desc, not used*/, DEVICE_FS) != USBD_OK)
- Error_Handler();
-
- if (USBD_RegisterClass(&usbd_inst, &${usbname}_def) != USBD_OK)
- Error_Handler();
-
- if (USBD_Start(&usbd_inst) != USBD_OK)
- Error_Handler();
- }
- SYSINIT_VF(${usbname}_init, SI_SUB_USB, SI_ORDER_MIDDLE, ${usbname}_init);
-
- void
- ${usbname}_epopen(USBD_HandleTypeDef *pdev)
- {
-
- ${epopencode}
- }
-
- void
- ${usbname}_epclose(USBD_HandleTypeDef *pdev)
- {
-
- ${epclosecode}
- }
-
- extern PCD_HandleTypeDef hpcd_USB_FS;
- void
- USB_LP_IRQHandler(void)
- {
-
- HAL_PCD_IRQHandler(&hpcd_USB_FS);
- }
-
- static volatile uint32_t holding;
- void
- Error_Handler(void)
- {
-
- #if 0
- debug_printf("error_handler\\n");
- #endif
- for (;;) holding++;
- }''').substitute(locals()))
-
- print('enda')
|