Compare commits

...

10 Commits

  1. 1
      .gitignore
  2. 4
      backend/.gitignore
  3. 1
      backend/MANIFEST.in
  4. 58
      backend/container.py
  5. 22
      backend/monsun_backend/__init__.py
  6. 20
      backend/monsun_backend/command_endpoint.py
  7. 102
      backend/monsun_backend/command_execution.py
  8. 0
      backend/monsun_backend/commands.py
  9. 56
      backend/monsun_backend/container.py
  10. 2
      backend/monsun_backend/defaults/config.yml
  11. 27
      backend/monsun_backend/util.py
  12. 4
      backend/requirements.txt
  13. 3
      backend/runsever.py
  14. 19
      backend/setup.py
  15. 3
      backend/wsgi.py
  16. 85
      ble-client-seq.puml
  17. 7
      config_example.yml
  18. 29
      download.py
  19. 38
      nucleo-wb55-ble/.mxproject
  20. 8
      nucleo-wb55-ble/.project
  21. 2
      nucleo-wb55-ble/Core/Inc/stm32wbxx_hal_conf.h
  22. 1
      nucleo-wb55-ble/Core/Inc/stm32wbxx_it.h
  23. 188
      nucleo-wb55-ble/Core/Src/main.c
  24. 16
      nucleo-wb55-ble/Core/Src/stm32wbxx_it.c
  25. 994
      nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_hal_pcd.h
  26. 91
      nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_hal_pcd_ex.h
  27. 237
      nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_ll_usb.h
  28. 2162
      nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c
  29. 336
      nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c
  30. 849
      nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c
  31. 175
      nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h
  32. 968
      nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
  33. 158
      nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h
  34. 103
      nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h
  35. 420
      nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h
  36. 114
      nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h
  37. 694
      nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c
  38. 948
      nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c
  39. 226
      nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c
  40. 99
      nucleo-wb55-ble/USB_Device/App/usb_device.c
  41. 105
      nucleo-wb55-ble/USB_Device/App/usb_device.h
  42. 338
      nucleo-wb55-ble/USB_Device/App/usbd_cdc_if.c
  43. 134
      nucleo-wb55-ble/USB_Device/App/usbd_cdc_if.h
  44. 396
      nucleo-wb55-ble/USB_Device/App/usbd_desc.c
  45. 145
      nucleo-wb55-ble/USB_Device/App/usbd_desc.h
  46. 810
      nucleo-wb55-ble/USB_Device/Target/usbd_conf.c
  47. 176
      nucleo-wb55-ble/USB_Device/Target/usbd_conf.h
  48. 28
      nucleo-wb55-ble/commands/dispatch.cpp
  49. 15
      nucleo-wb55-ble/commands/dispatch.hpp
  50. 77
      nucleo-wb55-ble/nucleo-wb55-ble.ioc
  51. 9
      nucleo-wb55-dongle-ble/Core/Src/main.c
  52. 24
      nucleo-wb55-dongle-ble/STM32_WPAN/App/app_ble.c
  53. 2
      nucleo-wb55-dongle-ble/STM32_WPAN/App/app_ble.h
  54. 203
      nucleo-wb55-dongle-ble/STM32_WPAN/App/p2p_client_app.c
  55. 2
      nucleo-wb55-dongle-ble/STM32_WPAN/App/p2p_client_app.h
  56. 40
      nucleo-wb55-dongle-ble/app/Command.hpp
  57. 16
      nucleo-wb55-dongle-ble/app/commands.hpp
  58. 1
      nucleo-wb55-dongle-ble/commands/GPCommand.cpp
  59. 0
      nucleo-wb55-dongle-ble/commands/GPCommand.hpp
  60. 32
      nucleo-wb55-dongle-ble/commands/dispatch.cpp
  61. 15
      nucleo-wb55-dongle-ble/commands/dispatch.hpp
  62. 25
      nucleo-wb55-dongle-ble/shared_commands/Command.hpp
  63. 0
      nucleo-wb55-dongle-ble/shared_commands/HeartbeatCommand.cpp
  64. 0
      nucleo-wb55-dongle-ble/shared_commands/HeartbeatCommand.hpp
  65. 0
      nucleo-wb55-dongle-ble/shared_commands/LedCommand.cpp
  66. 0
      nucleo-wb55-dongle-ble/shared_commands/LedCommand.hpp
  67. 0
      nucleo-wb55-dongle-ble/shared_commands/LogCommand.cpp
  68. 1
      nucleo-wb55-dongle-ble/shared_commands/LogCommand.hpp
  69. 0
      nucleo-wb55-dongle-ble/shared_commands/Notification.cpp
  70. 0
      nucleo-wb55-dongle-ble/shared_commands/Notification.hpp
  71. 0
      nucleo-wb55-dongle-ble/shared_commands/Request.cpp
  72. 0
      nucleo-wb55-dongle-ble/shared_commands/Request.hpp
  73. 0
      nucleo-wb55-dongle-ble/shared_commands/Response.cpp
  74. 0
      nucleo-wb55-dongle-ble/shared_commands/Response.hpp
  75. 0
      nucleo-wb55-dongle-ble/shared_commands/command_interpreter.c
  76. 6
      nucleo-wb55-dongle-ble/shared_commands/commands.h
  77. 24
      nucleo-wb55-dongle-ble/shared_commands/commands.hpp
  78. 33
      nucleo-wb55-dongle-ble/shared_commands/execute.cpp
  79. 13
      nucleo-wb55-dongle-ble/shared_commands/execute.hpp
  80. 3
      requirements.txt

1
.gitignore

@ -65,3 +65,4 @@ Release/
.vscode/
venv*/
*.pyc
config.yml

4
backend/.gitignore

@ -0,0 +1,4 @@
**/__pycache__/
build/
dist/
**/*.egg-info

1
backend/MANIFEST.in

@ -0,0 +1 @@
include monsun_backend/defaults/config.yml

58
backend/container.py

@ -1,58 +0,0 @@
from pathlib import Path
from typing import Dict
from typing import Optional
from dependency_injector import containers
from dependency_injector import providers
from flask_api import FlaskAPI
from serial import Serial
DEFAULTS_DIR = Path(__file__).parent / "defaults"
CONFIG_FILE = DEFAULTS_DIR / "config.yml"
class Container(containers.DeclarativeContainer):
config = providers.Configuration("config")
serial = providers.Factory(
Serial,
port=config.device_id.required(),
baudrate=config.baudrate.required(),
)
__container: Optional[Container] = None
def initialize_container(
config: Optional[Dict] = None,
config_file: Optional[Path] = None,
) -> Container:
global __container
if __container is not None:
raise RuntimeError("Container already initialized")
__container = Container()
__container.config.from_yaml(CONFIG_FILE)
if config is not None:
__container.config.from_dict(config)
if config_file is not None:
__container.config.from_yaml(config_file)
return __container
def init_app(app: FlaskAPI):
initialize_container(
config=app.config.get("DI_CONFIG"),
config_file=app.config.get("DI_CONFIG_FILE"),
)
def get_container() -> Container:
global __container
if __container is None:
raise RuntimeError("Container not initialized")
return __container

22
backend/__init__.py → backend/monsun_backend/__init__.py

@ -5,7 +5,12 @@ from flask_api import FlaskAPI
from . import command_endpoint
from . import command_execution
from . import container
__title__ = "monsun-backend"
__author__ = "Andreas Berthoud, Fabian Klein"
__version__ = "0.0.0"
__email__ = "andreasberthoud@gmail.com"
__copyright__ = f"2021 {__author__}"
def create_app() -> FlaskAPI:
@ -15,23 +20,30 @@ def create_app() -> FlaskAPI:
dictConfig(
{
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"default": {
"format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s",
},
},
"handlers": {
"wsgi": {
"console": {
"class": "logging.StreamHandler",
"stream": "ext://flask.logging.wsgi_errors_stream",
"formatter": "default",
"stream": "ext://sys.stdout",
},
},
"root": {"level": "NOTSET", "handlers": ["console"]},
"logger": {
"monsun_backend": {
"level": "DEBUG",
"propagate": "no",
},
},
"root": {"level": "DEBUG", "handlers": ["wsgi"]},
},
)
container.init_app(app)
# container.init_app(app)
if os.environ.get("WERKZEUG_RUN_MAIN") != "true":
# prevent from be called twice in debug mode

20
backend/command_endpoint.py → backend/monsun_backend/command_endpoint.py

@ -1,3 +1,5 @@
import logging
from flask import Response
from flask import blueprints
from flask import request
@ -8,12 +10,17 @@ from .commands import CommandId
from .commands import get_command_id_from_name
from .commands import get_request_class
_logger = logging.getLogger(__name__)
bp = blueprints.Blueprint("command", __name__)
@bp.route("/command", methods=["POST", "GET"])
def command():
@bp.route("/<role>/command", methods=["POST", "GET"])
def command(role: str):
logger = _logger.getChild(f"{role}/command")
arguments = dict(request.args)
logger.debug(f"arguments: {arguments}")
cmd = arguments.pop("cmd")
try:
@ -26,6 +33,13 @@ def command():
except Exception:
return Response(status=status.HTTP_400_BAD_REQUEST)
enqueue_command(command)
try:
enqueue_command(
role=role,
command=command,
)
except KeyError:
logger.error(f"role {role} does not exist")
return Response(status=status.HTTP_400_BAD_REQUEST)
return Response(status=status.HTTP_200_OK)

102
backend/command_execution.py → backend/monsun_backend/command_execution.py

@ -5,6 +5,7 @@ from enum import Enum
from multiprocessing import Process
from multiprocessing import Queue
from struct import unpack
from typing import Dict
from typing import List
from typing import Optional
from typing import Sequence
@ -12,17 +13,19 @@ from typing import Tuple
from serial import Serial
from backend.monsun_backend.util import log_function_call
from . import commands
from .commands import Command
from .commands import CommandId
from .commands import Request
from .commands import Response
from .container import get_container
from .container import initialize_container
from .container import get_initialize_container
_logger = logging.getLogger(__file__)
_command_queue: Queue = Queue()
_command_queue: Dict[str, Queue] = dict()
"""role name: command queue"""
class State(Enum):
@ -33,18 +36,24 @@ class State(Enum):
def worker_process(
role: str,
queue: Queue,
config,
):
logging.basicConfig(
level=logging.DEBUG,
format="[%(asctime)s] [%(name)-20s] [%(levelname)-8s] --- %(message)s",
)
logger = logging.getLogger("Command Loop")
root_logger = logging.getLogger(role)
root_logger.setLevel(logging.DEBUG)
logger = root_logger.getChild("worker_process")
logger.setLevel(logging.INFO)
initialize_container(config)
container = get_container()
container = get_initialize_container()
container.config.from_dict(
{
"role": role,
},
)
heartbeat_interval = container.config.heartbeat_interval()
serial_reconnection_wait_timeout = (
container.config.serial_reconnection_wait_timeout()
@ -58,6 +67,7 @@ def worker_process(
logger.info("connected with serial device")
connected = True
enter_fsm(
root_logger=root_logger,
serial=serial,
command_queue=queue,
heartbeat_interval=heartbeat_interval,
@ -71,11 +81,12 @@ def worker_process(
def enter_fsm(
root_logger: logging.Logger,
serial: Serial,
command_queue: Queue,
heartbeat_interval: float,
):
logger = logging.getLogger("FSM")
logger = root_logger.getChild("FSM")
state = State.executing_command
current_command: Optional[Command] = None
@ -113,7 +124,10 @@ def enter_fsm(
)
else:
request: Request = current_command
commands_, responses = receive(serial=serial)
commands_, responses = receive(
root_logger=root_logger,
serial=serial,
)
responses_received.extend(responses)
for command in commands_:
command_queue.put(command)
@ -146,7 +160,10 @@ def enter_fsm(
continue
elif state == State.receiving_command:
commands_, responses = receive(serial=serial)
commands_, responses = receive(
root_logger=root_logger,
serial=serial,
)
responses_received.extend(responses)
for command in commands_:
command_queue.put(command)
@ -167,14 +184,23 @@ def dequeue_command(
return None
def enqueue_command(command: Command):
_command_queue.put(command)
def enqueue_command(
role: str,
command: Command,
):
"""Add a command to the command queue
:param role: The role name
:param command: The command to enqueue
"""
_command_queue[role].put(command)
def receive(
root_logger: logging.Logger,
serial: Serial,
) -> Tuple[Sequence[Command], Sequence[Response]]:
logger = logging.getLogger("receive_and_log")
logger = root_logger.getChild("receive_and_log")
logger.setLevel(logging.INFO)
commands_received: List[Command] = list()
responses_received: List[Response] = list()
@ -185,9 +211,20 @@ def receive(
while bytes_read:
logger.debug(f"bytes: {bytes_read.hex()}")
command_id_int, data_length, _ = unpack(">BHB", bytes_read[:header_size])
payload = bytes(bytes_read[header_size : header_size + data_length])
stop_byte = bytes_read[header_size + data_length]
try:
command_id_int, data_length, _ = unpack(">BHB", bytes_read[:header_size])
payload = bytes(bytes_read[header_size : header_size + data_length])
stop_byte = bytes_read[header_size + data_length]
except IndexError:
# okay, something went wrong.
logger.error(
"There are less bytes than expected: "
f"Expected={header_size + data_length -1}, "
f"received={len(bytes_read)}",
)
logger.debug(f"bytes: {bytes_read.hex()}")
bytes_read = None
continue
try:
command_id = CommandId(command_id_int)
@ -222,24 +259,33 @@ def receive(
return commands_received, responses_received
_process: Optional[Process] = None
_process: Dict[str, Process] = dict()
"""role name: process"""
def _end_running_process():
if _process is not None:
_process.kill()
process: Process
for process in _process.values():
process.kill()
@log_function_call
def start_backgroup_process():
_logger.warning("start_backgroup_process called")
global _process
global _command_queue
container = get_initialize_container()
role_name: str
for role_name in container.config.roles():
_command_queue[role_name] = Queue()
_process[role_name] = Process(
target=worker_process,
args=(
role_name,
_command_queue[role_name],
),
)
_process[role_name].start()
_process = Process(
target=worker_process,
args=(
_command_queue,
get_container().config(),
),
)
_process.start()
atexit.register(_end_running_process)

0
backend/commands.py → backend/monsun_backend/commands.py

56
backend/monsun_backend/container.py

@ -0,0 +1,56 @@
import logging
from pathlib import Path
from pprint import pformat
from typing import Dict
from typing import Optional
from dependency_injector import containers
from dependency_injector import providers
from serial import Serial
from .util import log_function_call
DEFAULTS_DIR = Path(__file__).parent / "defaults"
CONFIG_FILE = DEFAULTS_DIR / "config.yml"
_logger = logging.getLogger(__name__)
class Container(containers.DeclarativeContainer):
config = providers.Configuration("config")
serial = providers.Factory(
Serial,
port=config.device_id[config.role].required(),
baudrate=config.baudrate.required(),
)
@log_function_call
def get_initialize_container(
config: Optional[Dict] = None,
config_file: Optional[Path] = None,
) -> Container:
logger = _logger.getChild("initialize_container")
logger.debug("initialize container...")
container = Container()
logger.debug(f"initialize container from config file: {CONFIG_FILE}")
container.config.from_yaml(CONFIG_FILE, required=True)
user_config = Path.cwd() / "config.yml"
if user_config.is_file():
logger.debug(f"initialize container from user config file: {user_config}")
container.config.from_yaml(user_config, required=True)
if config is not None:
logger.debug(f"initialize container with config: {config}")
container.config.from_dict(config)
if config_file is not None:
logger.debug(f"initialize container from config file: {config_file}")
container.config.from_yaml(config_file)
logger.debug(f"container config:\n{pformat(container.config())}")
return container

2
backend/defaults/config.yml → backend/monsun_backend/defaults/config.yml

@ -1,5 +1,3 @@
device_id: /dev/tty.usbmodem2067368F32521
# device_id: /dev/tty.usbmodem207E3283544E1
baudrate: 115200
header_size: 4
heartbeat_interval: 1

27
backend/monsun_backend/util.py

@ -0,0 +1,27 @@
import functools
import logging
function_call_logger = logging.getLogger("call")
# decorator
def log_function_call(func):
if logging.getLogger().level != logging.DEBUG:
return func
@functools.wraps(func)
def wrapper(*args, **kwargs):
function_call_logger.debug(
"calling {func}({arguments})".format(
func=func.__name__,
arguments=", ".join(
[str(value) for value in args]
+ [f"{key}={value}" for key, value in kwargs.items()],
),
),
)
return_val = func(*args, **kwargs)
function_call_logger.debug(f"{func.__name__}() returned {return_val}")
return return_val
return wrapper

4
backend/requirements.txt

@ -0,0 +1,4 @@
dependency-injector[yaml]>=4.34.0,<5
flask-api>=3.0.post1,<4
pyserial>=3.5,<4
uwsgi

3
backend/runsever.py

@ -1,3 +0,0 @@
from . import create_app
application = create_app()

19
backend/setup.py

@ -0,0 +1,19 @@
import setuptools
from monsun_backend import __author__
from monsun_backend import __email__
from monsun_backend import __version__
setuptools.setup(
name="monsun-backend",
version=__version__,
author=__author__,
author_email=__email__,
description="Monsun backend",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"Operating System :: OS Independent",
],
python_requires=">=3.7",
include_package_data=True,
)

3
backend/wsgi.py

@ -0,0 +1,3 @@
from monsun_backend import create_app
application = create_app()

85
ble-client-seq.puml

@ -0,0 +1,85 @@
@startuml
== Button pressed ==
participant unknown as uk
participant main
participant interrupt as it
participant app_entry
participant app_ble
participant p2p_client_app
participant stm32_seq
it -> app_entry : HAL_GPIO_EXTI_Callback()
app_entry -> app_ble : APP_BLE_Key_Button1_Action()
app_ble -> p2p_client_app : P2PC_APP_SW1_Button_Action()
p2p_client_app -> stm32_seq : UTIL_SEQ_SetTask(CFG_TASK_SW1_BUTTON_PUSHED_ID)
...waiting for task gets executed....
stm32_seq -> p2p_client_app : Button_Trigger_Received()
p2p_client_app -> p2p_client_app : toggleButtonStatus()
p2p_client_app -> p2p_client_app : Write_Char(P2P_WRITE_CHAR_UUID, 0, buttonStatus)
activate p2p_client_app
p2p_client_app -> "?b" : aci_gatt_write_without_resp()
deactivate p2p_client_app
== Event received ==
"?a" -> p2p_client_app : Event_Handler()
activate p2p_client_app
opt event == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE
opt event->core_event == ACI_GATT_PROC_COMPLETE_VSEVT_CODE
opt aP2PClientContext[index].connHandle != pr->Connection_Handle
p2p_client_app -> stm32_seq : UTIL_SEQ_SetTask(CFG_TASK_SEARCH_SERVICE_ID)
end
end
end
deactivate p2p_client_app
...waiting for task gets executed....
stm32_seq -> p2p_client_app : Update_Service()
......
uk -> app_entry : UTIL_SEQ_Idle()
uk -> app_entry : shci_notify_asynch_evt()
activate app_entry
app_entry -> stm32_seq : UTIL_SEQ_SetTask(CFG_TASK_SYSTEM_HCI_ASYNCH_EVT_ID)
deactivate app_entry
uk -> app_entry : shci_cmd_resp_release()
activate app_entry
app_entry -> stm32_seq : UTIL_SEQ_SetEvt(CFG_IDLEEVT_SYSTEM_HCI_CMD_EVT_RSP_ID)
deactivate app_entry
uk -> app_entry : shci_cmd_resp_wait()
activate app_entry
app_entry -> stm32_seq : UTIL_SEQ_WaitEvt(CFG_IDLEEVT_SYSTEM_HCI_CMD_EVT_RSP_ID)
deactivate app_entry
== INIT ==
main -> stm32_seq : UTIL_SEQ_Run(UTIL_SEQ_DEFAULT)
activate stm32_seq
stm32_seq -> shci_tl : shci_user_evt_proc()
activate shci_tl
shci_tl -> app_entry : APPE_SysUserEvtRx()
activate app_entry
app_entry -> app_debug : APPD_EnableCPU2()
app_entry -> app_ble : APP_BLE_Init()
activate app_ble
app_ble -> app_ble : Ble_Tl_Init()
app_ble -> stm32_seq : UTIL_SEQ_RegTask(CFG_TASK_HCI_ASYNCH_EVT_ID, UTIL_SEQ_RFU, hci_user_evt_proc)
app_ble -> shci : SHCI_C2_BLE_Init()
app_ble -> app_ble : Ble_Hci_Gap_Gatt_Init()
app_ble -> svc_ctl : SVCCTL_Init()
app_ble -> stm32_seq : UTIL_SEQ_RegTask(CFG_TASK_START_SCAN_ID, UTIL_SEQ_RFU, Scan_Request)
app_ble -> stm32_seq : UTIL_SEQ_RegTask(CFG_TASK_CONN_DEV_1_ID, UTIL_SEQ_RFU, Connect_Request)
app_ble -> uk : aci_hal_set_radio_activity_mask()
app_ble -> app_p2p_client : P2PC_APP_Init()
activate app_p2p_client
app_p2p_client -> svc_ctl : SVCCTL_RegisterCltHandler(Event_Handler)
deactivate app_p2p_client
app_ble -> hw_timeserver : HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(BleApplicationContext.SwitchOffGPIO_timer_Id), hw_ts_SingleShot, Switch_OFF_GPIO)
deactivate app_ble
deactivate app_entry
deactivate shci_tl
stm32_seq -> stm32_seq : UTIL_SEQ_PreIdle()
stm32_seq -> stm32_seq : UTIL_SEQ_Idle()
stm32_seq -> stm32_seq : UTIL_SEQ_PostIdle()
deactivate stm32_seq
@enduml

7
config_example.yml

@ -0,0 +1,7 @@
roles:
- server
- client
device_id:
server: /dev/tty.usbmodem207E3283544E1
client: /dev/tty.usbmodem2067368F32521

29
download.py

@ -1,18 +1,26 @@
import logging
import subprocess
from pathlib import Path
from typing import Sequence, Union
from typing import Sequence
from typing import Union
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("Download")
# APPLICATION_NAME = "nucleo-wb55-ble"
APPLICATION_NAME = "nucleo-wb55-dongle-ble"
#APPLICATION_NAME = "nucleo-wb55-dongle-usb"
#APPLICATION_NAME = "nucleo-wb55-dongle-blinky"
PORT="USB1"
CLI_PATH = Path("/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM32CubeProgrammer.app/Contents/MacOs/bin/STM32_Programmer_CLI")
ELF_FILE = Path.home() / Path(f"Documents/git/nucleo-playground-workspace/{APPLICATION_NAME}/Debug/{APPLICATION_NAME}.elf")
# APPLICATION_NAME = "nucleo-wb55-dongle-usb"
# APPLICATION_NAME = "nucleo-wb55-dongle-blinky"
PORT = "USB1"
CLI_PATH = Path(
"/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
"STM32CubeProgrammer.app/Contents/MacOs/bin/STM32_Programmer_CLI",
)
ELF_FILE = Path.home() / Path(
f"Documents/git/nucleo-playground-workspace/{APPLICATION_NAME}/"
f"Debug/{APPLICATION_NAME}.elf",
)
def execute_command(
@ -26,17 +34,17 @@ def execute_command(
)
def _poll_stdout() -> str:
return process.stdout.readline().decode()
return process.stdout.readline().decode() # type: ignore
exit_code = None
command_logger = logger.getChild("Programmer")
while exit_code is None:
for line in iter(_poll_stdout, ''):
for line in iter(_poll_stdout, ""):
command_logger.info(line.rstrip())
exit_code = process.poll()
for line in iter(_poll_stdout, ''):
for line in iter(_poll_stdout, ""):
command_logger.info(line.rstrip()) # flush pipe
logger.debug(f"Coomand finished with exit code {exit_code}")
@ -48,7 +56,8 @@ def download():
str(CLI_PATH),
"-c",
f"port={PORT}",
"-w", str(ELF_FILE),
"-w",
str(ELF_FILE),
]
execute_command(command)

38
nucleo-wb55-ble/.mxproject

File diff suppressed because one or more lines are too long

8
nucleo-wb55-ble/.project

@ -28,5 +28,13 @@
<nature>com.st.stm32cube.ide.mcu.MCURootProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
</natures>
<linkedResources>
<link>
<name>shared_commands</name>
<type>2</type>
<locationURI>$%7BPARENT-1-PROJECT_LOC%7D/nucleo-wb55-dongle-ble/shared_commands</locationURI>
</link>
</linkedResources>
</projectDescription>

2
nucleo-wb55-ble/Core/Inc/stm32wbxx_hal_conf.h

@ -44,7 +44,7 @@
/*#define HAL_IWDG_MODULE_ENABLED */
/*#define HAL_LCD_MODULE_ENABLED */
/*#define HAL_LPTIM_MODULE_ENABLED */
/*#define HAL_PCD_MODULE_ENABLED */
#define HAL_PCD_MODULE_ENABLED
/*#define HAL_PKA_MODULE_ENABLED */
/*#define HAL_QSPI_MODULE_ENABLED */
/*#define HAL_RNG_MODULE_ENABLED */

1
nucleo-wb55-ble/Core/Inc/stm32wbxx_it.h

@ -57,6 +57,7 @@ void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void EXTI4_IRQHandler(void);
void USB_LP_IRQHandler(void);
void HSEM_IRQHandler(void);
/* USER CODE BEGIN EFP */

188
nucleo-wb55-ble/Core/Src/main.c

@ -19,11 +19,16 @@
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "commands.h"
#include "stm32_lpm.h"
#include "stm32_seq.h"
#include "dbg_trace.h"
#include "hw_conf.h"
#include "otp.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@ -54,7 +59,11 @@ static void MX_GPIO_Init(void);
static void MX_RF_Init(void);
static void MX_RTC_Init(void);
/* USER CODE BEGIN PFP */
void PeriphClock_Config(void);
static void Reset_Device( void );
static void Reset_IPCC( void );
static void Reset_BackupDomain( void );
static void Init_Exti( void );
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
@ -78,20 +87,22 @@ int main(void)
HAL_Init();
/* USER CODE BEGIN Init */
Reset_Device();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
PeriphClock_Config();
Init_Exti(); /**< Configure the system Power Mode */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_RF_Init();
MX_RTC_Init();
MX_USB_Device_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
@ -102,10 +113,11 @@ int main(void)
/* USER CODE BEGIN WHILE */
while (1)
{
UTIL_SEQ_Run(UTIL_SEQ_DEFAULT);
pop_and_execute_commands();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
UTIL_SEQ_Run(~0);
}
/* USER CODE END 3 */
}
@ -130,11 +142,12 @@ void SystemClock_Config(void)
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE
|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI
|RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
@ -160,7 +173,8 @@ void SystemClock_Config(void)
/** Initializes the peripherals clocks
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS|RCC_PERIPHCLK_RFWAKEUP
|RCC_PERIPHCLK_RTC;
|RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSE;
PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSI;
@ -274,7 +288,165 @@ static void MX_GPIO_Init(void)
}
/* USER CODE BEGIN 4 */
void PeriphClock_Config(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 };
RCC_CRSInitTypeDef RCC_CRSInitStruct = { 0 };
/**
* This prevents the CPU2 to disable the HSI48 oscillator when
* it does not use anymore the RNG IP
*/
LL_HSEM_1StepLock( HSEM, 5 );
LL_RCC_HSI48_Enable();
while(!LL_RCC_HSI48_IsReady());
/* Select HSI48 as USB clock source */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/*Configure the clock recovery system (CRS)**********************************/
/* Enable CRS Clock */
__HAL_RCC_CRS_CLK_ENABLE();
/* Default Synchro Signal division factor (not divided) */
RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1;
/* Set the SYNCSRC[1:0] bits according to CRS_Source value */
RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB;
/* HSI48 is synchronized with USB SOF at 1KHz rate */
RCC_CRSInitStruct.ReloadValue = RCC_CRS_RELOADVALUE_DEFAULT;
RCC_CRSInitStruct.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT;
RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING;
/* Set the TRIM[5:0] to the default value*/
RCC_CRSInitStruct.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT;
/* Start automatic synchronization */
HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct);
return;
}
/*************************************************************
*
* LOCAL FUNCTIONS
*
*************************************************************/
static void Reset_Device( void )
{
#if ( CFG_HW_RESET_BY_FW == 1 )
Reset_BackupDomain();
Reset_IPCC();
#endif
return;
}
static void Reset_IPCC( void )
{
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC);
LL_C1_IPCC_ClearFlag_CHx(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C2_IPCC_ClearFlag_CHx(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C1_IPCC_DisableTransmitChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C2_IPCC_DisableTransmitChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C1_IPCC_DisableReceiveChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C2_IPCC_DisableReceiveChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
return;
}
static void Reset_BackupDomain( void )
{
if ((LL_RCC_IsActiveFlag_PINRST() != FALSE) && (LL_RCC_IsActiveFlag_SFTRST() == FALSE))
{
HAL_PWR_EnableBkUpAccess(); /**< Enable access to the RTC registers */
/**
* Write twice the value to flush the APB-AHB bridge
* This bit shall be written in the register before writing the next one
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
}
return;
}
static void Init_Exti( void )
{
/**< Disable all wakeup interrupt on CPU1 except IPCC(36), HSEM(38) */
LL_EXTI_DisableIT_0_31(~0);
LL_EXTI_DisableIT_32_63( (~0) & (~(LL_EXTI_LINE_36 | LL_EXTI_LINE_38)) );
return;
}
/*************************************************************
*
* WRAP FUNCTIONS
*
*************************************************************/
void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += HAL_GetTickFreq();
}
while ((HAL_GetTick() - tickstart) < wait)
{
/************************************************************************************
* ENTER SLEEP MODE
***********************************************************************************/
LL_LPM_EnableSleep( ); /**< Clear SLEEPDEEP bit of Cortex System Control Register */
/**
* This option is used to ensure that store operations are completed
*/
#if defined ( __CC_ARM)
__force_stores();
#endif
__WFI( );
}
}
/* USER CODE END 4 */
/**

16
nucleo-wb55-ble/Core/Src/stm32wbxx_it.c

@ -57,7 +57,7 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern PCD_HandleTypeDef hpcd_USB_FS;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
@ -214,6 +214,20 @@ void EXTI4_IRQHandler(void)
/* USER CODE END EXTI4_IRQn 1 */
}
/**
* @brief This function handles USB low priority interrupt, USB wake-up interrupt through EXTI line 28.
*/
void USB_LP_IRQHandler(void)
{
/* USER CODE BEGIN USB_LP_IRQn 0 */
/* USER CODE END USB_LP_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_FS);
/* USER CODE BEGIN USB_LP_IRQn 1 */
/* USER CODE END USB_LP_IRQn 1 */
}
/**
* @brief This function handles HSEM global interrupt.
*/

994
nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_hal_pcd.h

@ -0,0 +1,994 @@
/**
******************************************************************************
* @file stm32wbxx_hal_pcd.h
* @author MCD Application Team
* @brief Header file of PCD HAL module.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32WBxx_HAL_PCD_H
#define STM32WBxx_HAL_PCD_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx_ll_usb.h"
#if defined (USB)
/** @addtogroup STM32WBxx_HAL_Driver
* @{
*/
/** @addtogroup PCD
* @{
*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup PCD_Exported_Types PCD Exported Types
* @{
*/
/**
* @brief PCD State structure definition
*/
typedef enum
{
HAL_PCD_STATE_RESET = 0x00,
HAL_PCD_STATE_READY = 0x01,
HAL_PCD_STATE_ERROR = 0x02,
HAL_PCD_STATE_BUSY = 0x03,
HAL_PCD_STATE_TIMEOUT = 0x04
} PCD_StateTypeDef;
/* Device LPM suspend state */
typedef enum
{
LPM_L0 = 0x00, /* on */
LPM_L1 = 0x01, /* LPM L1 sleep */
LPM_L2 = 0x02, /* suspend */
LPM_L3 = 0x03, /* off */
} PCD_LPM_StateTypeDef;
typedef enum
{
PCD_LPM_L0_ACTIVE = 0x00, /* on */
PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */
} PCD_LPM_MsgTypeDef;
typedef enum
{
PCD_BCD_ERROR = 0xFF,
PCD_BCD_CONTACT_DETECTION = 0xFE,
PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD,
PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC,
PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB,
PCD_BCD_DISCOVERY_COMPLETED = 0x00,
} PCD_BCD_MsgTypeDef;
typedef USB_TypeDef PCD_TypeDef;
typedef USB_CfgTypeDef PCD_InitTypeDef;
typedef USB_EPTypeDef PCD_EPTypeDef;
/**
* @brief PCD Handle Structure definition
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
typedef struct __PCD_HandleTypeDef
#else
typedef struct
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
PCD_TypeDef *Instance; /*!< Register base address */
PCD_InitTypeDef Init; /*!< PCD required parameters */
__IO uint8_t USB_Address; /*!< USB Address */
PCD_EPTypeDef IN_ep[8]; /*!< IN endpoint parameters */
PCD_EPTypeDef OUT_ep[8]; /*!< OUT endpoint parameters */
HAL_LockTypeDef Lock; /*!< PCD peripheral status */
__IO PCD_StateTypeDef State; /*!< PCD communication state */
__IO uint32_t ErrorCode; /*!< PCD Error code */
uint32_t Setup[12]; /*!< Setup packet buffer */
PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */
uint32_t BESL;
uint32_t lpm_active; /*!< Enable or disable the Link Power Management .
This parameter can be set to ENABLE or DISABLE */
uint32_t battery_charging_active; /*!< Enable or disable Battery charging.
This parameter can be set to ENABLE or DISABLE */
void *pData; /*!< Pointer to upper stack Handler */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD SOF callback */
void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Setup Stage callback */
void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Reset callback */
void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Suspend callback */
void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Resume callback */
void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Connect callback */
void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Disconnect callback */
void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data OUT Stage callback */
void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data IN Stage callback */
void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO OUT Incomplete callback */
void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO IN Incomplete callback */
void (* BCDCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< USB OTG PCD BCD callback */
void (* LPMCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< USB OTG PCD LPM callback */
void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp Init callback */
void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp DeInit callback */
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
} PCD_HandleTypeDef;
/**
* @}
*/
/* Include PCD HAL Extended module */
#include "stm32wbxx_hal_pcd_ex.h"
/* Exported constants --------------------------------------------------------*/
/** @defgroup PCD_Exported_Constants PCD Exported Constants
* @{
*/
/** @defgroup PCD_Speed PCD Speed
* @{
*/
#define PCD_SPEED_FULL USBD_FS_SPEED
/**
* @}
*/
/** @defgroup PCD_PHY_Module PCD PHY Module
* @{
*/
#define PCD_PHY_ULPI 1U
#define PCD_PHY_EMBEDDED 2U
#define PCD_PHY_UTMI 3U
/**
* @}
*/
/** @defgroup PCD_Error_Code_definition PCD Error Code definition
* @brief PCD Error Code definition
* @{
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
#define HAL_PCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
/**
* @}
*/
/**
* @}
*/
/* Exported macros -----------------------------------------------------------*/
/** @defgroup PCD_Exported_Macros PCD Exported Macros
* @brief macros to handle interrupts and specific clock configurations
* @{
*/
#define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
#define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->ISTR) &= (uint16_t)(~(__INTERRUPT__)))
#define __HAL_USB_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR1 |= USB_WAKEUP_EXTI_LINE
#define __HAL_USB_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR1 &= ~(USB_WAKEUP_EXTI_LINE)
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup PCD_Exported_Functions PCD Exported Functions
* @{
*/
/* Initialization/de-initialization functions ********************************/
/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
* @{
*/
HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd);
void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
/** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition
* @brief HAL USB OTG PCD Callback ID enumeration definition
* @{
*/
typedef enum
{
HAL_PCD_SOF_CB_ID = 0x01, /*!< USB PCD SOF callback ID */
HAL_PCD_SETUPSTAGE_CB_ID = 0x02, /*!< USB PCD Setup Stage callback ID */
HAL_PCD_RESET_CB_ID = 0x03, /*!< USB PCD Reset callback ID */
HAL_PCD_SUSPEND_CB_ID = 0x04, /*!< USB PCD Suspend callback ID */
HAL_PCD_RESUME_CB_ID = 0x05, /*!< USB PCD Resume callback ID */
HAL_PCD_CONNECT_CB_ID = 0x06, /*!< USB PCD Connect callback ID */
HAL_PCD_DISCONNECT_CB_ID = 0x07, /*!< USB PCD Disconnect callback ID */
HAL_PCD_MSPINIT_CB_ID = 0x08, /*!< USB PCD MspInit callback ID */
HAL_PCD_MSPDEINIT_CB_ID = 0x09 /*!< USB PCD MspDeInit callback ID */
} HAL_PCD_CallbackIDTypeDef;
/**
* @}
*/
/** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition
* @brief HAL USB OTG PCD Callback pointer definition
* @{
*/
typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd); /*!< pointer to a common USB OTG PCD callback function */
typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data OUT Stage callback */
typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data IN Stage callback */
typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */
typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO IN Incomplete callback */
typedef void (*pPCD_LpmCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< pointer to USB OTG PCD LPM callback */
typedef void (*pPCD_BcdCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< pointer to USB OTG PCD BCD callback */
/**
* @}
*/
HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
HAL_PCD_CallbackIDTypeDef CallbackID,
pPCD_CallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd,
HAL_PCD_CallbackIDTypeDef CallbackID);
HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
pPCD_DataOutStageCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
pPCD_DataInStageCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
pPCD_IsoOutIncpltCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
pPCD_IsoInIncpltCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd,
pPCD_BcdCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd,
pPCD_LpmCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
/**
* @}
*/
/* I/O operation functions ***************************************************/
/* Non-Blocking mode: Interrupt */
/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions
* @{
*/
HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
/**
* @}
*/
/* Peripheral Control functions **********************************************/
/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions
* @{
*/
HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
uint16_t ep_mps, uint8_t ep_type);
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
uint8_t *pBuf, uint32_t len);
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
uint8_t *pBuf, uint32_t len);
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
/**
* @}
*/
/* Peripheral State functions ************************************************/
/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions
* @{
*/
PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
/**
* @}
*/
/**
* @}
*/
/* Private constants ---------------------------------------------------------*/
/** @defgroup PCD_Private_Constants PCD Private Constants
* @{
*/
/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt
* @{
*/
#define USB_WAKEUP_EXTI_LINE (0x1U << 28) /*!< USB FS EXTI Line WakeUp Interrupt */
/**
* @}
*/
/** @defgroup PCD_EP0_MPS PCD EP0 MPS
* @{
*/
#define PCD_EP0MPS_64 EP_MPS_64
#define PCD_EP0MPS_32 EP_MPS_32
#define PCD_EP0MPS_16 EP_MPS_16
#define PCD_EP0MPS_08 EP_MPS_8
/**
* @}
*/
/** @defgroup PCD_ENDP PCD ENDP
* @{
*/
#define PCD_ENDP0 0U
#define PCD_ENDP1 1U
#define PCD_ENDP2 2U
#define PCD_ENDP3 3U
#define PCD_ENDP4 4U
#define PCD_ENDP5 5U
#define PCD_ENDP6 6U
#define PCD_ENDP7 7U
/**
* @}
*/
/** @defgroup PCD_ENDP_Kind PCD Endpoint Kind
* @{
*/
#define PCD_SNG_BUF 0U
#define PCD_DBL_BUF 1U
/**
* @}
*/
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
/** @defgroup PCD_Private_Macros PCD Private Macros
* @{
*/
/******************** Bit definition for USB_COUNTn_RX register *************/
#define USB_CNTRX_NBLK_MSK (0x1FU << 10)
#define USB_CNTRX_BLSIZE (0x1U << 15)
/* SetENDPOINT */
#define PCD_SET_ENDPOINT(USBx, bEpNum, wRegValue) (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U)) = (uint16_t)(wRegValue))
/* GetENDPOINT */
#define PCD_GET_ENDPOINT(USBx, bEpNum) (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U)))
/* ENDPOINT transfer */
#define USB_EP0StartXfer USB_EPStartXfer
/**
* @brief sets the type in the endpoint register(bits EP_TYPE[1:0])
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param wType Endpoint Type.
* @retval None
*/
#define PCD_SET_EPTYPE(USBx, bEpNum, wType) (PCD_SET_ENDPOINT((USBx), (bEpNum), ((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_MASK) | (wType) | USB_EP_CTR_TX | USB_EP_CTR_RX)))
/**
* @brief gets the type in the endpoint register(bits EP_TYPE[1:0])
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval Endpoint Type
*/
#define PCD_GET_EPTYPE(USBx, bEpNum) (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_FIELD)
/**
* @brief free buffer used from the application realizing it to the line
* toggles bit SW_BUF in the double buffered endpoint register
* @param USBx USB device.
* @param bEpNum, bDir
* @retval None
*/
#define PCD_FreeUserBuffer(USBx, bEpNum, bDir) \
do { \
if ((bDir) == 0U) \
{ \
/* OUT double buffered endpoint */ \
PCD_TX_DTOG((USBx), (bEpNum)); \
} \
else if ((bDir) == 1U) \
{ \
/* IN double buffered endpoint */ \
PCD_RX_DTOG((USBx), (bEpNum)); \
} \
} while(0)
/**
* @brief sets the status for tx transfer (bits STAT_TX[1:0]).
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param wState new state
* @retval None
*/
#define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_DTOGMASK; \
/* toggle first bit ? */ \
if ((USB_EPTX_DTOG1 & (wState))!= 0U) \
{ \
_wRegVal ^= USB_EPTX_DTOG1; \
} \
/* toggle second bit ? */ \
if ((USB_EPTX_DTOG2 & (wState))!= 0U) \
{ \
_wRegVal ^= USB_EPTX_DTOG2; \
} \
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
} while(0) /* PCD_SET_EP_TX_STATUS */
/**
* @brief sets the status for rx transfer (bits STAT_TX[1:0])
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param wState new state
* @retval None
*/
#define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_DTOGMASK; \
/* toggle first bit ? */ \
if ((USB_EPRX_DTOG1 & (wState))!= 0U) \
{ \
_wRegVal ^= USB_EPRX_DTOG1; \
} \
/* toggle second bit ? */ \
if ((USB_EPRX_DTOG2 & (wState))!= 0U) \
{ \
_wRegVal ^= USB_EPRX_DTOG2; \
} \
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
} while(0) /* PCD_SET_EP_RX_STATUS */
/**
* @brief sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param wStaterx new state.
* @param wStatetx new state.
* @retval None
*/
#define PCD_SET_EP_TXRX_STATUS(USBx, bEpNum, wStaterx, wStatetx) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (USB_EPRX_DTOGMASK | USB_EPTX_STAT); \
/* toggle first bit ? */ \
if ((USB_EPRX_DTOG1 & (wStaterx))!= 0U) \
{ \
_wRegVal ^= USB_EPRX_DTOG1; \
} \
/* toggle second bit ? */ \
if ((USB_EPRX_DTOG2 & (wStaterx))!= 0U) \
{ \
_wRegVal ^= USB_EPRX_DTOG2; \
} \
/* toggle first bit ? */ \
if ((USB_EPTX_DTOG1 & (wStatetx))!= 0U) \
{ \
_wRegVal ^= USB_EPTX_DTOG1; \
} \
/* toggle second bit ? */ \
if ((USB_EPTX_DTOG2 & (wStatetx))!= 0U) \
{ \
_wRegVal ^= USB_EPTX_DTOG2; \
} \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
} while(0) /* PCD_SET_EP_TXRX_STATUS */
/**
* @brief gets the status for tx/rx transfer (bits STAT_TX[1:0]
* /STAT_RX[1:0])
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval status
*/
#define PCD_GET_EP_TX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_STAT)
#define PCD_GET_EP_RX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_STAT)
/**
* @brief sets directly the VALID tx/rx-status into the endpoint register
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_SET_EP_TX_VALID(USBx, bEpNum) (PCD_SET_EP_TX_STATUS((USBx), (bEpNum), USB_EP_TX_VALID))
#define PCD_SET_EP_RX_VALID(USBx, bEpNum) (PCD_SET_EP_RX_STATUS((USBx), (bEpNum), USB_EP_RX_VALID))
/**
* @brief checks stall condition in an endpoint.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval TRUE = endpoint in stall condition.
*/
#define PCD_GET_EP_TX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_TX_STATUS((USBx), (bEpNum)) == USB_EP_TX_STALL)
#define PCD_GET_EP_RX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_RX_STATUS((USBx), (bEpNum)) == USB_EP_RX_STALL)
/**
* @brief set & clear EP_KIND bit.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_SET_EP_KIND(USBx, bEpNum) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_KIND)); \
} while(0) /* PCD_SET_EP_KIND */
#define PCD_CLEAR_EP_KIND(USBx, bEpNum) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPKIND_MASK; \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
} while(0) /* PCD_CLEAR_EP_KIND */
/**
* @brief Sets/clears directly STATUS_OUT bit in the endpoint register.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_SET_OUT_STATUS(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum))
#define PCD_CLEAR_OUT_STATUS(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum))
/**
* @brief Sets/clears directly EP_KIND bit in the endpoint register.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_SET_EP_DBUF(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum))
#define PCD_CLEAR_EP_DBUF(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum))
/**
* @brief Clears bit CTR_RX / CTR_TX in the endpoint register.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0x7FFFU & USB_EPREG_MASK); \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_TX)); \
} while(0) /* PCD_CLEAR_RX_EP_CTR */
#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0xFF7FU & USB_EPREG_MASK); \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX)); \
} while(0) /* PCD_CLEAR_TX_EP_CTR */
/**
* @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_RX_DTOG(USBx, bEpNum) \
do { \
uint16_t _wEPVal; \
\
_wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_RX)); \
} while(0) /* PCD_RX_DTOG */
#define PCD_TX_DTOG(USBx, bEpNum) \
do { \
uint16_t _wEPVal; \
\
_wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_TX)); \
} while(0) /* PCD_TX_DTOG */
/**
* @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_CLEAR_RX_DTOG(USBx, bEpNum) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \
\
if ((_wRegVal & USB_EP_DTOG_RX) != 0U)\
{ \
PCD_RX_DTOG((USBx), (bEpNum)); \
} \
} while(0) /* PCD_CLEAR_RX_DTOG */
#define PCD_CLEAR_TX_DTOG(USBx, bEpNum) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \
\
if ((_wRegVal & USB_EP_DTOG_TX) != 0U)\
{ \
PCD_TX_DTOG((USBx), (bEpNum)); \
} \
} while(0) /* PCD_CLEAR_TX_DTOG */
/**
* @brief Sets address in an endpoint register.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param bAddr Address.
* @retval None
*/
#define PCD_SET_EP_ADDRESS(USBx, bEpNum, bAddr) \
do { \
uint16_t _wRegVal; \
\
_wRegVal = (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK) | (bAddr); \
\
PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \
} while(0) /* PCD_SET_EP_ADDRESS */
/**
* @brief Gets address in an endpoint register.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_GET_EP_ADDRESS(USBx, bEpNum) ((uint8_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPADDR_FIELD))
#define PCD_EP_TX_CNT(USBx, bEpNum) ((uint16_t *)((((uint32_t)(USBx)->BTABLE + ((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U)))
#define PCD_EP_RX_CNT(USBx, bEpNum) ((uint16_t *)((((uint32_t)(USBx)->BTABLE + ((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U)))
/**
* @brief sets address of the tx/rx buffer.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param wAddr address to be set (must be word aligned).
* @retval None
*/
#define PCD_SET_EP_TX_ADDRESS(USBx, bEpNum, wAddr) \
do { \
__IO uint16_t *_wRegVal; \
uint32_t _wRegBase = (uint32_t)USBx; \
\
_wRegBase += (uint32_t)(USBx)->BTABLE; \
_wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + (((uint32_t)(bEpNum) * 8U) * PMA_ACCESS)); \
*_wRegVal = ((wAddr) >> 1) << 1; \
} while(0) /* PCD_SET_EP_TX_ADDRESS */
#define PCD_SET_EP_RX_ADDRESS(USBx, bEpNum, wAddr) \
do { \
__IO uint16_t *_wRegVal; \
uint32_t _wRegBase = (uint32_t)USBx; \
\
_wRegBase += (uint32_t)(USBx)->BTABLE; \
_wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 4U) * PMA_ACCESS)); \
*_wRegVal = ((wAddr) >> 1) << 1; \
} while(0) /* PCD_SET_EP_RX_ADDRESS */
/**
* @brief Gets address of the tx/rx buffer.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval address of the buffer.
*/
#define PCD_GET_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_TX_ADDRESS((USBx), (bEpNum)))
#define PCD_GET_EP_RX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_RX_ADDRESS((USBx), (bEpNum)))
/**
* @brief Sets counter of rx buffer with no. of blocks.
* @param pdwReg Register pointer
* @param wCount Counter.
* @param wNBlocks no. of Blocks.
* @retval None
*/
#define PCD_CALC_BLK32(pdwReg, wCount, wNBlocks) \
do { \
(wNBlocks) = (wCount) >> 5; \
if (((wCount) & 0x1fU) == 0U) \
{ \
(wNBlocks)--; \
} \
*(pdwReg) = (uint16_t)(((wNBlocks) << 10) | USB_CNTRX_BLSIZE); \
} while(0) /* PCD_CALC_BLK32 */
#define PCD_CALC_BLK2(pdwReg, wCount, wNBlocks) \
do { \
(wNBlocks) = (wCount) >> 1; \
if (((wCount) & 0x1U) != 0U) \
{ \
(wNBlocks)++; \
} \
*(pdwReg) = (uint16_t)((wNBlocks) << 10); \
} while(0) /* PCD_CALC_BLK2 */
#define PCD_SET_EP_CNT_RX_REG(pdwReg, wCount) \
do { \
uint32_t wNBlocks; \
if ((wCount) == 0U) \
{ \
*(pdwReg) &= (uint16_t)~USB_CNTRX_NBLK_MSK; \
*(pdwReg) |= USB_CNTRX_BLSIZE; \
} \
else if((wCount) <= 62U) \
{ \
PCD_CALC_BLK2((pdwReg), (wCount), wNBlocks); \
} \
else \
{ \
PCD_CALC_BLK32((pdwReg), (wCount), wNBlocks); \
} \
} while(0) /* PCD_SET_EP_CNT_RX_REG */
#define PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum, wCount) \
do { \
uint32_t _wRegBase = (uint32_t)(USBx); \
__IO uint16_t *pdwReg; \
\
_wRegBase += (uint32_t)(USBx)->BTABLE; \
pdwReg = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \
PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount)); \
} while(0)
/**
* @brief sets counter for the tx/rx buffer.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param wCount Counter value.
* @retval None
*/
#define PCD_SET_EP_TX_CNT(USBx, bEpNum, wCount) \
do { \
uint32_t _wRegBase = (uint32_t)(USBx); \
__IO uint16_t *_wRegVal; \
\
_wRegBase += (uint32_t)(USBx)->BTABLE; \
_wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \
*_wRegVal = (uint16_t)(wCount); \
} while(0)
#define PCD_SET_EP_RX_CNT(USBx, bEpNum, wCount) \
do { \
uint32_t _wRegBase = (uint32_t)(USBx); \
__IO uint16_t *_wRegVal; \
\
_wRegBase += (uint32_t)(USBx)->BTABLE; \
_wRegVal = (__IO uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \
PCD_SET_EP_CNT_RX_REG(_wRegVal, (wCount)); \
} while(0)
/**
* @brief gets counter of the tx buffer.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval Counter value
*/
#define PCD_GET_EP_TX_CNT(USBx, bEpNum) ((uint32_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x3ffU)
#define PCD_GET_EP_RX_CNT(USBx, bEpNum) ((uint32_t)(*PCD_EP_RX_CNT((USBx), (bEpNum))) & 0x3ffU)
/**
* @brief Sets buffer 0/1 address in a double buffer endpoint.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param wBuf0Addr buffer 0 address.
* @retval Counter value
*/
#define PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum, wBuf0Addr) \
do { \
PCD_SET_EP_TX_ADDRESS((USBx), (bEpNum), (wBuf0Addr)); \
} while(0) /* PCD_SET_EP_DBUF0_ADDR */
#define PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum, wBuf1Addr) \
do { \
PCD_SET_EP_RX_ADDRESS((USBx), (bEpNum), (wBuf1Addr)); \
} while(0) /* PCD_SET_EP_DBUF1_ADDR */
/**
* @brief Sets addresses in a double buffer endpoint.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param wBuf0Addr: buffer 0 address.
* @param wBuf1Addr = buffer 1 address.
* @retval None
*/
#define PCD_SET_EP_DBUF_ADDR(USBx, bEpNum, wBuf0Addr, wBuf1Addr) \
do { \
PCD_SET_EP_DBUF0_ADDR((USBx), (bEpNum), (wBuf0Addr)); \
PCD_SET_EP_DBUF1_ADDR((USBx), (bEpNum), (wBuf1Addr)); \
} while(0) /* PCD_SET_EP_DBUF_ADDR */
/**
* @brief Gets buffer 0/1 address of a double buffer endpoint.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_GET_EP_DBUF0_ADDR(USBx, bEpNum) (PCD_GET_EP_TX_ADDRESS((USBx), (bEpNum)))
#define PCD_GET_EP_DBUF1_ADDR(USBx, bEpNum) (PCD_GET_EP_RX_ADDRESS((USBx), (bEpNum)))
/**
* @brief Gets buffer 0/1 address of a double buffer endpoint.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @param bDir endpoint dir EP_DBUF_OUT = OUT
* EP_DBUF_IN = IN
* @param wCount: Counter value
* @retval None
*/
#define PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount) \
do { \
if ((bDir) == 0U) \
/* OUT endpoint */ \
{ \
PCD_SET_EP_RX_DBUF0_CNT((USBx), (bEpNum), (wCount)); \
} \
else \
{ \
if ((bDir) == 1U) \
{ \
/* IN endpoint */ \
PCD_SET_EP_TX_CNT((USBx), (bEpNum), (wCount)); \
} \
} \
} while(0) /* SetEPDblBuf0Count*/
#define PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount) \
do { \
uint32_t _wBase = (uint32_t)(USBx); \
__IO uint16_t *_wEPRegVal; \
\
if ((bDir) == 0U) \
{ \
/* OUT endpoint */ \
PCD_SET_EP_RX_CNT((USBx), (bEpNum), (wCount)); \
} \
else \
{ \
if ((bDir) == 1U) \
{ \
/* IN endpoint */ \
_wBase += (uint32_t)(USBx)->BTABLE; \
_wEPRegVal = (__IO uint16_t *)(_wBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \
*_wEPRegVal = (uint16_t)(wCount); \
} \
} \
} while(0) /* SetEPDblBuf1Count */
#define PCD_SET_EP_DBUF_CNT(USBx, bEpNum, bDir, wCount) \
do { \
PCD_SET_EP_DBUF0_CNT((USBx), (bEpNum), (bDir), (wCount)); \
PCD_SET_EP_DBUF1_CNT((USBx), (bEpNum), (bDir), (wCount)); \
} while(0) /* PCD_SET_EP_DBUF_CNT */
/**
* @brief Gets buffer 0/1 rx/tx counter for double buffering.
* @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number.
* @retval None
*/
#define PCD_GET_EP_DBUF0_CNT(USBx, bEpNum) (PCD_GET_EP_TX_CNT((USBx), (bEpNum)))
#define PCD_GET_EP_DBUF1_CNT(USBx, bEpNum) (PCD_GET_EP_RX_CNT((USBx), (bEpNum)))
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* defined (USB) */
#ifdef __cplusplus
}
#endif
#endif /* STM32WBxx_HAL_PCD_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

91
nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_hal_pcd_ex.h

@ -0,0 +1,91 @@
/**
******************************************************************************
* @file stm32wbxx_hal_pcd_ex.h
* @author MCD Application Team
* @brief Header file of PCD HAL Extension module.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32WBxx_HAL_PCD_EX_H
#define STM32WBxx_HAL_PCD_EX_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx_hal_def.h"
#if defined (USB)
/** @addtogroup STM32WBxx_HAL_Driver
* @{
*/
/** @addtogroup PCDEx
* @{
*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup PCDEx_Exported_Functions PCDEx Exported Functions
* @{
*/
/** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
* @{
*/
HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr,
uint16_t ep_kind, uint32_t pmaadress);
HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd);
void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd);
void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg);
void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* defined (USB) */
#ifdef __cplusplus
}
#endif
#endif /* STM32WBxx_HAL_PCD_EX_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

237
nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_ll_usb.h

@ -0,0 +1,237 @@
/**
******************************************************************************
* @file stm32wbxx_ll_usb.h
* @author MCD Application Team
* @brief Header file of USB Low Layer HAL module.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32WBxx_LL_USB_H
#define STM32WBxx_LL_USB_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx_hal_def.h"
#if defined (USB)
/** @addtogroup STM32WBxx_HAL_Driver
* @{
*/
/** @addtogroup USB_LL
* @{
*/
/* Exported types ------------------------------------------------------------*/
/**
* @brief USB Mode definition
*/
typedef enum
{
USB_DEVICE_MODE = 0
} USB_ModeTypeDef;
/**
* @brief USB Initialization Structure definition
*/
typedef struct
{
uint32_t dev_endpoints; /*!< Device Endpoints number.
This parameter depends on the used USB core.
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint32_t speed; /*!< USB Core speed.
This parameter can be any value of @ref USB_Core_Speed */
uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */
uint32_t phy_itface; /*!< Select the used PHY interface.
This parameter can be any value of @ref USB_Core_PHY */
uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */
uint32_t low_power_enable; /*!< Enable or disable Low Power mode */
uint32_t lpm_enable; /*!< Enable or disable Battery charging. */
uint32_t battery_charging_enable; /*!< Enable or disable Battery charging. */
} USB_CfgTypeDef;
typedef struct
{
uint8_t num; /*!< Endpoint number
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint8_t is_in; /*!< Endpoint direction
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t is_stall; /*!< Endpoint stall condition
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t type; /*!< Endpoint type
This parameter can be any value of @ref USB_EP_Type */
uint8_t data_pid_start; /*!< Initial data PID
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint16_t pmaadress; /*!< PMA Address
This parameter can be any value between Min_addr = 0 and Max_addr = 1K */
uint16_t pmaaddr0; /*!< PMA Address0
This parameter can be any value between Min_addr = 0 and Max_addr = 1K */
uint16_t pmaaddr1; /*!< PMA Address1
This parameter can be any value between Min_addr = 0 and Max_addr = 1K */
uint8_t doublebuffer; /*!< Double buffer enable
This parameter can be 0 or 1 */
uint16_t tx_fifo_num; /*!< This parameter is not required by USB Device FS peripheral, it is used
only by USB OTG FS peripheral
This parameter is added to ensure compatibility across USB peripherals */
uint32_t maxpacket; /*!< Endpoint Max packet size
This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
uint8_t *xfer_buff; /*!< Pointer to transfer buffer */
uint32_t xfer_len; /*!< Current transfer length */
uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */
uint32_t xfer_len_db; /*!< double buffer transfer length used with bulk double buffer in */
uint8_t xfer_fill_db; /*!< double buffer Need to Fill new buffer used with bulk_in */
} USB_EPTypeDef;
/* Exported constants --------------------------------------------------------*/
/** @defgroup PCD_Exported_Constants PCD Exported Constants
* @{
*/
/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
* @{
*/
#define EP_MPS_64 0U
#define EP_MPS_32 1U
#define EP_MPS_16 2U
#define EP_MPS_8 3U
/**
* @}
*/
/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
* @{
*/
#define EP_TYPE_CTRL 0U
#define EP_TYPE_ISOC 1U
#define EP_TYPE_BULK 2U
#define EP_TYPE_INTR 3U
#define EP_TYPE_MSK 3U
/**
* @}
*/
/** @defgroup USB_LL Device Speed
* @{
*/
#define USBD_FS_SPEED 2U
/**
* @}
*/
#define BTABLE_ADDRESS 0x000U
#define PMA_ACCESS 1U
#define EP_ADDR_MSK 0x7U
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions
* @{
*/
HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg);
HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg);
HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx);
HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx);
HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode);
#if defined (HAL_PCD_MODULE_ENABLED)
HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep);
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep);
HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep);
HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep);
HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep);
#endif
HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address);
HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx);
HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx);
HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx);
uint32_t USB_ReadInterrupts(USB_TypeDef *USBx);
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx);
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx);
void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf,
uint16_t wPMABufAddr, uint16_t wNBytes);
void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf,
uint16_t wPMABufAddr, uint16_t wNBytes);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* defined (USB) */
#ifdef __cplusplus
}
#endif
#endif /* STM32WBxx_LL_USB_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

2162
nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c

File diff suppressed because it is too large

336
nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c

@ -0,0 +1,336 @@
/**
******************************************************************************
* @file stm32wbxx_hal_pcd_ex.c
* @author MCD Application Team
* @brief PCD Extended HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of the USB Peripheral Controller:
* + Extended features functions
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx_hal.h"
/** @addtogroup STM32WBxx_HAL_Driver
* @{
*/
/** @defgroup PCDEx PCDEx
* @brief PCD Extended HAL module driver
* @{
*/
#ifdef HAL_PCD_MODULE_ENABLED
#if defined (USB)
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions
* @{
*/
/** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
* @brief PCDEx control functions
*
@verbatim
===============================================================================
##### Extended features functions #####
===============================================================================
[..] This section provides functions allowing to:
(+) Update FIFO configuration
@endverbatim
* @{
*/
/**
* @brief Configure PMA for EP
* @param hpcd Device instance
* @param ep_addr endpoint address
* @param ep_kind endpoint Kind
* USB_SNG_BUF: Single Buffer used
* USB_DBL_BUF: Double Buffer used
* @param pmaadress: EP address in The PMA: In case of single buffer endpoint
* this parameter is 16-bit value providing the address
* in PMA allocated to endpoint.
* In case of double buffer endpoint this parameter
* is a 32-bit value providing the endpoint buffer 0 address
* in the LSB part of 32-bit value and endpoint buffer 1 address
* in the MSB part of 32-bit value.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr,
uint16_t ep_kind, uint32_t pmaadress)
{
PCD_EPTypeDef *ep;
/* initialize ep structure*/
if ((0x80U & ep_addr) == 0x80U)
{
ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
}
else
{
ep = &hpcd->OUT_ep[ep_addr];
}
/* Here we check if the endpoint is single or double Buffer*/
if (ep_kind == PCD_SNG_BUF)
{
/* Single Buffer */
ep->doublebuffer = 0U;
/* Configure the PMA */
ep->pmaadress = (uint16_t)pmaadress;
}
else /* USB_DBL_BUF */
{
/* Double Buffer Endpoint */
ep->doublebuffer = 1U;
/* Configure the PMA */
ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU);
ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16);
}
return HAL_OK;
}
/**
* @brief Activate BatteryCharging feature.
* @param hpcd PCD handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd)
{
USB_TypeDef *USBx = hpcd->Instance;
hpcd->battery_charging_active = 1U;
/* Enable BCD feature */
USBx->BCDR |= USB_BCDR_BCDEN;
/* Enable DCD : Data Contact Detect */
USBx->BCDR &= ~(USB_BCDR_PDEN);
USBx->BCDR &= ~(USB_BCDR_SDEN);
USBx->BCDR |= USB_BCDR_DCDEN;
return HAL_OK;
}
/**
* @brief Deactivate BatteryCharging feature.
* @param hpcd PCD handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd)
{
USB_TypeDef *USBx = hpcd->Instance;
hpcd->battery_charging_active = 0U;
/* Disable BCD feature */
USBx->BCDR &= ~(USB_BCDR_BCDEN);
return HAL_OK;
}
/**
* @brief Handle BatteryCharging Process.
* @param hpcd PCD handle
* @retval HAL status
*/
void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd)
{
USB_TypeDef *USBx = hpcd->Instance;
uint32_t tickstart = HAL_GetTick();
/* Wait Detect flag or a timeout is happen*/
while ((USBx->BCDR & USB_BCDR_DCDET) == 0U)
{
/* Check for the Timeout */
if ((HAL_GetTick() - tickstart) > 1000U)
{
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_ERROR);
#else
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
return;
}
}
HAL_Delay(200U);
/* Data Pin Contact ? Check Detect flag */
if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET)
{
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION);
#else
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}
/* Primary detection: checks if connected to Standard Downstream Port
(without charging capability) */
USBx->BCDR &= ~(USB_BCDR_DCDEN);
HAL_Delay(50U);
USBx->BCDR |= (USB_BCDR_PDEN);
HAL_Delay(50U);
/* If Charger detect ? */
if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET)
{
/* Start secondary detection to check connection to Charging Downstream
Port or Dedicated Charging Port */
USBx->BCDR &= ~(USB_BCDR_PDEN);
HAL_Delay(50U);
USBx->BCDR |= (USB_BCDR_SDEN);
HAL_Delay(50U);
/* If CDP ? */
if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET)
{
/* Dedicated Downstream Port DCP */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
#else
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}
else
{
/* Charging Downstream Port CDP */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
#else
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}
}
else /* NO */
{
/* Standard Downstream Port */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
#else
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}
/* Battery Charging capability discovery finished Start Enumeration */
(void)HAL_PCDEx_DeActivateBCD(hpcd);
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
#else
HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
}
/**
* @brief Activate LPM feature.
* @param hpcd PCD handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd)
{
USB_TypeDef *USBx = hpcd->Instance;
hpcd->lpm_active = 1U;
hpcd->LPM_State = LPM_L0;
USBx->LPMCSR |= USB_LPMCSR_LMPEN;
USBx->LPMCSR |= USB_LPMCSR_LPMACK;
return HAL_OK;
}
/**
* @brief Deactivate LPM feature.
* @param hpcd PCD handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd)
{
USB_TypeDef *USBx = hpcd->Instance;
hpcd->lpm_active = 0U;
USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN);
USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK);
return HAL_OK;
}
/**
* @brief Send LPM message to user layer callback.
* @param hpcd PCD handle
* @param msg LPM message
* @retval HAL status
*/
__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hpcd);
UNUSED(msg);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_PCDEx_LPM_Callback could be implemented in the user file
*/
}
/**
* @brief Send BatteryCharging message to user layer callback.
* @param hpcd PCD handle
* @param msg LPM message
* @retval HAL status
*/
__weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hpcd);
UNUSED(msg);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_PCDEx_BCD_Callback could be implemented in the user file
*/
}
/**
* @}
*/
/**
* @}
*/
#endif /* defined (USB) */
#endif /* HAL_PCD_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

849
nucleo-wb55-ble/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c

@ -0,0 +1,849 @@
/**
******************************************************************************
* @file stm32wbxx_ll_usb.c
* @author MCD Application Team
* @brief USB Low Layer HAL module driver.
*
* This file provides firmware functions to manage the following
* functionalities of the USB Peripheral Controller:
* + Initialization/de-initialization functions
* + I/O operation functions
* + Peripheral Control functions
* + Peripheral State functions
*
@verbatim
==============================================================================
##### How to use this driver #####
==============================================================================
[..]
(#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
(#) Call USB_CoreInit() API to initialize the USB Core peripheral.
(#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
@endverbatim
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx_hal.h"
/** @addtogroup STM32WBxx_LL_USB_DRIVER
* @{
*/
#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
#if defined (USB)
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the USB Core
* @param USBx USB Instance
* @param cfg pointer to a USB_CfgTypeDef structure that contains
* the configuration information for the specified USBx peripheral.
* @retval HAL status
*/
HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(USBx);
UNUSED(cfg);
/* NOTE : - This function is not required by USB Device FS peripheral, it is used
only by USB OTG FS peripheral.
- This function is added to ensure compatibility across platforms.
*/
return HAL_OK;
}
/**
* @brief USB_EnableGlobalInt
* Enables the controller's Global Int in the AHB Config reg
* @param USBx Selected device
* @retval HAL status
*/
HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
{
uint32_t winterruptmask;
/* Clear pending interrupts */
USBx->ISTR = 0U;
/* Set winterruptmask variable */
winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM |
USB_CNTR_SUSPM | USB_CNTR_ERRM |
USB_CNTR_SOFM | USB_CNTR_ESOFM |
USB_CNTR_RESETM | USB_CNTR_L1REQM;
/* Set interrupt mask */
USBx->CNTR = (uint16_t)winterruptmask;
return HAL_OK;
}
/**
* @brief USB_DisableGlobalInt
* Disable the controller's Global Int in the AHB Config reg
* @param USBx Selected device
* @retval HAL status
*/
HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
{
uint32_t winterruptmask;
/* Set winterruptmask variable */
winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM |
USB_CNTR_SUSPM | USB_CNTR_ERRM |
USB_CNTR_SOFM | USB_CNTR_ESOFM |
USB_CNTR_RESETM | USB_CNTR_L1REQM;
/* Clear interrupt mask */
USBx->CNTR &= (uint16_t)(~winterruptmask);
return HAL_OK;
}
/**
* @brief USB_SetCurrentMode Set functional mode
* @param USBx Selected device
* @param mode current core mode
* This parameter can be one of the these values:
* @arg USB_DEVICE_MODE Peripheral mode
* @retval HAL status
*/
HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(USBx);
UNUSED(mode);
/* NOTE : - This function is not required by USB Device FS peripheral, it is used
only by USB OTG FS peripheral.
- This function is added to ensure compatibility across platforms.
*/
return HAL_OK;
}
/**
* @brief USB_DevInit Initializes the USB controller registers
* for device mode
* @param USBx Selected device
* @param cfg pointer to a USB_CfgTypeDef structure that contains
* the configuration information for the specified USBx peripheral.
* @retval HAL status
*/
HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(cfg);
/* Init Device */
/* CNTR_FRES = 1 */
USBx->CNTR = (uint16_t)USB_CNTR_FRES;
/* CNTR_FRES = 0 */
USBx->CNTR = 0U;
/* Clear pending interrupts */
USBx->ISTR = 0U;
/*Set Btable Address*/
USBx->BTABLE = BTABLE_ADDRESS;
return HAL_OK;
}
#if defined (HAL_PCD_MODULE_ENABLED)
/**
* @brief Activate and configure an endpoint
* @param USBx Selected device
* @param ep pointer to endpoint structure
* @retval HAL status
*/
HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
{
HAL_StatusTypeDef ret = HAL_OK;
uint16_t wEpRegVal;
wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
/* initialize Endpoint */
switch (ep->type)
{
case EP_TYPE_CTRL:
wEpRegVal |= USB_EP_CONTROL;
break;
case EP_TYPE_BULK:
wEpRegVal |= USB_EP_BULK;
break;
case EP_TYPE_INTR:
wEpRegVal |= USB_EP_INTERRUPT;
break;
case EP_TYPE_ISOC:
wEpRegVal |= USB_EP_ISOCHRONOUS;
break;
default:
ret = HAL_ERROR;
break;
}
PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
if (ep->doublebuffer == 0U)
{
if (ep->is_in != 0U)
{
/*Set the endpoint Transmit buffer address */
PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
PCD_CLEAR_TX_DTOG(USBx, ep->num);
if (ep->type != EP_TYPE_ISOC)
{
/* Configure NAK status for the Endpoint */
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
}
else
{
/* Configure TX Endpoint to disabled state */
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
}
}
else
{
/*Set the endpoint Receive buffer address */
PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
/*Set the endpoint Receive buffer counter*/
PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
PCD_CLEAR_RX_DTOG(USBx, ep->num);
/* Configure VALID status for the Endpoint*/
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
}
}
/*Double Buffer*/
else
{
/* Set the endpoint as double buffered */
PCD_SET_EP_DBUF(USBx, ep->num);
/* Set buffer address for double buffered mode */
PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
if (ep->is_in == 0U)
{
/* Clear the data toggle bits for the endpoint IN/OUT */
PCD_CLEAR_RX_DTOG(USBx, ep->num);
PCD_CLEAR_TX_DTOG(USBx, ep->num);
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
}
else
{
/* Clear the data toggle bits for the endpoint IN/OUT */
PCD_CLEAR_RX_DTOG(USBx, ep->num);
PCD_CLEAR_TX_DTOG(USBx, ep->num);
if (ep->type != EP_TYPE_ISOC)
{
/* Configure NAK status for the Endpoint */
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
}
else
{
/* Configure TX Endpoint to disabled state */
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
}
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
}
}
return ret;
}
/**
* @brief De-activate and de-initialize an endpoint
* @param USBx Selected device
* @param ep pointer to endpoint structure
* @retval HAL status
*/
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
{
if (ep->doublebuffer == 0U)
{
if (ep->is_in != 0U)
{
PCD_CLEAR_TX_DTOG(USBx, ep->num);
/* Configure DISABLE status for the Endpoint*/
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
}
else
{
PCD_CLEAR_RX_DTOG(USBx, ep->num);
/* Configure DISABLE status for the Endpoint*/
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
}
}
/*Double Buffer*/
else
{
if (ep->is_in == 0U)
{
/* Clear the data toggle bits for the endpoint IN/OUT*/
PCD_CLEAR_RX_DTOG(USBx, ep->num);
PCD_CLEAR_TX_DTOG(USBx, ep->num);
/* Reset value of the data toggle bits for the endpoint out*/
PCD_TX_DTOG(USBx, ep->num);
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
}
else
{
/* Clear the data toggle bits for the endpoint IN/OUT*/
PCD_CLEAR_RX_DTOG(USBx, ep->num);
PCD_CLEAR_TX_DTOG(USBx, ep->num);
PCD_RX_DTOG(USBx, ep->num);
/* Configure DISABLE status for the Endpoint*/
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
}
}
return HAL_OK;
}
/**
* @brief USB_EPStartXfer setup and starts a transfer over an EP
* @param USBx Selected device
* @param ep pointer to endpoint structure
* @retval HAL status
*/
HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
{
uint32_t len;
uint16_t pmabuffer;
uint16_t wEPVal;
/* IN endpoint */
if (ep->is_in == 1U)
{
/*Multi packet transfer*/
if (ep->xfer_len > ep->maxpacket)
{
len = ep->maxpacket;
}
else
{
len = ep->xfer_len;
}
/* configure and validate Tx endpoint */
if (ep->doublebuffer == 0U)
{
USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
PCD_SET_EP_TX_CNT(USBx, ep->num, len);
}
else
{
/* double buffer bulk management */
if (ep->type == EP_TYPE_BULK)
{
if (ep->xfer_len_db > ep->maxpacket)
{
/* enable double buffer */
PCD_SET_EP_DBUF(USBx, ep->num);
/* each Time to write in PMA xfer_len_db will */
ep->xfer_len_db -= len;
/* Fill the two first buffer in the Buffer0 & Buffer1 */
if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
{
/* Set the Double buffer counter for pmabuffer1 */
PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
pmabuffer = ep->pmaaddr1;
/* Write the user buffer to USB PMA */
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
ep->xfer_buff += len;
if (ep->xfer_len_db > ep->maxpacket)
{
ep->xfer_len_db -= len;
}
else
{
len = ep->xfer_len_db;
ep->xfer_len_db = 0U;
}
/* Set the Double buffer counter for pmabuffer0 */
PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
pmabuffer = ep->pmaaddr0;
/* Write the user buffer to USB PMA */
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
}
else
{
/* Set the Double buffer counter for pmabuffer0 */
PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
pmabuffer = ep->pmaaddr0;
/* Write the user buffer to USB PMA */
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
ep->xfer_buff += len;
if (ep->xfer_len_db > ep->maxpacket)
{
ep->xfer_len_db -= len;
}
else
{
len = ep->xfer_len_db;
ep->xfer_len_db = 0U;
}
/* Set the Double buffer counter for pmabuffer1 */
PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
pmabuffer = ep->pmaaddr1;
/* Write the user buffer to USB PMA */
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
}
}
/* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
else
{
len = ep->xfer_len_db;
/* disable double buffer mode */
PCD_CLEAR_EP_DBUF(USBx, ep->num);
/* Set Tx count with nbre of byte to be transmitted */
PCD_SET_EP_TX_CNT(USBx, ep->num, len);
pmabuffer = ep->pmaaddr0;
/* Write the user buffer to USB PMA */
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
}
}/* end if bulk double buffer */
/* manage isochronous double buffer IN mode */
else
{
/* enable double buffer */
PCD_SET_EP_DBUF(USBx, ep->num);
/* each Time to write in PMA xfer_len_db will */
ep->xfer_len_db -= len;
/* Fill the data buffer */
if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
{
/* Set the Double buffer counter for pmabuffer1 */
PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
pmabuffer = ep->pmaaddr1;
/* Write the user buffer to USB PMA */
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
ep->xfer_buff += len;
if (ep->xfer_len_db > ep->maxpacket)
{
ep->xfer_len_db -= len;
}
else
{
len = ep->xfer_len_db;
ep->xfer_len_db = 0U;
}
if (len > 0U)
{
/* Set the Double buffer counter for pmabuffer0 */
PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
pmabuffer = ep->pmaaddr0;
/* Write the user buffer to USB PMA */
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
}
}
else
{
/* Set the Double buffer counter for pmabuffer0 */
PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
pmabuffer = ep->pmaaddr0;
/* Write the user buffer to USB PMA */
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
ep->xfer_buff += len;
if (ep->xfer_len_db > ep->maxpacket)
{
ep->xfer_len_db -= len;
}
else
{
len = ep->xfer_len_db;
ep->xfer_len_db = 0U;
}
if (len > 0U)
{
/* Set the Double buffer counter for pmabuffer1 */
PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
pmabuffer = ep->pmaaddr1;
/* Write the user buffer to USB PMA */
USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
}
}
}
}
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
}
else /* OUT endpoint */
{
if (ep->doublebuffer == 0U)
{
/* Multi packet transfer */
if (ep->xfer_len > ep->maxpacket)
{
len = ep->maxpacket;
ep->xfer_len -= len;
}
else
{
len = ep->xfer_len;
ep->xfer_len = 0U;
}
/* configure and validate Rx endpoint */
PCD_SET_EP_RX_CNT(USBx, ep->num, len);
}
else
{
/* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
/* Set the Double buffer counter */
if (ep->type == EP_TYPE_BULK)
{
PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
/* Coming from ISR */
if (ep->xfer_count != 0U)
{
/* update last value to check if there is blocking state */
wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
/*Blocking State */
if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
(((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
{
PCD_FreeUserBuffer(USBx, ep->num, 0U);
}
}
}
/* iso out double */
else if (ep->type == EP_TYPE_ISOC)
{
/* Multi packet transfer */
if (ep->xfer_len > ep->maxpacket)
{
len = ep->maxpacket;
ep->xfer_len -= len;
}
else
{
len = ep->xfer_len;
ep->xfer_len = 0U;
}
PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
}
else
{
return HAL_ERROR;
}
}
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
}
return HAL_OK;
}
/**
* @brief USB_EPSetStall set a stall condition over an EP
* @param USBx Selected device
* @param ep pointer to endpoint structure
* @retval HAL status
*/
HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
{
if (ep->is_in != 0U)
{
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
}
else
{
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
}
return HAL_OK;
}
/**
* @brief USB_EPClearStall Clear a stall condition over an EP
* @param USBx Selected device
* @param ep pointer to endpoint structure
* @retval HAL status
*/
HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
{
if (ep->doublebuffer == 0U)
{
if (ep->is_in != 0U)
{
PCD_CLEAR_TX_DTOG(USBx, ep->num);
if (ep->type != EP_TYPE_ISOC)
{
/* Configure NAK status for the Endpoint */
PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
}
}
else
{
PCD_CLEAR_RX_DTOG(USBx, ep->num);
/* Configure VALID status for the Endpoint */
PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
}
}
return HAL_OK;
}
#endif
/**
* @brief USB_StopDevice Stop the usb device mode
* @param USBx Selected device
* @retval HAL status
*/
HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
{
/* disable all interrupts and force USB reset */
USBx->CNTR = (uint16_t)USB_CNTR_FRES;
/* clear interrupt status register */
USBx->ISTR = 0U;
/* switch-off device */
USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
return HAL_OK;
}
/**
* @brief USB_SetDevAddress Stop the usb device mode
* @param USBx Selected device
* @param address new device address to be assigned
* This parameter can be a value from 0 to 255
* @retval HAL status
*/
HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
{
if (address == 0U)
{
/* set device address and enable function */
USBx->DADDR = (uint16_t)USB_DADDR_EF;
}
return HAL_OK;
}
/**
* @brief USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
* @param USBx Selected device
* @retval HAL status
*/
HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx)
{
/* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */
USBx->BCDR |= (uint16_t)USB_BCDR_DPPU;
return HAL_OK;
}
/**
* @brief USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
* @param USBx Selected device
* @retval HAL status
*/
HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx)
{
/* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */
USBx->BCDR &= (uint16_t)(~(USB_BCDR_DPPU));
return HAL_OK;
}
/**
* @brief USB_ReadInterrupts return the global USB interrupt status
* @param USBx Selected device
* @retval HAL status
*/
uint32_t USB_ReadInterrupts(USB_TypeDef *USBx)
{
uint32_t tmpreg;
tmpreg = USBx->ISTR;
return tmpreg;
}
/**
* @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
* @param USBx Selected device
* @retval HAL status
*/
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
{
USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
return HAL_OK;
}
/**
* @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
* @param USBx Selected device
* @retval HAL status
*/
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
{
USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
return HAL_OK;
}
/**
* @brief Copy a buffer from user memory area to packet memory area (PMA)
* @param USBx USB peripheral instance register address.
* @param pbUsrBuf pointer to user memory area.
* @param wPMABufAddr address into PMA.
* @param wNBytes no. of bytes to be copied.
* @retval None
*/
void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
uint32_t BaseAddr = (uint32_t)USBx;
uint32_t i, temp1, temp2;
__IO uint16_t *pdwVal;
uint8_t *pBuf = pbUsrBuf;
pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
for (i = n; i != 0U; i--)
{
temp1 = *pBuf;
pBuf++;
temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
*pdwVal = (uint16_t)temp2;
pdwVal++;
#if PMA_ACCESS > 1U
pdwVal++;
#endif
pBuf++;
}
}
/**
* @brief Copy data from packet memory area (PMA) to user memory buffer
* @param USBx USB peripheral instance register address.
* @param pbUsrBuf pointer to user memory area.
* @param wPMABufAddr address into PMA.
* @param wNBytes no. of bytes to be copied.
* @retval None
*/
void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
uint32_t n = (uint32_t)wNBytes >> 1;
uint32_t BaseAddr = (uint32_t)USBx;
uint32_t i, temp;
__IO uint16_t *pdwVal;
uint8_t *pBuf = pbUsrBuf;
pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
for (i = n; i != 0U; i--)
{
temp = *(__IO uint16_t *)pdwVal;
pdwVal++;
*pBuf = (uint8_t)((temp >> 0) & 0xFFU);
pBuf++;
*pBuf = (uint8_t)((temp >> 8) & 0xFFU);
pBuf++;
#if PMA_ACCESS > 1U
pdwVal++;
#endif
}
if ((wNBytes % 2U) != 0U)
{
temp = *pdwVal;
*pBuf = (uint8_t)((temp >> 0) & 0xFFU);
}
}
/**
* @}
*/
/**
* @}
*/
#endif /* defined (USB) */
#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

175
nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h

@ -0,0 +1,175 @@
/**
******************************************************************************
* @file usbd_cdc.h
* @author MCD Application Team
* @brief header file for the usbd_cdc.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CDC_H
#define __USB_CDC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_ioreq.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup usbd_cdc
* @brief This file is the Header file for usbd_cdc.c
* @{
*/
/** @defgroup usbd_cdc_Exported_Defines
* @{
*/
#define CDC_IN_EP 0x81U /* EP1 for data IN */
#define CDC_OUT_EP 0x01U /* EP1 for data OUT */
#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */
#ifndef CDC_HS_BINTERVAL
#define CDC_HS_BINTERVAL 0x10U
#endif /* CDC_HS_BINTERVAL */
#ifndef CDC_FS_BINTERVAL
#define CDC_FS_BINTERVAL 0x10U
#endif /* CDC_FS_BINTERVAL */
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
#define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
#define USB_CDC_CONFIG_DESC_SIZ 67U
#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
#define CDC_REQ_MAX_DATA_SIZE 0x7U
/*---------------------------------------------------------------------*/
/* CDC definitions */
/*---------------------------------------------------------------------*/
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U
#define CDC_SET_COMM_FEATURE 0x02U
#define CDC_GET_COMM_FEATURE 0x03U
#define CDC_CLEAR_COMM_FEATURE 0x04U
#define CDC_SET_LINE_CODING 0x20U
#define CDC_GET_LINE_CODING 0x21U
#define CDC_SET_CONTROL_LINE_STATE 0x22U
#define CDC_SEND_BREAK 0x23U
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
typedef struct
{
uint32_t bitrate;
uint8_t format;
uint8_t paritytype;
uint8_t datatype;
} USBD_CDC_LineCodingTypeDef;
typedef struct _USBD_CDC_Itf
{
int8_t (* Init)(void);
int8_t (* DeInit)(void);
int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length);
int8_t (* Receive)(uint8_t *Buf, uint32_t *Len);
int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
} USBD_CDC_ItfTypeDef;
typedef struct
{
uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */
uint8_t CmdOpCode;
uint8_t CmdLength;
uint8_t *RxBuffer;
uint8_t *TxBuffer;
uint32_t RxLength;
uint32_t TxLength;
__IO uint32_t TxState;
__IO uint32_t RxState;
} USBD_CDC_HandleTypeDef;
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern USBD_ClassTypeDef USBD_CDC;
#define USBD_CDC_CLASS &USBD_CDC
/**
* @}
*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_CDC_ItfTypeDef *fops);
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
uint32_t length);
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USB_CDC_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

968
nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c

@ -0,0 +1,968 @@
/**
******************************************************************************
* @file usbd_cdc.c
* @author MCD Application Team
* @brief This file provides the high layer firmware functions to manage the
* following functionalities of the USB CDC Class:
* - Initialization and Configuration of high and low layer
* - Enumeration as CDC Device (and enumeration for each implemented memory interface)
* - OUT/IN data transfer
* - Command IN transfer (class requests management)
* - Error management
*
* @verbatim
*
* ===================================================================
* CDC Class Driver Description
* ===================================================================
* This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
* Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
* Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
* This driver implements the following aspects of the specification:
* - Device descriptor management
* - Configuration descriptor management
* - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
* - Requests management (as described in section 6.2 in specification)
* - Abstract Control Model compliant
* - Union Functional collection (using 1 IN endpoint for control)
* - Data interface class
*
* These aspects may be enriched or modified for a specific user application.
*
* This driver doesn't implement the following aspects of the specification
* (but it is possible to manage these features with some modifications on this driver):
* - Any class-specific aspect relative to communication classes should be managed by user application.
* - All communication classes other than PSTN are not managed
*
* @endverbatim
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc.h"
#include "usbd_ctlreq.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_CDC
* @brief usbd core module
* @{
*/
/** @defgroup USBD_CDC_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CDC_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CDC_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CDC_Private_FunctionPrototypes
* @{
*/
static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
{
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
};
/**
* @}
*/
/** @defgroup USBD_CDC_Private_Variables
* @{
*/
/* CDC interface class callbacks structure */
USBD_ClassTypeDef USBD_CDC =
{
USBD_CDC_Init,
USBD_CDC_DeInit,
USBD_CDC_Setup,
NULL, /* EP0_TxSent, */
USBD_CDC_EP0_RxReady,
USBD_CDC_DataIn,
USBD_CDC_DataOut,
NULL,
NULL,
NULL,
USBD_CDC_GetHSCfgDesc,
USBD_CDC_GetFSCfgDesc,
USBD_CDC_GetOtherSpeedCfgDesc,
USBD_CDC_GetDeviceQualifierDescriptor,
};
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x02, /* bNumInterfaces: 2 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower 100 mA */
/*---------------------------------------------------------------------------*/
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/* Call Management Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/* ACM Functional Descriptor */
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/* Union Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/* Endpoint 2 Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_CMD_PACKET_SIZE),
CDC_HS_BINTERVAL, /* bInterval: */
/*---------------------------------------------------------------------------*/
/* Data class interface descriptor */
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass: */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface: */
/* Endpoint OUT Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
0x00, /* bInterval: ignore for Bulk transfer */
/* Endpoint IN Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
0x00 /* bInterval: ignore for Bulk transfer */
};
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x02, /* bNumInterfaces: 2 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower 100 mA */
/*---------------------------------------------------------------------------*/
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/* Call Management Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/* ACM Functional Descriptor */
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/* Union Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/* Endpoint 2 Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_CMD_PACKET_SIZE),
CDC_FS_BINTERVAL, /* bInterval: */
/*---------------------------------------------------------------------------*/
/* Data class interface descriptor */
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass: */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface: */
/* Endpoint OUT Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
0x00, /* bInterval: ignore for Bulk transfer */
/* Endpoint IN Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
0x00 /* bInterval: ignore for Bulk transfer */
};
__ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
USB_CDC_CONFIG_DESC_SIZ,
0x00,
0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: */
0x04, /* iConfiguration: */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif
USBD_MAX_POWER, /* MaxPower 100 mA */
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/*Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/*ACM Functional Descriptor*/
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
HIBYTE(CDC_CMD_PACKET_SIZE),
CDC_FS_BINTERVAL, /* bInterval: */
/*---------------------------------------------------------------------------*/
/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass: */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface: */
/*Endpoint OUT Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize: */
0x00,
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize: */
0x00,
0x00 /* bInterval */
};
/**
* @}
*/
/** @defgroup USBD_CDC_Private_Functions
* @{
*/
/**
* @brief USBD_CDC_Init
* Initialize the CDC interface
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
USBD_CDC_HandleTypeDef *hcdc;
hcdc = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
if (hcdc == NULL)
{
pdev->pClassData = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassData = (void *)hcdc;
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
CDC_DATA_HS_IN_PACKET_SIZE);
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
CDC_DATA_HS_OUT_PACKET_SIZE);
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
/* Set bInterval for CDC CMD Endpoint */
pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL;
}
else
{
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
CDC_DATA_FS_IN_PACKET_SIZE);
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
CDC_DATA_FS_OUT_PACKET_SIZE);
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
/* Set bInterval for CMD Endpoint */
pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL;
}
/* Open Command IN EP */
(void)USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U;
/* Init physical Interface components */
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
/* Init Xfer states */
hcdc->TxState = 0U;
hcdc->RxState = 0U;
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
CDC_DATA_HS_OUT_PACKET_SIZE);
}
else
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
CDC_DATA_FS_OUT_PACKET_SIZE);
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_Init
* DeInitialize the CDC layer
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, CDC_IN_EP);
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U;
/* Close EP OUT */
(void)USBD_LL_CloseEP(pdev, CDC_OUT_EP);
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U;
/* Close Command IN EP */
(void)USBD_LL_CloseEP(pdev, CDC_CMD_EP);
pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U;
pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = 0U;
/* DeInit physical Interface components */
if (pdev->pClassData != NULL)
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
(void)USBD_free(pdev->pClassData);
pdev->pClassData = NULL;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_Setup
* Handle the CDC specific requests
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
uint16_t len;
uint8_t ifalt = 0U;
uint16_t status_info = 0U;
USBD_StatusTypeDef ret = USBD_OK;
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS:
if (req->wLength != 0U)
{
if ((req->bmRequest & 0x80U) != 0U)
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
(uint8_t *)hcdc->data,
req->wLength);
len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength);
(void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len);
}
else
{
hcdc->CmdOpCode = req->bRequest;
hcdc->CmdLength = (uint8_t)req->wLength;
(void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength);
}
}
else
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
(uint8_t *)req, 0U);
}
break;
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_STATUS:
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
}
else
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_GET_INTERFACE:
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
(void)USBD_CtlSendData(pdev, &ifalt, 1U);
}
else
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_SET_INTERFACE:
if (pdev->dev_state != USBD_STATE_CONFIGURED)
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_CLEAR_FEATURE:
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
return (uint8_t)ret;
}
/**
* @brief USBD_CDC_DataIn
* Data sent on non-control IN endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_HandleTypeDef *hcdc;
PCD_HandleTypeDef *hpcd = pdev->pData;
if (pdev->pClassData == NULL)
{
return (uint8_t)USBD_FAIL;
}
hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
if ((pdev->ep_in[epnum].total_length > 0U) &&
((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
{
/* Update the packet total length */
pdev->ep_in[epnum].total_length = 0U;
/* Send ZLP */
(void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
}
else
{
hcdc->TxState = 0U;
if (((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL)
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
}
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_DataOut
* Data received on non-control Out endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
if (pdev->pClassData == NULL)
{
return (uint8_t)USBD_FAIL;
}
/* Get the received data length */
hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application Xfer */
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_EP0_RxReady
* Handle EP0 Rx Ready event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU))
{
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
(uint8_t *)hcdc->data,
(uint16_t)hcdc->CmdLength);
hcdc->CmdOpCode = 0xFFU;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_GetFSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc);
return USBD_CDC_CfgFSDesc;
}
/**
* @brief USBD_CDC_GetHSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc);
return USBD_CDC_CfgHSDesc;
}
/**
* @brief USBD_CDC_GetOtherSpeedCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_OtherSpeedCfgDesc);
return USBD_CDC_OtherSpeedCfgDesc;
}
/**
* @brief USBD_CDC_GetDeviceQualifierDescriptor
* return Device Qualifier descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc);
return USBD_CDC_DeviceQualifierDesc;
}
/**
* @brief USBD_CDC_RegisterInterface
* @param pdev: device instance
* @param fops: CD Interface callback
* @retval status
*/
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_CDC_ItfTypeDef *fops)
{
if (fops == NULL)
{
return (uint8_t)USBD_FAIL;
}
pdev->pUserData = fops;
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_SetTxBuffer
* @param pdev: device instance
* @param pbuff: Tx Buffer
* @retval status
*/
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
uint8_t *pbuff, uint32_t length)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
hcdc->TxBuffer = pbuff;
hcdc->TxLength = length;
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_SetRxBuffer
* @param pdev: device instance
* @param pbuff: Rx Buffer
* @retval status
*/
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
if (hcdc == NULL)
{
return (uint8_t)USBD_FAIL;
}
hcdc->RxBuffer = pbuff;
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_TransmitPacket
* Transmit packet on IN endpoint
* @param pdev: device instance
* @retval status
*/
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
USBD_StatusTypeDef ret = USBD_BUSY;
if (pdev->pClassData == NULL)
{
return (uint8_t)USBD_FAIL;
}
if (hcdc->TxState == 0U)
{
/* Tx Transfer in progress */
hcdc->TxState = 1U;
/* Update the packet total length */
pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength;
/* Transmit next packet */
(void)USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
ret = USBD_OK;
}
return (uint8_t)ret;
}
/**
* @brief USBD_CDC_ReceivePacket
* prepare OUT Endpoint for reception
* @param pdev: device instance
* @retval status
*/
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
if (pdev->pClassData == NULL)
{
return (uint8_t)USBD_FAIL;
}
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
CDC_DATA_HS_OUT_PACKET_SIZE);
}
else
{
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
CDC_DATA_FS_OUT_PACKET_SIZE);
}
return (uint8_t)USBD_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

158
nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h

@ -0,0 +1,158 @@
/**
******************************************************************************
* @file usbd_core.h
* @author MCD Application Team
* @brief Header file for usbd_core.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CORE_H
#define __USBD_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_conf.h"
#include "usbd_def.h"
#include "usbd_ioreq.h"
#include "usbd_ctlreq.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_CORE
* @brief This file is the Header file for usbd_core.c file
* @{
*/
/** @defgroup USBD_CORE_Exported_Defines
* @{
*/
#ifndef USBD_DEBUG_LEVEL
#define USBD_DEBUG_LEVEL 0U
#endif /* USBD_DEBUG_LEVEL */
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
#define USBD_SOF USBD_LL_SOF
/**
* @}
*/
/** @defgroup USBD_CORE_Exported_FunctionsPrototype
* @{
*/
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id);
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass);
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup);
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata);
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata);
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed);
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev);
/* USBD Low Level Driver */
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t ep_type, uint16_t ep_mps);
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr);
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t *pbuf, uint32_t size);
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t *pbuf, uint32_t size);
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
void USBD_LL_Delay(uint32_t Delay);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CORE_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

103
nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h

@ -0,0 +1,103 @@
/**
******************************************************************************
* @file usbd_req.h
* @author MCD Application Team
* @brief Header file for the usbd_req.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_REQUEST_H
#define __USB_REQUEST_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_REQ
* @brief header file for the usbd_req.c file
* @{
*/
/** @defgroup USBD_REQ_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Exported_FunctionsPrototype
* @{
*/
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata);
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USB_REQUEST_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

420
nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h

@ -0,0 +1,420 @@
/**
******************************************************************************
* @file usbd_def.h
* @author MCD Application Team
* @brief General defines for the usb device library
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_DEF_H
#define __USBD_DEF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_conf.h"
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
* @{
*/
/** @defgroup USB_DEF
* @brief general defines for the usb device library file
* @{
*/
/** @defgroup USB_DEF_Exported_Defines
* @{
*/
#ifndef NULL
#define NULL 0U
#endif /* NULL */
#ifndef USBD_MAX_NUM_INTERFACES
#define USBD_MAX_NUM_INTERFACES 1U
#endif /* USBD_MAX_NUM_CONFIGURATION */
#ifndef USBD_MAX_NUM_CONFIGURATION
#define USBD_MAX_NUM_CONFIGURATION 1U
#endif /* USBD_MAX_NUM_CONFIGURATION */
#ifndef USBD_LPM_ENABLED
#define USBD_LPM_ENABLED 0U
#endif /* USBD_LPM_ENABLED */
#ifndef USBD_SELF_POWERED
#define USBD_SELF_POWERED 1U
#endif /*USBD_SELF_POWERED */
#ifndef USBD_MAX_POWER
#define USBD_MAX_POWER 0x32U /* 100 mA */
#endif /* USBD_MAX_POWER */
#ifndef USBD_SUPPORT_USER_STRING_DESC
#define USBD_SUPPORT_USER_STRING_DESC 0U
#endif /* USBD_SUPPORT_USER_STRING_DESC */
#ifndef USBD_CLASS_USER_STRING_DESC
#define USBD_CLASS_USER_STRING_DESC 0U
#endif /* USBD_CLASS_USER_STRING_DESC */
#define USB_LEN_DEV_QUALIFIER_DESC 0x0AU
#define USB_LEN_DEV_DESC 0x12U
#define USB_LEN_CFG_DESC 0x09U
#define USB_LEN_IF_DESC 0x09U
#define USB_LEN_EP_DESC 0x07U
#define USB_LEN_OTG_DESC 0x03U
#define USB_LEN_LANGID_STR_DESC 0x04U
#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09U
#define USBD_IDX_LANGID_STR 0x00U
#define USBD_IDX_MFC_STR 0x01U
#define USBD_IDX_PRODUCT_STR 0x02U
#define USBD_IDX_SERIAL_STR 0x03U
#define USBD_IDX_CONFIG_STR 0x04U
#define USBD_IDX_INTERFACE_STR 0x05U
#define USB_REQ_TYPE_STANDARD 0x00U
#define USB_REQ_TYPE_CLASS 0x20U
#define USB_REQ_TYPE_VENDOR 0x40U
#define USB_REQ_TYPE_MASK 0x60U
#define USB_REQ_RECIPIENT_DEVICE 0x00U
#define USB_REQ_RECIPIENT_INTERFACE 0x01U
#define USB_REQ_RECIPIENT_ENDPOINT 0x02U
#define USB_REQ_RECIPIENT_MASK 0x03U
#define USB_REQ_GET_STATUS 0x00U
#define USB_REQ_CLEAR_FEATURE 0x01U
#define USB_REQ_SET_FEATURE 0x03U
#define USB_REQ_SET_ADDRESS 0x05U
#define USB_REQ_GET_DESCRIPTOR 0x06U
#define USB_REQ_SET_DESCRIPTOR 0x07U
#define USB_REQ_GET_CONFIGURATION 0x08U
#define USB_REQ_SET_CONFIGURATION 0x09U
#define USB_REQ_GET_INTERFACE 0x0AU
#define USB_REQ_SET_INTERFACE 0x0BU
#define USB_REQ_SYNCH_FRAME 0x0CU
#define USB_DESC_TYPE_DEVICE 0x01U
#define USB_DESC_TYPE_CONFIGURATION 0x02U
#define USB_DESC_TYPE_STRING 0x03U
#define USB_DESC_TYPE_INTERFACE 0x04U
#define USB_DESC_TYPE_ENDPOINT 0x05U
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U
#define USB_DESC_TYPE_IAD 0x0BU
#define USB_DESC_TYPE_BOS 0x0FU
#define USB_CONFIG_REMOTE_WAKEUP 0x02U
#define USB_CONFIG_SELF_POWERED 0x01U
#define USB_FEATURE_EP_HALT 0x00U
#define USB_FEATURE_REMOTE_WAKEUP 0x01U
#define USB_FEATURE_TEST_MODE 0x02U
#define USB_DEVICE_CAPABITY_TYPE 0x10U
#define USB_CONF_DESC_SIZE 0x09U
#define USB_IF_DESC_SIZE 0x09U
#define USB_EP_DESC_SIZE 0x07U
#define USB_IAD_DESC_SIZE 0x08U
#define USB_HS_MAX_PACKET_SIZE 512U
#define USB_FS_MAX_PACKET_SIZE 64U
#define USB_MAX_EP0_SIZE 64U
/* Device Status */
#define USBD_STATE_DEFAULT 0x01U
#define USBD_STATE_ADDRESSED 0x02U
#define USBD_STATE_CONFIGURED 0x03U
#define USBD_STATE_SUSPENDED 0x04U
/* EP0 State */
#define USBD_EP0_IDLE 0x00U
#define USBD_EP0_SETUP 0x01U
#define USBD_EP0_DATA_IN 0x02U
#define USBD_EP0_DATA_OUT 0x03U
#define USBD_EP0_STATUS_IN 0x04U
#define USBD_EP0_STATUS_OUT 0x05U
#define USBD_EP0_STALL 0x06U
#define USBD_EP_TYPE_CTRL 0x00U
#define USBD_EP_TYPE_ISOC 0x01U
#define USBD_EP_TYPE_BULK 0x02U
#define USBD_EP_TYPE_INTR 0x03U
/**
* @}
*/
/** @defgroup USBD_DEF_Exported_TypesDefinitions
* @{
*/
typedef struct usb_setup_req
{
uint8_t bmRequest;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} USBD_SetupReqTypedef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} USBD_ConfigDescTypedef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumDeviceCaps;
} USBD_BosDescTypedef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} USBD_EpDescTypedef;
struct _USBD_HandleTypeDef;
typedef struct _Device_cb
{
uint8_t (*Init)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx);
uint8_t (*DeInit)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx);
/* Control Endpoints*/
uint8_t (*Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
uint8_t (*EP0_TxSent)(struct _USBD_HandleTypeDef *pdev);
uint8_t (*EP0_RxReady)(struct _USBD_HandleTypeDef *pdev);
/* Class Specific Endpoints*/
uint8_t (*DataIn)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t (*DataOut)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t (*SOF)(struct _USBD_HandleTypeDef *pdev);
uint8_t (*IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t (*IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t *(*GetHSConfigDescriptor)(uint16_t *length);
uint8_t *(*GetFSConfigDescriptor)(uint16_t *length);
uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length);
uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length);
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length);
#endif
} USBD_ClassTypeDef;
/* Following USB Device Speed */
typedef enum
{
USBD_SPEED_HIGH = 0U,
USBD_SPEED_FULL = 1U,
USBD_SPEED_LOW = 2U,
} USBD_SpeedTypeDef;
/* Following USB Device status */
typedef enum
{
USBD_OK = 0U,
USBD_BUSY,
USBD_EMEM,
USBD_FAIL,
} USBD_StatusTypeDef;
/* USB Device descriptors structure */
typedef struct
{
uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#if (USBD_CLASS_USER_STRING_DESC == 1)
uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
#endif
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1))
uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#endif
} USBD_DescriptorsTypeDef;
/* USB Device handle structure */
typedef struct
{
uint32_t status;
uint32_t total_length;
uint32_t rem_length;
uint32_t maxpacket;
uint16_t is_used;
uint16_t bInterval;
} USBD_EndpointTypeDef;
/* USB Device handle structure */
typedef struct _USBD_HandleTypeDef
{
uint8_t id;
uint32_t dev_config;
uint32_t dev_default_config;
uint32_t dev_config_status;
USBD_SpeedTypeDef dev_speed;
USBD_EndpointTypeDef ep_in[16];
USBD_EndpointTypeDef ep_out[16];
__IO uint32_t ep0_state;
uint32_t ep0_data_len;
__IO uint8_t dev_state;
__IO uint8_t dev_old_state;
uint8_t dev_address;
uint8_t dev_connection_status;
uint8_t dev_test_mode;
uint32_t dev_remote_wakeup;
uint8_t ConfIdx;
USBD_SetupReqTypedef request;
USBD_DescriptorsTypeDef *pDesc;
USBD_ClassTypeDef *pClass;
void *pClassData;
void *pUserData;
void *pData;
void *pBosDesc;
void *pConfDesc;
} USBD_HandleTypeDef;
/**
* @}
*/
/** @defgroup USBD_DEF_Exported_Macros
* @{
*/
__STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr)
{
uint16_t _SwapVal, _Byte1, _Byte2;
uint8_t *_pbuff = addr;
_Byte1 = *(uint8_t *)_pbuff;
_pbuff++;
_Byte2 = *(uint8_t *)_pbuff;
_SwapVal = (_Byte2 << 8) | _Byte1;
return _SwapVal;
}
#ifndef LOBYTE
#define LOBYTE(x) ((uint8_t)((x) & 0x00FFU))
#endif
#ifndef HIBYTE
#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U))
#endif
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#if defined ( __GNUC__ )
#ifndef __weak
#define __weak __attribute__((weak))
#endif /* __weak */
#ifndef __packed
#define __packed __attribute__((__packed__))
#endif /* __packed */
#endif /* __GNUC__ */
/* In HS mode and when the DMA is used, all variables and data structures dealing
with the DMA during the transaction process should be 4-bytes aligned */
#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
#ifndef __ALIGN_END
#define __ALIGN_END __attribute__ ((aligned (4U)))
#endif /* __ALIGN_END */
#ifndef __ALIGN_BEGIN
#define __ALIGN_BEGIN
#endif /* __ALIGN_BEGIN */
#else
#ifndef __ALIGN_END
#define __ALIGN_END
#endif /* __ALIGN_END */
#ifndef __ALIGN_BEGIN
#if defined (__CC_ARM) /* ARM Compiler */
#define __ALIGN_BEGIN __align(4U)
#elif defined (__ICCARM__) /* IAR Compiler */
#define __ALIGN_BEGIN
#endif /* __CC_ARM */
#endif /* __ALIGN_BEGIN */
#endif /* __GNUC__ */
/**
* @}
*/
/** @defgroup USBD_DEF_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_DEF_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_DEF_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

114
nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h

@ -0,0 +1,114 @@
/**
******************************************************************************
* @file usbd_ioreq.h
* @author MCD Application Team
* @brief Header file for the usbd_ioreq.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_IOREQ_H
#define __USBD_IOREQ_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
#include "usbd_core.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_IOREQ
* @brief header file for the usbd_ioreq.c file
* @{
*/
/** @defgroup USBD_IOREQ_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype
* @{
*/
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len);
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len);
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len);
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len);
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev);
uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_IOREQ_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

694
nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c

@ -0,0 +1,694 @@
/**
******************************************************************************
* @file usbd_core.c
* @author MCD Application Team
* @brief This file provides all the USBD core functions.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_core.h"
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_CORE
* @brief usbd core module
* @{
*/
/** @defgroup USBD_CORE_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CORE_Private_Functions
* @{
*/
/**
* @brief USBD_Init
* Initializes the device stack and load the class driver
* @param pdev: device instance
* @param pdesc: Descriptor structure address
* @param id: Low level core index
* @retval None
*/
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
USBD_DescriptorsTypeDef *pdesc, uint8_t id)
{
USBD_StatusTypeDef ret;
/* Check whether the USB Host handle is valid */
if (pdev == NULL)
{
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Invalid Device handle");
#endif
return USBD_FAIL;
}
/* Unlink previous class resources */
pdev->pClass = NULL;
pdev->pUserData = NULL;
pdev->pConfDesc = NULL;
/* Assign USBD Descriptors */
if (pdesc != NULL)
{
pdev->pDesc = pdesc;
}
/* Set Device initial State */
pdev->dev_state = USBD_STATE_DEFAULT;
pdev->id = id;
/* Initialize low level driver */
ret = USBD_LL_Init(pdev);
return ret;
}
/**
* @brief USBD_DeInit
* Re-Initialize the device library
* @param pdev: device instance
* @retval status: status
*/
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
{
USBD_StatusTypeDef ret;
/* Disconnect the USB Device */
(void)USBD_LL_Stop(pdev);
/* Set Default State */
pdev->dev_state = USBD_STATE_DEFAULT;
/* Free Class Resources */
if (pdev->pClass != NULL)
{
pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
pdev->pClass = NULL;
pdev->pUserData = NULL;
}
/* Free Device descriptors resources */
pdev->pDesc = NULL;
pdev->pConfDesc = NULL;
/* DeInitialize low level driver */
ret = USBD_LL_DeInit(pdev);
return ret;
}
/**
* @brief USBD_RegisterClass
* Link class driver to Device Core.
* @param pDevice : Device Handle
* @param pclass: Class handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
{
uint16_t len = 0U;
if (pclass == NULL)
{
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Invalid Class handle");
#endif
return USBD_FAIL;
}
/* link the class to the USB Device handle */
pdev->pClass = pclass;
/* Get Device Configuration Descriptor */
#ifdef USE_USB_HS
if (pdev->pClass->GetHSConfigDescriptor != NULL)
{
pdev->pConfDesc = (void *)pdev->pClass->GetHSConfigDescriptor(&len);
}
#else /* Default USE_USB_FS */
if (pdev->pClass->GetFSConfigDescriptor != NULL)
{
pdev->pConfDesc = (void *)pdev->pClass->GetFSConfigDescriptor(&len);
}
#endif /* USE_USB_FS */
return USBD_OK;
}
/**
* @brief USBD_Start
* Start the USB Device Core.
* @param pdev: Device Handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev)
{
/* Start the low level driver */
return USBD_LL_Start(pdev);
}
/**
* @brief USBD_Stop
* Stop the USB Device Core.
* @param pdev: Device Handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev)
{
/* Disconnect USB Device */
(void)USBD_LL_Stop(pdev);
/* Free Class Resources */
if (pdev->pClass != NULL)
{
(void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
}
return USBD_OK;
}
/**
* @brief USBD_RunTestMode
* Launch test mode process
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev)
{
/* Prevent unused argument compilation warning */
UNUSED(pdev);
return USBD_OK;
}
/**
* @brief USBD_SetClassConfig
* Configure device and start the interface
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
USBD_StatusTypeDef ret = USBD_FAIL;
if (pdev->pClass != NULL)
{
/* Set configuration and Start the Class */
ret = (USBD_StatusTypeDef)pdev->pClass->Init(pdev, cfgidx);
}
return ret;
}
/**
* @brief USBD_ClrClassConfig
* Clear current configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status: USBD_StatusTypeDef
*/
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
/* Clear configuration and De-initialize the Class process */
if (pdev->pClass != NULL)
{
pdev->pClass->DeInit(pdev, cfgidx);
}
return USBD_OK;
}
/**
* @brief USBD_LL_SetupStage
* Handle the setup stage
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
{
USBD_StatusTypeDef ret;
USBD_ParseSetupRequest(&pdev->request, psetup);
pdev->ep0_state = USBD_EP0_SETUP;
pdev->ep0_data_len = pdev->request.wLength;
switch (pdev->request.bmRequest & 0x1FU)
{
case USB_REQ_RECIPIENT_DEVICE:
ret = USBD_StdDevReq(pdev, &pdev->request);
break;
case USB_REQ_RECIPIENT_INTERFACE:
ret = USBD_StdItfReq(pdev, &pdev->request);
break;
case USB_REQ_RECIPIENT_ENDPOINT:
ret = USBD_StdEPReq(pdev, &pdev->request);
break;
default:
ret = USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
break;
}
return ret;
}
/**
* @brief USBD_LL_DataOutStage
* Handle data OUT stage
* @param pdev: device instance
* @param epnum: endpoint index
* @param pdata: data pointer
* @retval status
*/
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
uint8_t epnum, uint8_t *pdata)
{
USBD_EndpointTypeDef *pep;
USBD_StatusTypeDef ret;
if (epnum == 0U)
{
pep = &pdev->ep_out[0];
if (pdev->ep0_state == USBD_EP0_DATA_OUT)
{
if (pep->rem_length > pep->maxpacket)
{
pep->rem_length -= pep->maxpacket;
(void)USBD_CtlContinueRx(pdev, pdata, MIN(pep->rem_length, pep->maxpacket));
}
else
{
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->EP0_RxReady != NULL)
{
pdev->pClass->EP0_RxReady(pdev);
}
}
(void)USBD_CtlSendStatus(pdev);
}
}
else
{
#if 0
if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
{
/*
* STATUS PHASE completed, update ep0_state to idle
*/
pdev->ep0_state = USBD_EP0_IDLE;
(void)USBD_LL_StallEP(pdev, 0U);
}
#endif
}
}
else
{
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->DataOut != NULL)
{
ret = (USBD_StatusTypeDef)pdev->pClass->DataOut(pdev, epnum);
if (ret != USBD_OK)
{
return ret;
}
}
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_DataInStage
* Handle data in stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev,
uint8_t epnum, uint8_t *pdata)
{
USBD_EndpointTypeDef *pep;
USBD_StatusTypeDef ret;
if (epnum == 0U)
{
pep = &pdev->ep_in[0];
if (pdev->ep0_state == USBD_EP0_DATA_IN)
{
if (pep->rem_length > pep->maxpacket)
{
pep->rem_length -= pep->maxpacket;
(void)USBD_CtlContinueSendData(pdev, pdata, pep->rem_length);
/* Prepare endpoint for premature end of transfer */
(void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
}
else
{
/* last packet is MPS multiple, so send ZLP packet */
if ((pep->maxpacket == pep->rem_length) &&
(pep->total_length >= pep->maxpacket) &&
(pep->total_length < pdev->ep0_data_len))
{
(void)USBD_CtlContinueSendData(pdev, NULL, 0U);
pdev->ep0_data_len = 0U;
/* Prepare endpoint for premature end of transfer */
(void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
}
else
{
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->EP0_TxSent != NULL)
{
pdev->pClass->EP0_TxSent(pdev);
}
}
(void)USBD_LL_StallEP(pdev, 0x80U);
(void)USBD_CtlReceiveStatus(pdev);
}
}
}
else
{
#if 0
if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
(pdev->ep0_state == USBD_EP0_IDLE))
{
(void)USBD_LL_StallEP(pdev, 0x80U);
}
#endif
}
if (pdev->dev_test_mode == 1U)
{
(void)USBD_RunTestMode(pdev);
pdev->dev_test_mode = 0U;
}
}
else
{
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->DataIn != NULL)
{
ret = (USBD_StatusTypeDef)pdev->pClass->DataIn(pdev, epnum);
if (ret != USBD_OK)
{
return ret;
}
}
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_Reset
* Handle Reset event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
{
/* Upon Reset call user call back */
pdev->dev_state = USBD_STATE_DEFAULT;
pdev->ep0_state = USBD_EP0_IDLE;
pdev->dev_config = 0U;
pdev->dev_remote_wakeup = 0U;
if (pdev->pClass == NULL)
{
return USBD_FAIL;
}
if (pdev->pClassData != NULL)
{
if (pdev->pClass->DeInit != NULL)
{
(void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
}
}
/* Open EP0 OUT */
(void)USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
pdev->ep_out[0x00U & 0xFU].is_used = 1U;
pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
/* Open EP0 IN */
(void)USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
pdev->ep_in[0x80U & 0xFU].is_used = 1U;
pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
return USBD_OK;
}
/**
* @brief USBD_LL_SetSpeed
* Handle Reset event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev,
USBD_SpeedTypeDef speed)
{
pdev->dev_speed = speed;
return USBD_OK;
}
/**
* @brief USBD_LL_Suspend
* Handle Suspend event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
{
pdev->dev_old_state = pdev->dev_state;
pdev->dev_state = USBD_STATE_SUSPENDED;
return USBD_OK;
}
/**
* @brief USBD_LL_Resume
* Handle Resume event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
{
if (pdev->dev_state == USBD_STATE_SUSPENDED)
{
pdev->dev_state = pdev->dev_old_state;
}
return USBD_OK;
}
/**
* @brief USBD_LL_SOF
* Handle SOF event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
{
if (pdev->pClass == NULL)
{
return USBD_FAIL;
}
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->SOF != NULL)
{
(void)pdev->pClass->SOF(pdev);
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_IsoINIncomplete
* Handle iso in incomplete event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
if (pdev->pClass == NULL)
{
return USBD_FAIL;
}
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->IsoINIncomplete != NULL)
{
(void)pdev->pClass->IsoINIncomplete(pdev, epnum);
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_IsoOUTIncomplete
* Handle iso out incomplete event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
if (pdev->pClass == NULL)
{
return USBD_FAIL;
}
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (pdev->pClass->IsoOUTIncomplete != NULL)
{
(void)pdev->pClass->IsoOUTIncomplete(pdev, epnum);
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_DevConnected
* Handle device connection event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
{
/* Prevent unused argument compilation warning */
UNUSED(pdev);
return USBD_OK;
}
/**
* @brief USBD_LL_DevDisconnected
* Handle device disconnection event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
{
/* Free Class Resources */
pdev->dev_state = USBD_STATE_DEFAULT;
if (pdev->pClass != NULL)
{
(void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
}
return USBD_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

948
nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c

@ -0,0 +1,948 @@
/**
******************************************************************************
* @file usbd_req.c
* @author MCD Application Team
* @brief This file provides the standard USB requests following chapter 9.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_ctlreq.h"
#include "usbd_ioreq.h"
/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_REQ
* @brief USB standard requests module
* @{
*/
/** @defgroup USBD_REQ_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_REQ_Private_FunctionPrototypes
* @{
*/
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static uint8_t USBD_GetLen(uint8_t *buf);
/**
* @}
*/
/** @defgroup USBD_REQ_Private_Functions
* @{
*/
/**
* @brief USBD_StdDevReq
* Handle standard usb device requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_StatusTypeDef ret = USBD_OK;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS:
case USB_REQ_TYPE_VENDOR:
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
break;
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_DESCRIPTOR:
USBD_GetDescriptor(pdev, req);
break;
case USB_REQ_SET_ADDRESS:
USBD_SetAddress(pdev, req);
break;
case USB_REQ_SET_CONFIGURATION:
ret = USBD_SetConfig(pdev, req);
break;
case USB_REQ_GET_CONFIGURATION:
USBD_GetConfig(pdev, req);
break;
case USB_REQ_GET_STATUS:
USBD_GetStatus(pdev, req);
break;
case USB_REQ_SET_FEATURE:
USBD_SetFeature(pdev, req);
break;
case USB_REQ_CLEAR_FEATURE:
USBD_ClrFeature(pdev, req);
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
return ret;
}
/**
* @brief USBD_StdItfReq
* Handle standard usb interface requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_StatusTypeDef ret = USBD_OK;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS:
case USB_REQ_TYPE_VENDOR:
case USB_REQ_TYPE_STANDARD:
switch (pdev->dev_state)
{
case USBD_STATE_DEFAULT:
case USBD_STATE_ADDRESSED:
case USBD_STATE_CONFIGURED:
if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES)
{
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
if ((req->wLength == 0U) && (ret == USBD_OK))
{
(void)USBD_CtlSendStatus(pdev);
}
}
else
{
USBD_CtlError(pdev, req);
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
return ret;
}
/**
* @brief USBD_StdEPReq
* Handle standard usb endpoint requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_EndpointTypeDef *pep;
uint8_t ep_addr;
USBD_StatusTypeDef ret = USBD_OK;
ep_addr = LOBYTE(req->wIndex);
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS:
case USB_REQ_TYPE_VENDOR:
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
break;
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_SET_FEATURE:
switch (pdev->dev_state)
{
case USBD_STATE_ADDRESSED:
if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
{
(void)USBD_LL_StallEP(pdev, ep_addr);
(void)USBD_LL_StallEP(pdev, 0x80U);
}
else
{
USBD_CtlError(pdev, req);
}
break;
case USBD_STATE_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT)
{
if ((ep_addr != 0x00U) && (ep_addr != 0x80U) && (req->wLength == 0x00U))
{
(void)USBD_LL_StallEP(pdev, ep_addr);
}
}
(void)USBD_CtlSendStatus(pdev);
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
case USB_REQ_CLEAR_FEATURE:
switch (pdev->dev_state)
{
case USBD_STATE_ADDRESSED:
if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
{
(void)USBD_LL_StallEP(pdev, ep_addr);
(void)USBD_LL_StallEP(pdev, 0x80U);
}
else
{
USBD_CtlError(pdev, req);
}
break;
case USBD_STATE_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT)
{
if ((ep_addr & 0x7FU) != 0x00U)
{
(void)USBD_LL_ClearStallEP(pdev, ep_addr);
}
(void)USBD_CtlSendStatus(pdev);
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
case USB_REQ_GET_STATUS:
switch (pdev->dev_state)
{
case USBD_STATE_ADDRESSED:
if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
{
USBD_CtlError(pdev, req);
break;
}
pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \
&pdev->ep_out[ep_addr & 0x7FU];
pep->status = 0x0000U;
(void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U);
break;
case USBD_STATE_CONFIGURED:
if ((ep_addr & 0x80U) == 0x80U)
{
if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U)
{
USBD_CtlError(pdev, req);
break;
}
}
else
{
if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U)
{
USBD_CtlError(pdev, req);
break;
}
}
pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \
&pdev->ep_out[ep_addr & 0x7FU];
if ((ep_addr == 0x00U) || (ep_addr == 0x80U))
{
pep->status = 0x0000U;
}
else if (USBD_LL_IsStallEP(pdev, ep_addr) != 0U)
{
pep->status = 0x0001U;
}
else
{
pep->status = 0x0000U;
}
(void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U);
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
return ret;
}
/**
* @brief USBD_GetDescriptor
* Handle Get Descriptor requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
uint16_t len = 0U;
uint8_t *pbuf = NULL;
uint8_t err = 0U;
switch (req->wValue >> 8)
{
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U))
case USB_DESC_TYPE_BOS:
if (pdev->pDesc->GetBOSDescriptor != NULL)
{
pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
break;
#endif
case USB_DESC_TYPE_DEVICE:
pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
break;
case USB_DESC_TYPE_CONFIGURATION:
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
pbuf = pdev->pClass->GetHSConfigDescriptor(&len);
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
}
else
{
pbuf = pdev->pClass->GetFSConfigDescriptor(&len);
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
}
break;
case USB_DESC_TYPE_STRING:
switch ((uint8_t)(req->wValue))
{
case USBD_IDX_LANGID_STR:
if (pdev->pDesc->GetLangIDStrDescriptor != NULL)
{
pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_MFC_STR:
if (pdev->pDesc->GetManufacturerStrDescriptor != NULL)
{
pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_PRODUCT_STR:
if (pdev->pDesc->GetProductStrDescriptor != NULL)
{
pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_SERIAL_STR:
if (pdev->pDesc->GetSerialStrDescriptor != NULL)
{
pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_CONFIG_STR:
if (pdev->pDesc->GetConfigurationStrDescriptor != NULL)
{
pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_INTERFACE_STR:
if (pdev->pDesc->GetInterfaceStrDescriptor != NULL)
{
pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
break;
default:
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
if (pdev->pClass->GetUsrStrDescriptor != NULL)
{
pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
#endif
#if (USBD_CLASS_USER_STRING_DESC == 1U)
if (pdev->pDesc->GetUserStrDescriptor != NULL)
{
pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed, (req->wValue), &len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
#endif
#if ((USBD_CLASS_USER_STRING_DESC == 0U) && (USBD_SUPPORT_USER_STRING_DESC == 0U))
USBD_CtlError(pdev, req);
err++;
#endif
break;
}
break;
case USB_DESC_TYPE_DEVICE_QUALIFIER:
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len);
}
else
{
USBD_CtlError(pdev, req);
err++;
}
break;
case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
if (pdev->dev_speed == USBD_SPEED_HIGH)
{
pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
}
else
{
USBD_CtlError(pdev, req);
err++;
}
break;
default:
USBD_CtlError(pdev, req);
err++;
break;
}
if (err != 0U)
{
return;
}
if (req->wLength != 0U)
{
if (len != 0U)
{
len = MIN(len, req->wLength);
(void)USBD_CtlSendData(pdev, pbuf, len);
}
else
{
USBD_CtlError(pdev, req);
}
}
else
{
(void)USBD_CtlSendStatus(pdev);
}
}
/**
* @brief USBD_SetAddress
* Set device address
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
uint8_t dev_addr;
if ((req->wIndex == 0U) && (req->wLength == 0U) && (req->wValue < 128U))
{
dev_addr = (uint8_t)(req->wValue) & 0x7FU;
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
USBD_CtlError(pdev, req);
}
else
{
pdev->dev_address = dev_addr;
(void)USBD_LL_SetUSBAddress(pdev, dev_addr);
(void)USBD_CtlSendStatus(pdev);
if (dev_addr != 0U)
{
pdev->dev_state = USBD_STATE_ADDRESSED;
}
else
{
pdev->dev_state = USBD_STATE_DEFAULT;
}
}
}
else
{
USBD_CtlError(pdev, req);
}
}
/**
* @brief USBD_SetConfig
* Handle Set device configuration request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_StatusTypeDef ret = USBD_OK;
static uint8_t cfgidx;
cfgidx = (uint8_t)(req->wValue);
if (cfgidx > USBD_MAX_NUM_CONFIGURATION)
{
USBD_CtlError(pdev, req);
return USBD_FAIL;
}
switch (pdev->dev_state)
{
case USBD_STATE_ADDRESSED:
if (cfgidx != 0U)
{
pdev->dev_config = cfgidx;
ret = USBD_SetClassConfig(pdev, cfgidx);
if (ret != USBD_OK)
{
USBD_CtlError(pdev, req);
}
else
{
(void)USBD_CtlSendStatus(pdev);
pdev->dev_state = USBD_STATE_CONFIGURED;
}
}
else
{
(void)USBD_CtlSendStatus(pdev);
}
break;
case USBD_STATE_CONFIGURED:
if (cfgidx == 0U)
{
pdev->dev_state = USBD_STATE_ADDRESSED;
pdev->dev_config = cfgidx;
(void)USBD_ClrClassConfig(pdev, cfgidx);
(void)USBD_CtlSendStatus(pdev);
}
else if (cfgidx != pdev->dev_config)
{
/* Clear old configuration */
(void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config);
/* set new configuration */
pdev->dev_config = cfgidx;
ret = USBD_SetClassConfig(pdev, cfgidx);
if (ret != USBD_OK)
{
USBD_CtlError(pdev, req);
(void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config);
pdev->dev_state = USBD_STATE_ADDRESSED;
}
else
{
(void)USBD_CtlSendStatus(pdev);
}
}
else
{
(void)USBD_CtlSendStatus(pdev);
}
break;
default:
USBD_CtlError(pdev, req);
(void)USBD_ClrClassConfig(pdev, cfgidx);
ret = USBD_FAIL;
break;
}
return ret;
}
/**
* @brief USBD_GetConfig
* Handle Get device configuration request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
if (req->wLength != 1U)
{
USBD_CtlError(pdev, req);
}
else
{
switch (pdev->dev_state)
{
case USBD_STATE_DEFAULT:
case USBD_STATE_ADDRESSED:
pdev->dev_default_config = 0U;
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_default_config, 1U);
break;
case USBD_STATE_CONFIGURED:
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config, 1U);
break;
default:
USBD_CtlError(pdev, req);
break;
}
}
}
/**
* @brief USBD_GetStatus
* Handle Get Status request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
switch (pdev->dev_state)
{
case USBD_STATE_DEFAULT:
case USBD_STATE_ADDRESSED:
case USBD_STATE_CONFIGURED:
if (req->wLength != 0x2U)
{
USBD_CtlError(pdev, req);
break;
}
#if (USBD_SELF_POWERED == 1U)
pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
#else
pdev->dev_config_status = 0U;
#endif
if (pdev->dev_remote_wakeup != 0U)
{
pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
}
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config_status, 2U);
break;
default:
USBD_CtlError(pdev, req);
break;
}
}
/**
* @brief USBD_SetFeature
* Handle Set device feature request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
{
pdev->dev_remote_wakeup = 1U;
(void)USBD_CtlSendStatus(pdev);
}
}
/**
* @brief USBD_ClrFeature
* Handle clear device feature request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
switch (pdev->dev_state)
{
case USBD_STATE_DEFAULT:
case USBD_STATE_ADDRESSED:
case USBD_STATE_CONFIGURED:
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
{
pdev->dev_remote_wakeup = 0U;
(void)USBD_CtlSendStatus(pdev);
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
}
/**
* @brief USBD_ParseSetupRequest
* Copy buffer into setup structure
* @param pdev: device instance
* @param req: usb request
* @retval None
*/
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
{
uint8_t *pbuff = pdata;
req->bmRequest = *(uint8_t *)(pbuff);
pbuff++;
req->bRequest = *(uint8_t *)(pbuff);
pbuff++;
req->wValue = SWAPBYTE(pbuff);
pbuff++;
pbuff++;
req->wIndex = SWAPBYTE(pbuff);
pbuff++;
pbuff++;
req->wLength = SWAPBYTE(pbuff);
}
/**
* @brief USBD_CtlError
* Handle USB low level Error
* @param pdev: device instance
* @param req: usb request
* @retval None
*/
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
UNUSED(req);
(void)USBD_LL_StallEP(pdev, 0x80U);
(void)USBD_LL_StallEP(pdev, 0U);
}
/**
* @brief USBD_GetString
* Convert Ascii string into unicode one
* @param desc : descriptor buffer
* @param unicode : Formatted string buffer (unicode)
* @param len : descriptor length
* @retval None
*/
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
{
uint8_t idx = 0U;
uint8_t *pdesc;
if (desc == NULL)
{
return;
}
pdesc = desc;
*len = ((uint16_t)USBD_GetLen(pdesc) * 2U) + 2U;
unicode[idx] = *(uint8_t *)len;
idx++;
unicode[idx] = USB_DESC_TYPE_STRING;
idx++;
while (*pdesc != (uint8_t)'\0')
{
unicode[idx] = *pdesc;
pdesc++;
idx++;
unicode[idx] = 0U;
idx++;
}
}
/**
* @brief USBD_GetLen
* return the string length
* @param buf : pointer to the ascii string buffer
* @retval string length
*/
static uint8_t USBD_GetLen(uint8_t *buf)
{
uint8_t len = 0U;
uint8_t *pbuff = buf;
while (*pbuff != (uint8_t)'\0')
{
len++;
pbuff++;
}
return len;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

226
nucleo-wb55-ble/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c

@ -0,0 +1,226 @@
/**
******************************************************************************
* @file usbd_ioreq.c
* @author MCD Application Team
* @brief This file provides the IO requests APIs for control endpoints.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_ioreq.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_IOREQ
* @brief control I/O requests module
* @{
*/
/** @defgroup USBD_IOREQ_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USBD_IOREQ_Private_Functions
* @{
*/
/**
* @brief USBD_CtlSendData
* send data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be sent
* @retval status
*/
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len)
{
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_DATA_IN;
pdev->ep_in[0].total_length = len;
#ifdef USBD_AVOID_PACKET_SPLIT_MPS
pdev->ep_in[0].rem_length = 0U;
#else
pdev->ep_in[0].rem_length = len;
#endif
/* Start the transfer */
(void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len);
return USBD_OK;
}
/**
* @brief USBD_CtlContinueSendData
* continue sending data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be sent
* @retval status
*/
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len)
{
/* Start the next transfer */
(void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len);
return USBD_OK;
}
/**
* @brief USBD_CtlPrepareRx
* receive data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be received
* @retval status
*/
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len)
{
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_DATA_OUT;
pdev->ep_out[0].total_length = len;
#ifdef USBD_AVOID_PACKET_SPLIT_MPS
pdev->ep_out[0].rem_length = 0U;
#else
pdev->ep_out[0].rem_length = len;
#endif
/* Start the transfer */
(void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len);
return USBD_OK;
}
/**
* @brief USBD_CtlContinueRx
* continue receive data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be received
* @retval status
*/
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len)
{
(void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len);
return USBD_OK;
}
/**
* @brief USBD_CtlSendStatus
* send zero lzngth packet on the ctl pipe
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev)
{
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_STATUS_IN;
/* Start the transfer */
(void)USBD_LL_Transmit(pdev, 0x00U, NULL, 0U);
return USBD_OK;
}
/**
* @brief USBD_CtlReceiveStatus
* receive zero lzngth packet on the ctl pipe
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev)
{
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_STATUS_OUT;
/* Start the transfer */
(void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
return USBD_OK;
}
/**
* @brief USBD_GetRxCount
* returns the received data length
* @param pdev: device instance
* @param ep_addr: endpoint address
* @retval Rx Data blength
*/
uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
return USBD_LL_GetRxDataSize(pdev, ep_addr);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

99
nucleo-wb55-ble/USB_Device/App/usb_device.c

@ -0,0 +1,99 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usb_device.c
* @version : v3.0_Cube
* @brief : This file implements the USB Device
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usb_device.h"
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_cdc.h"
#include "usbd_cdc_if.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
extern void Error_Handler(void);
/* USB Device Core handle declaration. */
USBD_HandleTypeDef hUsbDeviceFS;
extern USBD_DescriptorsTypeDef CDC_Desc;
/*
* -- Insert your variables declaration here --
*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*
* -- Insert your external function declaration here --
*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Init USB device Library, add supported class and start the library
* @retval None
*/
void MX_USB_Device_Init(void)
{
/* USER CODE BEGIN USB_Device_Init_PreTreatment */
/* USER CODE END USB_Device_Init_PreTreatment */
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &CDC_Desc, DEVICE_FS) != USBD_OK) {
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) {
Error_Handler();
}
if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK) {
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
Error_Handler();
}
/* USER CODE BEGIN USB_Device_Init_PostTreatment */
/* USER CODE END USB_Device_Init_PostTreatment */
}
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

105
nucleo-wb55-ble/USB_Device/App/usb_device.h

@ -0,0 +1,105 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usb_device.h
* @version : v3.0_Cube
* @brief : Header for usb_device.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEVICE__H__
#define __USB_DEVICE__H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx.h"
#include "stm32wbxx_hal.h"
#include "usbd_def.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup USBD_OTG_DRIVER
* @{
*/
/** @defgroup USBD_DEVICE USBD_DEVICE
* @brief Device file for Usb otg low level driver.
* @{
*/
/** @defgroup USBD_DEVICE_Exported_Variables USBD_DEVICE_Exported_Variables
* @brief Public variables.
* @{
*/
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/*
* -- Insert your variables declaration here --
*/
/* USER CODE BEGIN VARIABLES */
/* USER CODE END VARIABLES */
/**
* @}
*/
/** @defgroup USBD_DEVICE_Exported_FunctionsPrototype USBD_DEVICE_Exported_FunctionsPrototype
* @brief Declaration of public functions for Usb device.
* @{
*/
/** USB Device initialization function. */
void MX_USB_Device_Init(void);
/*
* -- Insert functions declaration here --
*/
/* USER CODE BEGIN FD */
/* USER CODE END FD */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USB_DEVICE__H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

338
nucleo-wb55-ble/USB_Device/App/usbd_cdc_if.c

@ -0,0 +1,338 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_cdc_if.c
* @version : v3.0_Cube
* @brief : Usb device for Virtual Com Port.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc_if.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint8_t buffer[7];
/* USER CODE END PV */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @brief Usb device library.
* @{
*/
/** @addtogroup USBD_CDC_IF
* @{
*/
/** @defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions
* @brief Private types.
* @{
*/
/* USER CODE BEGIN PRIVATE_TYPES */
/* USER CODE END PRIVATE_TYPES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines
* @brief Private defines.
* @{
*/
/* USER CODE BEGIN PRIVATE_DEFINES */
/* USER CODE END PRIVATE_DEFINES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros
* @brief Private macros.
* @{
*/
/* USER CODE BEGIN PRIVATE_MACRO */
/* USER CODE END PRIVATE_MACRO */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables
* @brief Private variables.
* @{
*/
/* Create buffer for reception and transmission */
/* It's up to user to redefine and/or remove those define */
/** Received data over USB are stored in this buffer */
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
/** Data to send over USB CDC are stored in this buffer */
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
/* USER CODE BEGIN PRIVATE_VARIABLES */
/* USER CODE END PRIVATE_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
* @brief Public variables.
* @{
*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static int8_t CDC_Init_FS(void);
static int8_t CDC_DeInit_FS(void);
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length);
static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
/**
* @}
*/
USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
{
CDC_Init_FS,
CDC_DeInit_FS,
CDC_Control_FS,
CDC_Receive_FS,
CDC_TransmitCplt_FS
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the CDC media low layer over the FS USB IP
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Init_FS(void)
{
/* USER CODE BEGIN 3 */
/* Set Application Buffers */
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
return (USBD_OK);
/* USER CODE END 3 */
}
/**
* @brief DeInitializes the CDC media low layer
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_DeInit_FS(void)
{
/* USER CODE BEGIN 4 */
return (USBD_OK);
/* USER CODE END 4 */
}
/**
* @brief Manage the CDC class requests
* @param cmd: Command code
* @param pbuf: Buffer containing command data (request parameters)
* @param length: Number of data to be sent (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)
{
/* USER CODE BEGIN 5 */
switch(cmd)
{
case CDC_SEND_ENCAPSULATED_COMMAND:
break;
case CDC_GET_ENCAPSULATED_RESPONSE:
break;
case CDC_SET_COMM_FEATURE:
break;
case CDC_GET_COMM_FEATURE:
break;
case CDC_CLEAR_COMM_FEATURE:
break;
/*******************************************************************************/
/* Line Coding Structure */
/*-----------------------------------------------------------------------------*/
/* Offset | Field | Size | Value | Description */
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
/* 4 | bCharFormat | 1 | Number | Stop bits */
/* 0 - 1 Stop bit */
/* 1 - 1.5 Stop bits */
/* 2 - 2 Stop bits */
/* 5 | bParityType | 1 | Number | Parity */
/* 0 - None */
/* 1 - Odd */
/* 2 - Even */
/* 3 - Mark */
/* 4 - Space */
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
/*******************************************************************************/
case CDC_SET_LINE_CODING:
for (int i = 0; i< 7; i++) {
buffer[i] = pbuf[i];
}
break;
case CDC_GET_LINE_CODING:
for (int i = 0; i< 7; i++) {
pbuf[i] = buffer[i];
}
break;
case CDC_SET_CONTROL_LINE_STATE:
break;
case CDC_SEND_BREAK:
break;
default:
break;
}
return (USBD_OK);
/* USER CODE END 5 */
}
/**
* @brief Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* @note
* This function will issue a NAK packet on any OUT packet received on
* USB endpoint until exiting this function. If you exit this function
* before transfer is complete on CDC interface (ie. using DMA controller)
* it will result in receiving more data while previous ones are still
* not sent.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
usb_receive(Buf, Len);
return (USBD_OK);
/* USER CODE END 6 */
}
/**
* @brief CDC_Transmit_FS
* Data to send over USB IN endpoint are sent over CDC interface
* through this function.
* @note
*
*
* @param Buf: Buffer of data to be sent
* @param Len: Number of data to be sent (in bytes)
* @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
*/
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 7 */
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
if (hcdc->TxState != 0){
return USBD_BUSY;
}
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
/* USER CODE END 7 */
return result;
}
/**
* @brief CDC_TransmitCplt_FS
* Data transmited callback
*
* @note
* This function is IN transfer complete callback used to inform user that
* the submitted Data is successfully sent over USB.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 13 */
UNUSED(Buf);
UNUSED(Len);
UNUSED(epnum);
/* USER CODE END 13 */
return result;
}
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

134
nucleo-wb55-ble/USB_Device/App/usbd_cdc_if.h

@ -0,0 +1,134 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_cdc_if.h
* @version : v3.0_Cube
* @brief : Header for usbd_cdc_if.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CDC_IF_H__
#define __USBD_CDC_IF_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @brief For Usb device.
* @{
*/
/** @defgroup USBD_CDC_IF USBD_CDC_IF
* @brief Usb VCP device module
* @{
*/
/** @defgroup USBD_CDC_IF_Exported_Defines USBD_CDC_IF_Exported_Defines
* @brief Defines.
* @{
*/
/* USER CODE BEGIN EXPORTED_DEFINES */
/* Define size for the receive and transmit buffer over CDC */
/* It's up to user to redefine and/or remove those define */
#define APP_RX_DATA_SIZE 2048
#define APP_TX_DATA_SIZE 2048
/* USER CODE END EXPORTED_DEFINES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_Types USBD_CDC_IF_Exported_Types
* @brief Types.
* @{
*/
/* USER CODE BEGIN EXPORTED_TYPES */
/* USER CODE END EXPORTED_TYPES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_Macros USBD_CDC_IF_Exported_Macros
* @brief Aliases.
* @{
*/
/* USER CODE BEGIN EXPORTED_MACRO */
/* USER CODE END EXPORTED_MACRO */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
* @brief Public variables.
* @{
*/
/** CDC Interface callback. */
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_CDC_IF_Exported_FunctionsPrototype USBD_CDC_IF_Exported_FunctionsPrototype
* @brief Public functions declaration.
* @{
*/
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
/* USER CODE BEGIN EXPORTED_FUNCTIONS */
__weak void usb_receive(uint8_t *buf, uint32_t *len);
/* USER CODE END EXPORTED_FUNCTIONS */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CDC_IF_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

396
nucleo-wb55-ble/USB_Device/App/usbd_desc.c

@ -0,0 +1,396 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : App/usbd_desc.c
* @version : v3.0_Cube
* @brief : This file implements the USB device descriptors.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_conf.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @addtogroup USBD_DESC
* @{
*/
/** @defgroup USBD_DESC_Private_TypesDefinitions USBD_DESC_Private_TypesDefinitions
* @brief Private types.
* @{
*/
/* USER CODE BEGIN PRIVATE_TYPES */
/* USER CODE END PRIVATE_TYPES */
/**
* @}
*/
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
* @brief Private defines.
* @{
*/
#define USBD_VID 1155
#define USBD_LANGID_STRING 1033
#define USBD_MANUFACTURER_STRING "STMicroelectronics"
#define USBD_PID 22336
#define USBD_PRODUCT_STRING "STM32 Virtual ComPort"
#define USBD_CONFIGURATION_STRING "CDC Config"
#define USBD_INTERFACE_STRING "CDC Interface"
/* USER CODE BEGIN PRIVATE_DEFINES */
/* USER CODE END PRIVATE_DEFINES */
/**
* @}
*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/** @defgroup USBD_DESC_Private_Macros USBD_DESC_Private_Macros
* @brief Private macros.
* @{
*/
/* USER CODE BEGIN PRIVATE_MACRO */
/* USER CODE END PRIVATE_MACRO */
/**
* @}
*/
/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static void Get_SerialNum(void);
static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len);
/**
* @}
*/
/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
uint8_t * USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t * USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
/**
* @}
*/
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
USBD_DescriptorsTypeDef CDC_Desc =
{
USBD_CDC_DeviceDescriptor,
USBD_CDC_LangIDStrDescriptor,
USBD_CDC_ManufacturerStrDescriptor,
USBD_CDC_ProductStrDescriptor,
USBD_CDC_SerialStrDescriptor,
USBD_CDC_ConfigStrDescriptor,
USBD_CDC_InterfaceStrDescriptor
};
#if defined ( __ICCARM__ ) /* IAR Compiler */
#pragma data_alignment=4
#endif /* defined ( __ICCARM__ ) */
/** USB standard device descriptor. */
__ALIGN_BEGIN uint8_t USBD_CDC_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
0x00, /*bcdUSB */
0x02,
0x02, /*bDeviceClass*/
0x02, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID), /*idProduct*/
HIBYTE(USBD_PID), /*idProduct*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
};
/* USB_DeviceDescriptor */
/**
* @}
*/
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
#if defined ( __ICCARM__ ) /* IAR Compiler */
#pragma data_alignment=4
#endif /* defined ( __ICCARM__ ) */
/** USB lang indentifier descriptor. */
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END =
{
USB_LEN_LANGID_STR_DESC,
USB_DESC_TYPE_STRING,
LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING)
};
#if defined ( __ICCARM__ ) /* IAR Compiler */
#pragma data_alignment=4
#endif /* defined ( __ICCARM__ ) */
/* Internal string descriptor. */
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
USB_SIZ_STRING_SERIAL,
USB_DESC_TYPE_STRING,
};
/**
* @}
*/
/** @defgroup USBD_DESC_Private_Functions USBD_DESC_Private_Functions
* @brief Private functions.
* @{
*/
/**
* @brief Return the device descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_CDC_DeviceDesc);
return USBD_CDC_DeviceDesc;
}
/**
* @brief Return the LangID string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_LangIDDesc);
return USBD_LangIDDesc;
}
/**
* @brief Return the product string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if(speed == 0)
{
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING, USBD_StrDesc, length);
}
else
{
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Return the manufacturer string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief Return the serial number string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = USB_SIZ_STRING_SERIAL;
/* Update the serial number string descriptor with the data from the unique
* ID */
Get_SerialNum();
/* USER CODE BEGIN USBD_CDC_SerialStrDescriptor */
/* USER CODE END USBD_CDC_SerialStrDescriptor */
return (uint8_t *) USBD_StringSerial;
}
/**
* @brief Return the configuration string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if(speed == USBD_SPEED_HIGH)
{
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length);
}
else
{
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Return the interface string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t * USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if(speed == 0)
{
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length);
}
else
{
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Create the serial number string descriptor
* @param None
* @retval None
*/
static void Get_SerialNum(void)
{
uint32_t deviceserial0, deviceserial1, deviceserial2;
deviceserial0 = *(uint32_t *) DEVICE_ID1;
deviceserial1 = *(uint32_t *) DEVICE_ID2;
deviceserial2 = *(uint32_t *) DEVICE_ID3;
deviceserial0 += deviceserial2;
if (deviceserial0 != 0)
{
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
}
/**
* @brief Convert Hex 32Bits value into char
* @param value: value to convert
* @param pbuf: pointer to the buffer
* @param len: buffer length
* @retval None
*/
static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len)
{
uint8_t idx = 0;
for (idx = 0; idx < len; idx++)
{
if (((value >> 28)) < 0xA)
{
pbuf[2 * idx] = (value >> 28) + '0';
}
else
{
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
}
value = value << 4;
pbuf[2 * idx + 1] = 0;
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

145
nucleo-wb55-ble/USB_Device/App/usbd_desc.h

@ -0,0 +1,145 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_desc.c
* @version : v3.0_Cube
* @brief : Header for usbd_conf.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_DESC__C__
#define __USBD_DESC__C__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_DESC USBD_DESC
* @brief Usb device descriptors module.
* @{
*/
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
* @brief Constants.
* @{
*/
#define DEVICE_ID1 (UID_BASE)
#define DEVICE_ID2 (UID_BASE + 0x4)
#define DEVICE_ID3 (UID_BASE + 0x8)
#define USB_SIZ_STRING_SERIAL 0x1A
/* USER CODE BEGIN EXPORTED_CONSTANTS */
/* USER CODE END EXPORTED_CONSTANTS */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_Defines USBD_DESC_Exported_Defines
* @brief Defines.
* @{
*/
/* USER CODE BEGIN EXPORTED_DEFINES */
/* USER CODE END EXPORTED_DEFINES */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_TypesDefinitions USBD_DESC_Exported_TypesDefinitions
* @brief Types.
* @{
*/
/* USER CODE BEGIN EXPORTED_TYPES */
/* USER CODE END EXPORTED_TYPES */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_Macros USBD_DESC_Exported_Macros
* @brief Aliases.
* @{
*/
/* USER CODE BEGIN EXPORTED_MACRO */
/* USER CODE END EXPORTED_MACRO */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_Variables USBD_DESC_Exported_Variables
* @brief Public variables.
* @{
*/
extern USBD_DescriptorsTypeDef CDC_Desc;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_DESC_Exported_FunctionsPrototype USBD_DESC_Exported_FunctionsPrototype
* @brief Public functions declaration.
* @{
*/
/* USER CODE BEGIN EXPORTED_FUNCTIONS */
/* USER CODE END EXPORTED_FUNCTIONS */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_DESC__C__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

810
nucleo-wb55-ble/USB_Device/Target/usbd_conf.c

@ -0,0 +1,810 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : Target/usbd_conf.c
* @version : v3.0_Cube
* @brief : This file implements the board support package for the USB device library
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx.h"
#include "stm32wbxx_hal.h"
#include "usbd_def.h"
#include "usbd_core.h"
#include "usbd_cdc.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
PCD_HandleTypeDef hpcd_USB_FS;
void Error_Handler(void);
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* Exported function prototypes ----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* Private functions ---------------------------------------------------------*/
static USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status);
/* USER CODE BEGIN 1 */
static void SystemClockConfig_Resume(void);
/* USER CODE END 1 */
extern void SystemClock_Config(void);
/*******************************************************************************
LL Driver Callbacks (PCD -> USB Device Library)
*******************************************************************************/
/* MSP Init */
#if (USE_HAL_PCD_REGISTER_CALLBACK == 1U)
static void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
#else
void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
#endif /* USE_HAL_PCD_REGISTER_CALLBACK */
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(pcdHandle->Instance==USB)
{
/* USER CODE BEGIN USB_MspInit 0 */
/* USER CODE END USB_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USB GPIO Configuration
PA11 ------> USB_DM
PA12 ------> USB_DP
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF10_USB;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_USB_CLK_ENABLE();
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(USB_LP_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USB_LP_IRQn);
/* USER CODE BEGIN USB_MspInit 1 */
/* USER CODE END USB_MspInit 1 */
}
}
#if (USE_HAL_PCD_REGISTER_CALLBACK == 1U)
static void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
#else
void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
#endif /* USE_HAL_PCD_REGISTER_CALLBACK */
{
if(pcdHandle->Instance==USB)
{
/* USER CODE BEGIN USB_MspDeInit 0 */
/* USER CODE END USB_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USB_CLK_DISABLE();
/**USB GPIO Configuration
PA11 ------> USB_DM
PA12 ------> USB_DP
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* Peripheral interrupt Deinit*/
HAL_NVIC_DisableIRQ(USB_LP_IRQn);
/* USER CODE BEGIN USB_MspDeInit 1 */
/* USER CODE END USB_MspDeInit 1 */
}
}
/**
* @brief Setup stage callback
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_SetupStageCallback_PreTreatment */
/* USER CODE END HAL_PCD_SetupStageCallback_PreTreatment */
USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup);
/* USER CODE BEGIN HAL_PCD_SetupStageCallback_PostTreatment */
/* USER CODE END HAL_PCD_SetupStageCallback_PostTreatment */
}
/**
* @brief Data Out stage callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#else
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_DataOutStageCallback_PreTreatment */
/* USER CODE END HAL_PCD_DataOutStageCallback_PreTreatment */
USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
/* USER CODE BEGIN HAL_PCD_DataOutStageCallback_PostTreatment */
/* USER CODE END HAL_PCD_DataOutStageCallback_PostTreatment */
}
/**
* @brief Data In stage callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#else
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_DataInStageCallback_PreTreatment */
/* USER CODE END HAL_PCD_DataInStageCallback_PreTreatment */
USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
/* USER CODE BEGIN HAL_PCD_DataInStageCallback_PostTreatment */
/* USER CODE END HAL_PCD_DataInStageCallback_PostTreatment */
}
/**
* @brief SOF callback.
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_SOFCallback_PreTreatment */
/* USER CODE END HAL_PCD_SOFCallback_PreTreatment */
USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_SOFCallback_PostTreatment */
/* USER CODE END HAL_PCD_SOFCallback_PostTreatment */
}
/**
* @brief Reset callback.
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ResetCallback_PreTreatment */
/* USER CODE END HAL_PCD_ResetCallback_PreTreatment */
USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
if ( hpcd->Init.speed != PCD_SPEED_FULL)
{
Error_Handler();
}
/* Set Speed. */
USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed);
/* Reset Device. */
USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_ResetCallback_PostTreatment */
/* USER CODE END HAL_PCD_ResetCallback_PostTreatment */
}
/**
* @brief Suspend callback.
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_SuspendCallback_PreTreatment */
/* USER CODE END HAL_PCD_SuspendCallback_PreTreatment */
/* Inform USB library that core enters in suspend Mode. */
USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData);
/* Enter in STOP mode. */
/* USER CODE BEGIN 2 */
if (hpcd->Init.low_power_enable)
{
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
}
/* USER CODE END 2 */
/* USER CODE BEGIN HAL_PCD_SuspendCallback_PostTreatment */
/* USER CODE END HAL_PCD_SuspendCallback_PostTreatment */
}
/**
* @brief Resume callback.
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ResumeCallback_PreTreatment */
/* USER CODE END HAL_PCD_ResumeCallback_PreTreatment */
/* USER CODE BEGIN 3 */
if (hpcd->Init.low_power_enable)
{
/* Reset SLEEPDEEP bit of Cortex System Control Register. */
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
SystemClockConfig_Resume();
}
/* USER CODE END 3 */
USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_ResumeCallback_PostTreatment */
/* USER CODE END HAL_PCD_ResumeCallback_PostTreatment */
}
/**
* @brief ISOOUTIncomplete callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#else
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ISOOUTIncompleteCallback_PreTreatment */
/* USER CODE END HAL_PCD_ISOOUTIncompleteCallback_PreTreatment */
USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
/* USER CODE BEGIN HAL_PCD_ISOOUTIncompleteCallback_PostTreatment */
/* USER CODE END HAL_PCD_ISOOUTIncompleteCallback_PostTreatment */
}
/**
* @brief ISOINIncomplete callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#else
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ISOINIncompleteCallback_PreTreatment */
/* USER CODE END HAL_PCD_ISOINIncompleteCallback_PreTreatment */
USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
/* USER CODE BEGIN HAL_PCD_ISOINIncompleteCallback_PostTreatment */
/* USER CODE END HAL_PCD_ISOINIncompleteCallback_PostTreatment */
}
/**
* @brief Connect callback.
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_ConnectCallback_PreTreatment */
/* USER CODE END HAL_PCD_ConnectCallback_PreTreatment */
USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_ConnectCallback_PostTreatment */
/* USER CODE END HAL_PCD_ConnectCallback_PostTreatment */
}
/**
* @brief Disconnect callback.
* @param hpcd: PCD handle
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
#else
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN HAL_PCD_DisconnectCallback_PreTreatment */
/* USER CODE END HAL_PCD_DisconnectCallback_PreTreatment */
USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData);
/* USER CODE BEGIN HAL_PCD_DisconnectCallback_PostTreatment */
/* USER CODE END HAL_PCD_DisconnectCallback_PostTreatment */
}
/* USER CODE BEGIN LowLevelInterface */
/* USER CODE END LowLevelInterface */
/*******************************************************************************
LL Driver Interface (USB Device Library --> PCD)
*******************************************************************************/
/**
* @brief Initializes the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
{
/* Init USB Ip. */
hpcd_USB_FS.pData = pdev;
/* Link the driver to the stack. */
pdev->pData = &hpcd_USB_FS;
/* Enable USB power on Pwrctrl CR2 register. */
HAL_PWREx_EnableVddUSB();
hpcd_USB_FS.Instance = USB;
hpcd_USB_FS.Init.dev_endpoints = 8;
hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;
hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
hpcd_USB_FS.Init.Sof_enable = DISABLE;
hpcd_USB_FS.Init.low_power_enable = DISABLE;
hpcd_USB_FS.Init.lpm_enable = DISABLE;
hpcd_USB_FS.Init.battery_charging_enable = DISABLE;
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
/* register Msp Callbacks (before the Init) */
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_MSPINIT_CB_ID, PCD_MspInit);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_MSPDEINIT_CB_ID, PCD_MspDeInit);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK)
{
Error_Handler( );
}
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
/* Register USB PCD CallBacks */
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SOF_CB_ID, PCD_SOFCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SETUPSTAGE_CB_ID, PCD_SetupStageCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_RESET_CB_ID, PCD_ResetCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_SUSPEND_CB_ID, PCD_SuspendCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_RESUME_CB_ID, PCD_ResumeCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_CONNECT_CB_ID, PCD_ConnectCallback);
HAL_PCD_RegisterCallback(&hpcd_USB_FS, HAL_PCD_DISCONNECT_CB_ID, PCD_DisconnectCallback);
/* USER CODE BEGIN RegisterCallBackFirstPart */
/* USER CODE END RegisterCallBackFirstPart */
HAL_PCD_RegisterLpmCallback(&hpcd_USB_FS, PCDEx_LPM_Callback);
HAL_PCD_RegisterDataOutStageCallback(&hpcd_USB_FS, PCD_DataOutStageCallback);
HAL_PCD_RegisterDataInStageCallback(&hpcd_USB_FS, PCD_DataInStageCallback);
HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_FS, PCD_ISOOUTIncompleteCallback);
HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_FS, PCD_ISOINIncompleteCallback);
/* USER CODE BEGIN RegisterCallBackSecondPart */
/* USER CODE END RegisterCallBackSecondPart */
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
/* USER CODE BEGIN EndPoint_Configuration */
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
/* USER CODE END EndPoint_Configuration */
/* USER CODE BEGIN EndPoint_Configuration_CDC */
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100);
/* USER CODE END EndPoint_Configuration_CDC */
return USBD_OK;
}
/**
* @brief De-Initializes the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_DeInit(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Starts the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_Start(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Stops the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_Stop(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Opens an endpoint of the low level driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @param ep_type: Endpoint type
* @param ep_mps: Endpoint max packet size
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Closes an endpoint of the low level driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Flushes an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Sets a Stall condition on an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Clears a Stall condition on an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Returns Stall condition.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval Stall (1: Yes, 0: No)
*/
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData;
if((ep_addr & 0x80) == 0x80)
{
return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
}
else
{
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
}
}
/**
* @brief Assigns a USB address to the device.
* @param pdev: Device handle
* @param dev_addr: Device address
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Transmits data over an endpoint.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @param pbuf: Pointer to data to be sent
* @param size: Data size
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Prepares an endpoint for reception.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @param pbuf: Pointer to data to be received
* @param size: Data size
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Returns the last transfered packet size.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval Recived Data Size
*/
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr);
}
/**
* @brief Send LPM message to user layer
* @param hpcd: PCD handle
* @param msg: LPM message
* @retval None
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
static void PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
#else
void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
/* USER CODE BEGIN LPM_Callback */
switch (msg)
{
case PCD_LPM_L0_ACTIVE:
if (hpcd->Init.low_power_enable)
{
SystemClockConfig_Resume();
/* Reset SLEEPDEEP bit of Cortex System Control Register. */
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
}
USBD_LL_Resume(hpcd->pData);
break;
case PCD_LPM_L1_ACTIVE:
USBD_LL_Suspend(hpcd->pData);
/* Enter in STOP mode. */
if (hpcd->Init.low_power_enable)
{
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
}
break;
}
/* USER CODE END LPM_Callback */
}
/**
* @brief Delays routine for the USB Device Library.
* @param Delay: Delay in ms
* @retval None
*/
void USBD_LL_Delay(uint32_t Delay)
{
HAL_Delay(Delay);
}
/**
* @brief Static single allocation.
* @param size: Size of allocated memory
* @retval None
*/
void *USBD_static_malloc(uint32_t size)
{
static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
return mem;
}
/**
* @brief Dummy memory free
* @param p: Pointer to allocated memory address
* @retval None
*/
void USBD_static_free(void *p)
{
}
/* USER CODE BEGIN 5 */
/**
* @brief Configures system clock after wake-up from USB resume callBack:
* enable HSI, PLL and select PLL as system clock source.
* @retval None
*/
static void SystemClockConfig_Resume(void)
{
SystemClock_Config();
}
/* USER CODE END 5 */
/**
* @brief Retuns the USB status depending on the HAL status:
* @param hal_status: HAL status
* @retval USB status
*/
USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status)
{
USBD_StatusTypeDef usb_status = USBD_OK;
switch (hal_status)
{
case HAL_OK :
usb_status = USBD_OK;
break;
case HAL_ERROR :
usb_status = USBD_FAIL;
break;
case HAL_BUSY :
usb_status = USBD_BUSY;
break;
case HAL_TIMEOUT :
usb_status = USBD_FAIL;
break;
default :
usb_status = USBD_FAIL;
break;
}
return usb_status;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

176
nucleo-wb55-ble/USB_Device/Target/usbd_conf.h

@ -0,0 +1,176 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_conf.h
* @version : v3.0_Cube
* @brief : Header for usbd_conf.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CONF__H__
#define __USBD_CONF__H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stm32wbxx.h"
#include "stm32wbxx_hal.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup USBD_OTG_DRIVER
* @brief Driver for Usb device.
* @{
*/
/** @defgroup USBD_CONF USBD_CONF
* @brief Configuration file for Usb otg low level driver.
* @{
*/
/** @defgroup USBD_CONF_Exported_Variables USBD_CONF_Exported_Variables
* @brief Public variables.
* @{
*/
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines
* @brief Defines for configuration of the Usb device.
* @{
*/
/*---------- -----------*/
#define USBD_MAX_NUM_INTERFACES 1U
/*---------- -----------*/
#define USBD_MAX_NUM_CONFIGURATION 1U
/*---------- -----------*/
#define USBD_MAX_STR_DESC_SIZ 512U
/*---------- -----------*/
#define USBD_DEBUG_LEVEL 0U
/*---------- -----------*/
#define USBD_LPM_ENABLED 1U
/*---------- -----------*/
#define USBD_SELF_POWERED 1U
/****************************************/
/* #define for FS and HS identification */
#define DEVICE_FS 0
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Macros USBD_CONF_Exported_Macros
* @brief Aliases.
* @{
*/
/* Memory management macros */
/** Alias for memory allocation. */
#define USBD_malloc (void *)USBD_static_malloc
/** Alias for memory release. */
#define USBD_free USBD_static_free
/** Alias for memory set. */
#define USBD_memset memset
/** Alias for memory copy. */
#define USBD_memcpy memcpy
/** Alias for delay. */
#define USBD_Delay HAL_Delay
/* DEBUG macros */
#if (USBD_DEBUG_LEVEL > 0)
#define USBD_UsrLog(...) printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_UsrLog(...)
#endif
#if (USBD_DEBUG_LEVEL > 1)
#define USBD_ErrLog(...) printf("ERROR: ") ;\
printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_ErrLog(...)
#endif
#if (USBD_DEBUG_LEVEL > 2)
#define USBD_DbgLog(...) printf("DEBUG : ") ;\
printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_DbgLog(...)
#endif
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Types USBD_CONF_Exported_Types
* @brief Types.
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_FunctionsPrototype USBD_CONF_Exported_FunctionsPrototype
* @brief Declaration of public functions for Usb device.
* @{
*/
/* Exported functions -------------------------------------------------------*/
void *USBD_static_malloc(uint32_t size);
void USBD_static_free(void *p);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CONF__H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

28
nucleo-wb55-ble/commands/dispatch.cpp

@ -0,0 +1,28 @@
/*
* dispatch.cpp
*
* Created on: 18 Jul 2021
* Author: Andreas Berthoud
*/
#include "dispatch.hpp"
#include "HeartbeatCommand.hpp"
#include "LedCommand.hpp"
void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t size) {
switch (command_id)
{
case COMMAND_HEARTBEAT_REQUEST:
push_command(new HeartbeatRequest(payload_ptr, size));
break;
case COMMAND_LED_REQUEST:
push_command(new LedRequest(payload_ptr, size));
break;
default:
break;
}
}

15
nucleo-wb55-ble/commands/dispatch.hpp

@ -0,0 +1,15 @@
/*
* dispatch.hpp
*
* Created on: 18 Jul 2021
* Author: Andreas Berthoud
*/
#ifndef DISPATCH_HPP_
#define DISPATCH_HPP_
#include <stdint.h>
extern "C" void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t length);
#endif /* DISPATCH_HPP_ */

77
nucleo-wb55-ble/nucleo-wb55-ble.ioc

@ -1,19 +1,21 @@
#MicroXplorer Configuration settings - do not modify
Mcu.Family=STM32WB
ProjectManager.MainLocation=Core/Src
USB_DEVICE.CLASS_NAME_FS=CDC
RCC.USART1Freq_Value=32000000
RCC.SAI1Freq_Value=128000000
RCC.SAI1Freq_Value=48000000
RCC.CortexFreq_Value=32000000
ProjectManager.KeepUserCode=true
Mcu.UserName=STM32WB55RGVx
RF1.Signal=RF_RF1
RCC.RFWKPFreq_Value=32768
RCC.SMPSCLockSelectionVirtualVirtual=RCC_SMPSCLKSOURCE_HSI
RCC.PLLSAI1RoutputFreq_Value=128000000
RCC.PLLSAI1RoutputFreq_Value=48000000
PA14.GPIO_Label=JTCK
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_RF_Init-RF-false-HAL-true,4-MX_RTC_Init-RTC-false-HAL-true,5-APPE_Init-STM32_WPAN-false-HAL-false,0-MX_HSEM_Init-HSEM-false-HAL-true
PD0.GPIO_Label=SW2
VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
PA11.Mode=Device
RCC.RTCFreq_Value=32768
PB0.GPIO_Label=LED_GREEN
PD0.Locked=true
@ -33,11 +35,12 @@ Mcu.IP2=RCC
Mcu.IP3=RF
Mcu.IP0=HSEM
Mcu.IP1=NVIC
PA12.Signal=USB_DP
Mcu.UserConstants=
RCC.VCOSAI1OutputFreq_Value=256000000
RCC.VCOSAI1OutputFreq_Value=96000000
Mcu.ThirdPartyNb=0
RCC.HCLKFreq_Value=32000000
Mcu.IPNb=9
Mcu.IPNb=11
STM32_WPAN.LOCAL_NAME=Travis
ProjectManager.PreviousToolchain=
RCC.APB2TimFreq_Value=32000000
@ -45,9 +48,9 @@ PCC.Ble.PowerLevel=Min
Mcu.Pin6=PB0
PD0.Signal=GPIO_Input
Mcu.Pin7=PB1
Mcu.Pin8=PA13
Mcu.Pin8=PA11
OSC_OUT.Mode=HSE-External-Oscillator
Mcu.Pin9=PA14
Mcu.Pin9=PA12
OSC_OUT.Signal=RCC_OSC_OUT
RCC.AHBFreq_Value=32000000
Mcu.Pin0=PC14-OSC32_IN
@ -62,22 +65,23 @@ NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
RCC.FCLK2Freq_Value=32000000
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false
PB3.Mode=Trace_Asynchronous_SW
RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE
NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true
Mcu.IP10=USB_DEVICE
PD1.GPIOParameters=GPIO_Label
NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true
RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE
PD1.GPIO_Label=SW3
ProjectManager.FirmwarePackage=STM32Cube FW_WB V1.11.1
MxDb.Version=DB.6.0.21
PB0.GPIOParameters=GPIO_Label
ProjectManager.BackupPrevious=false
PC14-OSC32_IN.Mode=LSE-External-Oscillator
RCC.VCOInputFreq_Value=32000000
RCC.VCOInputFreq_Value=4000000
PC4.GPIO_Label=SW1
PA14.Mode=Trace_Asynchronous_SW
PB1.GPIO_Label=LED_RED
File.Version=6
PB3.GPIOParameters=GPIO_Label
RCC.PLLRCLKFreq_Value=128000000
RCC.PLLRCLKFreq_Value=16000000
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false
ProjectManager.HalAssertFull=false
PB0.Locked=true
@ -92,31 +96,35 @@ ProjectManager.ToolChainLocation=
RCC.LSI_VALUE=32000
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
RCC.LSCOPinFreq_Value=32000
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS
NVIC.USB_LP_IRQn=true\:0\:0\:false\:false\:true\:false\:true
VP_STM32_WPAN_VS_BLE_HOST.Signal=STM32_WPAN_VS_BLE_HOST
VP_TINY_LPM_VS_TINY_LPM.Mode=TINY_LPM_Enabled
PB5.GPIO_Label=LED_BLUE
VP_HSEM_VS_HSEM.Mode=HSEM_Activate
RCC.PLLPoutputFreq_Value=128000000
RCC.PLLPoutputFreq_Value=16000000
RCC.APB1TimFreq_Value=32000000
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
PC4.Locked=true
RCC.LPUART1Freq_Value=32000000
RCC.CK48CLockSelection=RCC_USBCLKSOURCE_HSI48
RCC.SMPSDivider=1
ProjectManager.CustomerFirmwarePackage=
PC4.GPIOParameters=GPIO_Label
RCC.MSIClockRange=RCC_MSIRANGE_10
RCC.HSI48_VALUE=48000000
PB3.Locked=true
RCC.PLLSAI1N=24
PB3.GPIO_Label=JTDO
VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
PCC.Ble.Mode=NOT_SELECTED
PC15-OSC32_OUT.Mode=LSE-External-Oscillator
NVIC.EXTI4_IRQn=true\:0\:0\:false\:false\:true\:true\:true
RCC.PLLQoutputFreq_Value=128000000
RCC.PLLQoutputFreq_Value=16000000
ProjectManager.ProjectFileName=nucleo-wb55-ble.ioc
VP_STM32_WPAN_VS_BLE_HOST.Mode=STM32_WPAN_Enabled
Mcu.PinsNb=20
Mcu.PinsNb=23
ProjectManager.NoMain=false
USB_DEVICE.VirtualModeFS=Cdc_FS
RCC.HCLK3Freq_Value=32000000
PC4.Signal=GPXTI4
PD1.Signal=GPIO_Input
@ -126,23 +134,25 @@ ProjectManager.DeletePrevious=true
RCC.HCLK2Freq_Value=32000000
PC14-OSC32_IN.Signal=RCC_OSC32_IN
boardIOC=true
USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS
RCC.FamilyName=M
PA13.Signal=SYS_JTMS-SWDIO
ProjectManager.TargetToolchain=STM32CubeIDE
STM32_WPAN.LOCAL_NAME_FORMATTED=,'T','r','a','v','i','s'
RCC.HCLKRFFreq_Value=16000000
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS
PB5.Locked=true
ProjectManager.RegisterCallBack=
OSC_IN.Signal=RCC_OSC_IN
RCC.USBFreq_Value=128000000
RCC.USBFreq_Value=48000000
PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
RCC.PLLSAI1PoutputFreq_Value=128000000
RCC.PLLSAI1PoutputFreq_Value=48000000
PB1.Locked=true
RCC.SMPSCLockSelectionVirtual=RCC_SMPSCLKSOURCE_HSI
board=P-NUCLEO-WB55-Nucleo
VP_SEQUENCER_VS_SEQUENCER.Mode=SEQUENCER_Enabled
RCC.Cortex2Freq_Value=32000000
RCC.VCOOutputFreq_Value=256000000
RCC.VCOOutputFreq_Value=32000000
ProjectManager.LastFirmware=true
RCC.SMPS1Freq_Value=16000000
RCC.APB2Freq_Value=32000000
@ -151,26 +161,31 @@ PCC.Ble.DataLength=6
RCC.I2C1Freq_Value=32000000
RCC.LCDFreq_Value=32768
RCC.RNGFreq_Value=32000
RCC.PLLSAI1QoutputFreq_Value=128000000
RCC.ADCFreq_Value=128000000
RCC.PLLSAI1QoutputFreq_Value=48000000
RCC.ADCFreq_Value=48000000
VP_SYS_VS_Systick.Mode=SysTick
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false
PA13.Mode=Trace_Asynchronous_SW
ProjectManager.FreePins=false
RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,Cortex2Freq_Value,CortexFreq_Value,FCLK2Freq_Value,FCLKCortexFreq_Value,FamilyName,HCLK2Freq_Value,HCLK3Freq_Value,HCLKFreq_Value,HCLKRFFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LCDFreq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,MSIClockRange,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PWRFreq_Value,RFWKPClockSelection,RFWKPFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SMPS1Freq_Value,SMPSCLockSelectionVirtual,SMPSCLockSelectionVirtualVirtual,SMPSDivider,SYSCLKFreq_VALUE,SYSCLKSource,USART1Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value
RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,CK48CLockSelection,Cortex2Freq_Value,CortexFreq_Value,FCLK2Freq_Value,FCLKCortexFreq_Value,FamilyName,HCLK2Freq_Value,HCLK3Freq_Value,HCLKFreq_Value,HCLKRFFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LCDFreq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1N,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PWRFreq_Value,RFWKPClockSelection,RFWKPFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SMPS1Freq_Value,SMPSCLockSelectionVirtual,SMPSCLockSelectionVirtualVirtual,SMPSDivider,SYSCLKFreq_VALUE,SYSCLKSource,USART1Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value
ProjectManager.AskForMigrate=true
Mcu.Name=STM32WB55RGVx
RCC.LPTIM2Freq_Value=32000000
PA13.GPIO_Label=JTMS
ProjectManager.UnderRoot=true
Mcu.IP8=TINY_LPM
Mcu.IP9=USB
Mcu.IP6=STM32_WPAN
Mcu.IP7=SYS
ProjectManager.CoupleFile=false
PB3.Signal=SYS_JTDO-SWO
RCC.SYSCLKFreq_VALUE=32000000
PB5.Signal=GPIO_Output
Mcu.Pin22=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
Mcu.Pin20=VP_SYS_VS_Systick
Mcu.Pin21=VP_TINY_LPM_VS_TINY_LPM
SH.GPXTI4.0=GPIO_EXTI4
PA12.Mode=Device
PCC.Ble.ConnectionInterval=1000.0
NVIC.ForceEnableDMAVector=true
KeepUserPlacement=false
@ -181,30 +196,32 @@ STM32_WPAN.IPParameters=LOCAL_NAME,LOCAL_NAME_FORMATTED
PA13.Locked=true
ProjectManager.CompilerOptimize=6
RF1.Mode=RF1_Activate
PA11.Signal=USB_DM
PA14.Signal=SYS_JTCK-SWCLK
ProjectManager.HeapSize=0x200
Mcu.Pin15=VP_RTC_VS_RTC_Activate
Mcu.Pin15=PB5
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
Mcu.Pin16=VP_SEQUENCER_VS_SEQUENCER
Mcu.Pin16=VP_HSEM_VS_HSEM
SH.GPXTI4.ConfNb=1
Mcu.Pin13=PB5
Mcu.Pin14=VP_HSEM_VS_HSEM
Mcu.Pin19=VP_TINY_LPM_VS_TINY_LPM
Mcu.Pin13=PD1
Mcu.Pin14=PB3
Mcu.Pin19=VP_STM32_WPAN_VS_BLE_HOST
ProjectManager.ComputerToolchain=false
Mcu.Pin17=VP_STM32_WPAN_VS_BLE_HOST
Mcu.Pin17=VP_RTC_VS_RTC_Activate
RCC.HSI_VALUE=16000000
Mcu.Pin18=VP_SYS_VS_Systick
Mcu.Pin18=VP_SEQUENCER_VS_SEQUENCER
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
Mcu.Pin11=PD1
Mcu.Pin12=PB3
Mcu.Pin11=PA14
Mcu.Pin12=PD0
PD0.GPIOParameters=GPIO_Label
Mcu.Pin10=PD0
Mcu.Pin10=PA13
RCC.PWRFreq_Value=32000000
VP_TINY_LPM_VS_TINY_LPM.Signal=TINY_LPM_VS_TINY_LPM
RCC.APB1Freq_Value=32000000
PD1.Locked=true
RCC.RFWKPClockSelection=RCC_RFWKPCLKSOURCE_LSE
PB0.Signal=GPIO_Output
USB_DEVICE.VirtualMode=Cdc
ProjectManager.DeviceId=STM32WB55RGVx
ProjectManager.LibraryCopy=1
PB1.GPIOParameters=GPIO_Label

9
nucleo-wb55-dongle-ble/Core/Src/main.c

@ -114,14 +114,15 @@ int main(void)
/* Init code for STM32_WPAN */
APPE_Init();
HAL_Delay(1000);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
HAL_Delay(20);
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
HAL_Delay(20);
// HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
// HAL_Delay(20);
// HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
// HAL_Delay(20);
UTIL_SEQ_Run(UTIL_SEQ_DEFAULT);
pop_and_execute_commands();

24
nucleo-wb55-dongle-ble/STM32_WPAN/App/app_ble.c

@ -360,7 +360,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
int k = 0;
uint8_t adtype, adlength;
log_debug("SVCCTL_App_Notification", "enter, event=%n", 1, event_pckt->evt);
// log_debug("SVCCTL_App_Notification", "enter, event=%d", 1, event_pckt->evt);
switch (event_pckt->evt)
{
/* USER CODE BEGIN evt */
@ -391,6 +391,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
{
/* USER CODE BEGIN GAP_GENERAL_DISCOVERY_PROC */
log_debug("SVCCTL_App_Notification", "-- GAP GENERAL DISCOVERY PROCEDURE_COMPLETED", 0);
/* USER CODE END GAP_GENERAL_DISCOVERY_PROC */
APP_DBG_MSG("-- GAP GENERAL DISCOVERY PROCEDURE_COMPLETED\n");
/*if a device found, connect to it, device 1 being chosen first if both found*/
@ -427,7 +428,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
0x01);
if(result != BLE_STATUS_SUCCESS) {
/* USER CODE BEGIN BLE_STATUS_SUCCESS */
log_debug("SVCCTL_App_Notification", "BLE_STATUS_SUCCESS: false", 0);
/* USER CODE END BLE_STATUS_SUCCESS */
}
aci_hal_set_radio_activity_mask(0x0020);
@ -439,6 +440,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
case 0x0004:
{
/* USER CODE BEGIN RADIO_ACTIVITY_EVENT */
// log_debug("SVCCTL_App_Notification", "RADIO_ACTIVITY_EVENT", 0);
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
HAL_Delay(5);
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
@ -647,7 +649,21 @@ APP_BLE_ConnStatus_t APP_BLE_Get_Client_Connection_Status( uint16_t Connection_H
return APP_BLE_IDLE;
}
/* USER CODE BEGIN FD */
void APP_BLE_Key_Button1_Action(void)
{
#if OOB_DEMO == 0
P2PC_APP_SW1_Button_Action();
#else
if(P2P_Client_APP_Get_State () != APP_BLE_CONNECTED_CLIENT)
{
UTIL_SEQ_SetTask(1 << CFG_TASK_START_SCAN_ID, CFG_SCH_PRIO_0);
}
else
{
P2PC_APP_SW1_Button_Action();
}
#endif
}
/* USER CODE END FD */
/*************************************************************
*
@ -808,7 +824,7 @@ static void Scan_Request( void )
{
/* USER CODE BEGIN BLE_SCAN_SUCCESS */
log_debug("Scan_Request", "START GENERAL DISCOVERY (SCAN)", 0);
log_debug("Scan_Request", "START GENERAL DISCOVERY (SCAN)", 0);
/* USER CODE END BLE_SCAN_SUCCESS */
APP_DBG_MSG(" \r\n\r** START GENERAL DISCOVERY (SCAN) ** \r\n\r");
}

2
nucleo-wb55-dongle-ble/STM32_WPAN/App/app_ble.h

@ -80,7 +80,7 @@ extern "C" {
APP_BLE_ConnStatus_t APP_BLE_Get_Client_Connection_Status( uint16_t Connection_Handle );
/* USER CODE BEGIN EF */
void APP_BLE_Key_Button1_Action(void);
/* USER CODE END EF */
#ifdef __cplusplus

203
nucleo-wb55-dongle-ble/STM32_WPAN/App/p2p_client_app.c

@ -106,7 +106,28 @@ typedef struct
}P2P_ClientContext_t;
/* USER CODE BEGIN PTD */
typedef struct{
uint8_t Device_Led_Selection;
uint8_t Led1;
}P2P_LedCharValue_t;
typedef struct{
uint8_t Device_Button_Selection;
uint8_t Button1;
}P2P_ButtonCharValue_t;
typedef struct
{
uint8_t Notification_Status; /* used to chek if P2P Server is enabled to Notify */
P2P_LedCharValue_t LedControl;
P2P_ButtonCharValue_t ButtonStatus;
uint16_t ConnectionHandle;
} P2P_Client_App_Context_t;
/* USER CODE END PTD */
/* Private defines ------------------------------------------------------------*/
@ -133,14 +154,16 @@ PLACE_IN_SECTION("BLE_APP_CONTEXT") static P2P_ClientContext_t aP2PClientContext
* END of Section BLE_APP_CONTEXT
*/
/* USER CODE BEGIN PV */
PLACE_IN_SECTION("BLE_APP_CONTEXT") static P2P_Client_App_Context_t P2P_Client_App_Context;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
static void Gatt_Notification(P2P_Client_App_Notification_evt_t *pNotification);
static SVCCTL_EvtAckStatus_t Event_Handler(void *Event);
/* USER CODE BEGIN PFP */
static tBleStatus Write_Char(uint16_t UUID, uint8_t Service_Instance, uint8_t *pPayload);
static void Button_Trigger_Received( void );
static void Update_Service( void );
/* USER CODE END PFP */
/* Functions Definition ------------------------------------------------------*/
@ -153,7 +176,20 @@ void P2PC_APP_Init(void)
{
uint8_t index =0;
/* USER CODE BEGIN P2PC_APP_Init_1 */
log_debug("P2PC_APP_Init", "enter", 0);
UTIL_SEQ_RegTask( 1<< CFG_TASK_SEARCH_SERVICE_ID, UTIL_SEQ_RFU, Update_Service );
UTIL_SEQ_RegTask( 1<< CFG_TASK_SW1_BUTTON_PUSHED_ID, UTIL_SEQ_RFU, Button_Trigger_Received );
/**
* Initialize LedButton Service
*/
P2P_Client_App_Context.Notification_Status=0;
P2P_Client_App_Context.ConnectionHandle = 0x00;
P2P_Client_App_Context.LedControl.Device_Led_Selection=0x00;/* device Led */
P2P_Client_App_Context.LedControl.Led1=0x00; /* led OFF */
P2P_Client_App_Context.ButtonStatus.Device_Button_Selection=0x01;/* Device1 */
P2P_Client_App_Context.ButtonStatus.Button1=0x00;
/* USER CODE END P2PC_APP_Init_1 */
for(index = 0; index < BLE_CFG_CLT_MAX_NBR_CB; index++)
{
@ -188,13 +224,26 @@ void P2PC_APP_Notification(P2PC_APP_ConnHandle_Not_evt_t *pNotification)
case PEER_CONN_HANDLE_EVT :
/* USER CODE BEGIN PEER_CONN_HANDLE_EVT */
P2P_Client_App_Context.ConnectionHandle = pNotification->ConnectionHandle;
/* USER CODE END PEER_CONN_HANDLE_EVT */
break;
case PEER_DISCON_HANDLE_EVT :
/* USER CODE BEGIN PEER_DISCON_HANDLE_EVT */
{
uint8_t index = 0;
P2P_Client_App_Context.ConnectionHandle = 0x00;
while((index < BLE_CFG_CLT_MAX_NBR_CB) &&
(aP2PClientContext[index].state != APP_BLE_IDLE))
{
aP2PClientContext[index].state = APP_BLE_IDLE;
}
// BSP_LED_Off(LED_BLUE);
#if OOB_DEMO == 0
UTIL_SEQ_SetTask(1<<CFG_TASK_CONN_DEV_1_ID, CFG_SCH_PRIO_0);
#endif
}
/* USER CODE END PEER_DISCON_HANDLE_EVT */
break;
@ -210,7 +259,10 @@ void P2PC_APP_Notification(P2PC_APP_ConnHandle_Not_evt_t *pNotification)
return;
}
/* USER CODE BEGIN FD */
void P2PC_APP_SW1_Button_Action(void)
{
UTIL_SEQ_SetTask(1<<CFG_TASK_SW1_BUTTON_PUSHED_ID, CFG_SCH_PRIO_0);
}
/* USER CODE END FD */
/*************************************************************
@ -526,7 +578,28 @@ void Gatt_Notification(P2P_Client_App_Notification_evt_t *pNotification)
case P2P_NOTIFICATION_INFO_RECEIVED_EVT:
/* USER CODE BEGIN P2P_NOTIFICATION_INFO_RECEIVED_EVT */
{
P2P_Client_App_Context.LedControl.Device_Led_Selection=pNotification->DataTransfered.pPayload[0];
switch(P2P_Client_App_Context.LedControl.Device_Led_Selection) {
case 0x01 : {
P2P_Client_App_Context.LedControl.Led1=pNotification->DataTransfered.pPayload[1];
if(P2P_Client_App_Context.LedControl.Led1==0x00){
// BSP_LED_Off(LED_BLUE);
log_debug("Gatt_Notification", " -- P2P APPLICATION CLIENT : NOTIFICATION RECEIVED - LED OFF ", 0);
} else {
log_debug("Gatt_Notification", " -- P2P APPLICATION CLIENT : NOTIFICATION RECEIVED - LED ON", 0);
// BSP_LED_On(LED_BLUE);
}
break;
}
default : break;
}
}
/* USER CODE END P2P_NOTIFICATION_INFO_RECEIVED_EVT */
break;
@ -546,7 +619,127 @@ uint8_t P2P_Client_APP_Get_State( void ) {
return aP2PClientContext[0].state;
}
/* USER CODE BEGIN LF */
/**
* @brief Feature Characteristic update
* @param pFeatureValue: The address of the new value to be written
* @retval None
*/
tBleStatus Write_Char(uint16_t UUID, uint8_t Service_Instance, uint8_t *pPayload)
{
log_debug("Write_Char", "enter", 0);
tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
uint8_t index;
index = 0;
while((index < BLE_CFG_CLT_MAX_NBR_CB) &&
(aP2PClientContext[index].state != APP_BLE_IDLE))
{
switch(UUID)
{
case P2P_WRITE_CHAR_UUID: /* SERVER RX -- so CLIENT TX */
log_debug("Write_Char", "payload 0x%x%x", 2, pPayload[0], pPayload[1]);
ret =aci_gatt_write_without_resp(aP2PClientContext[index].connHandle,
aP2PClientContext[index].P2PWriteToServerCharHdle,
2, /* charValueLen */
(uint8_t *) pPayload);
break;
default:
break;
}
index++;
}
return ret;
}/* end Write_Char() */
void Button_Trigger_Received(void)
{
log_debug("Button_Trigger_Received", "-- P2P APPLICATION CLIENT : BUTTON PUSHED - WRITE TO SERVER ", 0);
if(P2P_Client_App_Context.ButtonStatus.Button1==0x00){
P2P_Client_App_Context.ButtonStatus.Button1=0x01;
}else {
P2P_Client_App_Context.ButtonStatus.Button1=0x00;
}
Write_Char( P2P_WRITE_CHAR_UUID, 0, (uint8_t *)&P2P_Client_App_Context.ButtonStatus);
return;
}
void Update_Service()
{
log_debug("Update_Service", "enter", 0);
uint16_t enable = 0x0001;
uint16_t disable = 0x0000;
uint8_t index;
index = 0;
while((index < BLE_CFG_CLT_MAX_NBR_CB) &&
(aP2PClientContext[index].state != APP_BLE_IDLE))
{
switch(aP2PClientContext[index].state)
{
case APP_BLE_DISCOVER_SERVICES:
log_info("Update_Service", "P2P_DISCOVER_SERVICES", 0);
break;
case APP_BLE_DISCOVER_CHARACS:
log_info("Update_Service", "* GATT : Discover P2P Characteristics", 0);
aci_gatt_disc_all_char_of_service(aP2PClientContext[index].connHandle,
aP2PClientContext[index].P2PServiceHandle,
aP2PClientContext[index].P2PServiceEndHandle);
break;
case APP_BLE_DISCOVER_WRITE_DESC: /* Not Used - No decriptor */
log_info("Update_Service", "* GATT : Discover Descriptor of TX - Write Characteritic", 0);
aci_gatt_disc_all_char_desc(aP2PClientContext[index].connHandle,
aP2PClientContext[index].P2PWriteToServerCharHdle,
aP2PClientContext[index].P2PWriteToServerCharHdle+2);
break;
case APP_BLE_DISCOVER_NOTIFICATION_CHAR_DESC:
log_info("Update_Service", "* GATT : Discover Descriptor of Rx - Notification Characteritic", 0);
aci_gatt_disc_all_char_desc(aP2PClientContext[index].connHandle,
aP2PClientContext[index].P2PNotificationCharHdle,
aP2PClientContext[index].P2PNotificationCharHdle+2);
break;
case APP_BLE_ENABLE_NOTIFICATION_DESC:
log_info("Update_Service", "* GATT : Enable Server Notification", 0);
aci_gatt_write_char_desc(aP2PClientContext[index].connHandle,
aP2PClientContext[index].P2PNotificationDescHandle,
2,
(uint8_t *)&enable);
aP2PClientContext[index].state = APP_BLE_CONNECTED_CLIENT;
log_info("Update_Service", "state: APP_BLE_CONNECTED_CLIENT", 0);
// BSP_LED_Off(LED_RED);
break;
case APP_BLE_DISABLE_NOTIFICATION_DESC :
log_debug("Update_Service", "* GATT : Disable Server Notification", 0);
aci_gatt_write_char_desc(aP2PClientContext[index].connHandle,
aP2PClientContext[index].P2PNotificationDescHandle,
2,
(uint8_t *)&disable);
aP2PClientContext[index].state = APP_BLE_CONNECTED_CLIENT;
log_info("Update_Service", "state: APP_BLE_CONNECTED_CLIENT", 0);
break;
default:
break;
}
index++;
}
return;
}
/* USER CODE END LF */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

2
nucleo-wb55-dongle-ble/STM32_WPAN/App/p2p_client_app.h

@ -70,7 +70,7 @@ void P2PC_APP_Init( void );
void P2PC_APP_Notification( P2PC_APP_ConnHandle_Not_evt_t *pNotification );
uint8_t P2P_Client_APP_Get_State( void );
/* USER CODE BEGIN EFP */
void P2PC_APP_SW1_Button_Action(void);
/* USER CODE END EFP */
#ifdef __cplusplus

40
nucleo-wb55-dongle-ble/app/Command.hpp

@ -1,40 +0,0 @@
/*
* Command.hpp
*
* Created on: Jul 8, 2021
* Author: Andreas Berthoud
*/
#ifndef SRC_COMMAND_H_
#define SRC_COMMAND_H_
#include <stdint.h>
extern "C" void pop_and_execute_commands();
extern "C" void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t length);
typedef enum : uint8_t {
COMMAND_NONE = 0,
COMMAND_LOG = 0x1,
COMMAND_HEARTBEAT_REQUEST = 0x2,
COMMAND_HEARTBEAT_RESPONSE = 0x3,
COMMAND_LED_REQUEST = 0x4,
COMMAND_LED_RESPONSE = 0x5,
COMMAND_GP_REQUEST = 0x6,
COMMAND_GP_RESPONSE = 0x7,
} CommandId;
class Command {
public:
CommandId id;
virtual ~Command() {};
virtual CommandId get_command_id() = 0;
virtual bool execute() = 0;
};
void push_command(Command * command);
#endif /* SRC_COMMAND_H_ */

16
nucleo-wb55-dongle-ble/app/commands.hpp

@ -1,16 +0,0 @@
/*
* commands.hpp
*
* Created on: Jul 13, 2021
* Author: Andreas Berthoud
*/
#ifndef COMMANDS_HPP_
#define COMMANDS_HPP_
extern "C" void log_debug(const char * format, int nargs, ...);
extern "C" void log_info(const char * format, int nargs, ...);
extern "C" void log_warning(const char * format, int nargs, ...);
extern "C" void log_error(const char * format, int nargs, ...);
#endif /* COMMANDS_HPP_ */

1
nucleo-wb55-dongle-ble/app/GPCommand.cpp → nucleo-wb55-dongle-ble/commands/GPCommand.cpp

@ -6,6 +6,7 @@
*/
#include "GPCommand.hpp"
#include "app_ble.h"
GPResponse::GPResponse(uint16_t response_identifier, bool was_successful)

0
nucleo-wb55-dongle-ble/app/GPCommand.hpp → nucleo-wb55-dongle-ble/commands/GPCommand.hpp

32
nucleo-wb55-dongle-ble/commands/dispatch.cpp

@ -0,0 +1,32 @@
/*
* dispatch.cpp
*
* Created on: 18 Jul 2021
* Author: Andreas Berthoud
*/
#include "dispatch.hpp"
#include "GPCommand.hpp"
#include "HeartbeatCommand.hpp"
#include "LedCommand.hpp"
void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t size) {
switch (command_id)
{
case COMMAND_HEARTBEAT_REQUEST:
push_command(new HeartbeatRequest(payload_ptr, size));
break;
case COMMAND_LED_REQUEST:
push_command(new LedRequest(payload_ptr, size));
break;
case COMMAND_GP_REQUEST:
push_command(new GPRequest(payload_ptr, size));
break;
default:
break;
}
}

15
nucleo-wb55-dongle-ble/commands/dispatch.hpp

@ -0,0 +1,15 @@
/*
* dispatch.hpp
*
* Created on: 18 Jul 2021
* Author: Andreas Berthoud
*/
#ifndef DISPATCH_HPP_
#define DISPATCH_HPP_
#include <stdint.h>
extern "C" void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t length);
#endif /* DISPATCH_HPP_ */

25
nucleo-wb55-dongle-ble/shared_commands/Command.hpp

@ -0,0 +1,25 @@
/*
* Command.hpp
*
* Created on: Jul 8, 2021
* Author: Andreas Berthoud
*/
#ifndef SRC_COMMAND_H_
#define SRC_COMMAND_H_
#include "commands.hpp"
class Command {
public:
CommandId id;
virtual ~Command() {};
virtual CommandId get_command_id() = 0;
virtual bool execute() = 0;
};
void push_command(Command * command);
#endif /* SRC_COMMAND_H_ */

0
nucleo-wb55-dongle-ble/app/HeartbeatCommand.cpp → nucleo-wb55-dongle-ble/shared_commands/HeartbeatCommand.cpp

0
nucleo-wb55-dongle-ble/app/HeartbeatCommand.hpp → nucleo-wb55-dongle-ble/shared_commands/HeartbeatCommand.hpp

0
nucleo-wb55-dongle-ble/app/LedCommand.cpp → nucleo-wb55-dongle-ble/shared_commands/LedCommand.cpp

0
nucleo-wb55-dongle-ble/app/LedCommand.hpp → nucleo-wb55-dongle-ble/shared_commands/LedCommand.hpp

0
nucleo-wb55-dongle-ble/app/LogCommand.cpp → nucleo-wb55-dongle-ble/shared_commands/LogCommand.cpp

1
nucleo-wb55-dongle-ble/app/LogCommand.hpp → nucleo-wb55-dongle-ble/shared_commands/LogCommand.hpp

@ -9,6 +9,7 @@
#define LOGCOMMAND_H_
#include "Notification.hpp"
#include <stdarg.h>
extern "C" void log_debug(const char * logger_name, const char * format, int nargs, ...);
extern "C" void log_info(const char * logger_name, const char * format, int nargs, ...);

0
nucleo-wb55-dongle-ble/app/Notification.cpp → nucleo-wb55-dongle-ble/shared_commands/Notification.cpp

0
nucleo-wb55-dongle-ble/app/Notification.hpp → nucleo-wb55-dongle-ble/shared_commands/Notification.hpp

0
nucleo-wb55-dongle-ble/app/Request.cpp → nucleo-wb55-dongle-ble/shared_commands/Request.cpp

0
nucleo-wb55-dongle-ble/app/Request.hpp → nucleo-wb55-dongle-ble/shared_commands/Request.hpp

0
nucleo-wb55-dongle-ble/app/Response.cpp → nucleo-wb55-dongle-ble/shared_commands/Response.cpp

0
nucleo-wb55-dongle-ble/app/Response.hpp → nucleo-wb55-dongle-ble/shared_commands/Response.hpp

0
nucleo-wb55-dongle-ble/app/command_interpreter.c → nucleo-wb55-dongle-ble/shared_commands/command_interpreter.c

6
nucleo-wb55-dongle-ble/app/commands.h → nucleo-wb55-dongle-ble/shared_commands/commands.h

@ -8,12 +8,12 @@
#ifndef COMMANDS_H_
#define COMMANDS_H_
void pop_and_execute_commands();
void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t length);
void log_debug(const char * logger_name, const char * format, int nargs, ...);
void log_info(const char * logger_name, const char * format, int nargs, ...);
void log_warning(const char * logger_name, const char * format, int nargs, ...);
void log_error(const char * logger_name, const char * format, int nargs, ...);
void pop_and_execute_commands();
void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t length);
#endif /* COMMANDS_H_ */

24
nucleo-wb55-dongle-ble/shared_commands/commands.hpp

@ -0,0 +1,24 @@
/*
* commands.hpp
*
* Created on: Jul 13, 2021
* Author: Andreas Berthoud
*/
#ifndef COMMANDS_HPP_
#define COMMANDS_HPP_
#include <stdint.h>
typedef enum : uint8_t {
COMMAND_NONE = 0,
COMMAND_LOG = 0x1,
COMMAND_HEARTBEAT_REQUEST = 0x2,
COMMAND_HEARTBEAT_RESPONSE = 0x3,
COMMAND_LED_REQUEST = 0x4,
COMMAND_LED_RESPONSE = 0x5,
COMMAND_GP_REQUEST = 0x6,
COMMAND_GP_RESPONSE = 0x7,
} CommandId;
#endif /* COMMANDS_HPP_ */

33
nucleo-wb55-dongle-ble/app/Command.cpp → nucleo-wb55-dongle-ble/shared_commands/execute.cpp

@ -1,19 +1,17 @@
/*
* Command.cpp
* execute.cpp
*
* Created on: Jul 8, 2021
* Created on: 18 Jul 2021
* Author: Andreas Berthoud
*/
#include <queue>
#include <cstring>
#include "Command.hpp"
#include "string.h"
#include "execute.hpp"
#include "stm32wbxx_hal.h"
#include "commands.hpp"
#include "HeartbeatCommand.hpp"
#include "LedCommand.hpp"
#include "GPCommand.hpp"
#include "LogCommand.hpp"
std::queue<Command*> command_queue;
@ -28,29 +26,12 @@ void pop_and_execute_commands() {
bool was_successful = command->execute();
HAL_Delay(5); // this delay is required. Otherwise, the command were not sent somehow...
if (!was_successful) {
log_error("Execution of command with ID %n was not successful!", 1, command->id);
log_error("pop_and_execute_commands", "Execution of command with ID %n was not successful!", 1, command->id);
}
delete command;
command_queue.pop();
}
}
void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t size) {
switch (command_id)
{
case COMMAND_HEARTBEAT_REQUEST:
push_command(new HeartbeatRequest(payload_ptr, size));
break;
case COMMAND_LED_REQUEST:
push_command(new LedRequest(payload_ptr, size));
break;
case COMMAND_GP_REQUEST:
push_command(new GPRequest(payload_ptr, size));
break;
default:
break;
}
}

13
nucleo-wb55-dongle-ble/shared_commands/execute.hpp

@ -0,0 +1,13 @@
/*
* execute.hpp
*
* Created on: 18 Jul 2021
* Author: Andreas Berthoud
*/
#ifndef EXECUTE_HPP_
#define EXECUTE_HPP_
extern "C" void pop_and_execute_commands();
#endif /* EXECUTE_HPP_ */

3
requirements.txt

@ -1,4 +1 @@
dependency-injector[yaml]>=4.34.0,<5
flask-api>=3.0.post1,<4
pre-commit
pyserial>=3.5,<4

Loading…
Cancel
Save