Skip to content

Commit 74cc78c

Browse files
committed
Update badge-hardware.md
1 parent 4b5c8b0 commit 74cc78c

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed

docs/tildagon-apps/reference/badge-hardware.md

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,196 @@ eventbus.emit(
598598
)
599599
```
600600

601+
## PD
602+
603+
The PD module allows sending and receiving PD messages on the USB in and out ports. The message header is handled entirely by the badge for Venodr messages and will automatically fill the fields of the header relating to the physical layer. This leaves the user to only fill the message type and number of objects for the Prime messages used to communicate with the cables plugs. The fusb302b part that the badge uses supports USB PD 2.0, Version 1.1 and uses the number of objects field of the header to determine message length, preventing us from sending extended messages. Each message that it sends must have a 2 byte header then 0-7 4 byte data objects. To assist with this the badge will padd the messsages sent to the next 4 byte boundry, so messages received from another badge may have additional 0s appended to the end.
604+
605+
### Example
606+
607+
608+
```python
609+
import settings
610+
from app import App
611+
from app_components import Menu, clear_background
612+
from system.patterndisplay.events import PatternReload
613+
from system.eventbus import eventbus
614+
from system.power import events
615+
from pd import Host, Device
616+
617+
main_menu_items = ["rainbow", "cylon", "flash", "off"]
618+
619+
class LedSyncApp(App):
620+
def __init__(self):
621+
self.usb_in = Device()
622+
self.usb_out = Host()
623+
self.menu = Menu(self, main_menu_items, select_handler=self.select_handler, back_handler=self.back_handler)
624+
eventbus.on(events.VendorMsgDevRxEvent, self._handle_dev_msg, self)
625+
eventbus.on(events.VendorMsgHostRxEvent, self._handle_host_msg, self)
626+
eventbus.on(events.BadgeAsHostAttachEvent, self._handle_host_detect, self)
627+
self.state = main_menu_items[0]
628+
629+
def _handle_dev_msg(self, event:VendorMsgDevRxEvent):
630+
msg = self.usb_in.get_vendor_msg()
631+
if msg is not None:
632+
settings.set("pattern", main_menu_items[msg[0]])
633+
eventbus.emit(PatternReload())
634+
self.state = main_menu_items[msg[0]]
635+
if self.usb_out.badge_connected():
636+
self.usb_out.send_vendor_msg(msg)
637+
638+
def _handle_host_msg(self, event:VendorMsgHostRxEvent):
639+
msg = self.usb_out.get_vendor_msg()
640+
if msg is not None:
641+
settings.set("pattern", main_menu_items[msg[0]])
642+
eventbus.emit(PatternReload())
643+
self.state = main_menu_items[msg[0]]
644+
if self.usb_in.badge_connected():
645+
self.usb_in.send_vendor_msg(msg)
646+
647+
def _handle_host_detect(self, event:BadgeAsHostAttachEvent):
648+
idx = main_menu_items.index(self.state)
649+
self.usb_out.send_vendor_msg(bytearray([idx]))
650+
651+
def select_handler(self, item, item_idx):
652+
self.state = main_menu_items[item_idx]
653+
settings.set("pattern", main_menu_items[item_idx])
654+
eventbus.emit(PatternReload())
655+
if self.usb_in.badge_connected():
656+
self.usb_in.send_vendor_msg(bytearray([item_idx]))
657+
if self.usb_out.badge_connected():
658+
self.usb_out.send_vendor_msg(bytearray([item_idx]))
659+
660+
def back_handler(self):
661+
self.minimise()
662+
663+
def draw(self, ctx):
664+
clear_background(ctx)
665+
self.menu.draw(ctx)
666+
667+
def update(self, delta):
668+
self.menu.update(delta)
669+
670+
__app_export__ = LedSyncApp
671+
```
672+
673+
### Usage
674+
675+
To use either of the USB ports for PD communications, import the Host or Device classes. To assist with the creation of a message import the helper.
676+
```python
677+
from pd import Host, Device
678+
```
679+
680+
Then create the objects,
681+
```python
682+
usb_in = Device()
683+
usb_out = Host()
684+
```
685+
686+
Check the connection state and send a message
687+
```python
688+
if usb_out.pd_enabled():
689+
usb_out.send_vendor_msg(data, length)
690+
```
691+
692+
693+
### Methods
694+
695+
Both the Host and Device ports support the following methods.
696+
697+
<!-- prettier-ignore -->
698+
| Method | Description | Arguments | Returns |
699+
| ------ | ----------- | --------- | ------- |
700+
| connected | Gets if the badge is connected as a device. | None. | `state`(`bool`): Connection state |
701+
| pd_enabled | Is the PD enbled on this port | None | `state`(`bool`): PD enabled |
702+
| badge_connected | Gets if the badge is connected to another badge as a device | None. | `state`(`bool`): Connection state |
703+
| get_vendor_msg | Gets vendor message from the in port | None. | `message`(`tuple`): `vendor header`(int) message header, `length`(`int`)message length, `buffer`(`list`) list of data |
704+
| send_vendor_msg | Sends a vendor message on the in port | `data`(`bytearray`): data, contents (VDOs) left to the user and the helper. the data will be padded to the 4 byte VDO boundry, max 28 bytes | None. |
705+
706+
The Host port also supports sending messages to the cable plug at either end, known as prime and double prime messages. The are as follwos:
707+
708+
<!-- prettier-ignore -->
709+
| Method | Description | Arguments | Returns |
710+
| ------ | ----------- | --------- | ------- |
711+
| send_prime_msg | Send a prime message | `data`(`bytearray`): data, must include 2 byte header | None |
712+
| send_dbl_prime_msg | Send a double prime message | `data`(`bytearray`): data, must include 2 byte header | None |
713+
| get_prime_msg | Get a received prime message | None | `data`(`bytearray`): data, includes 2 byte header |
714+
| get_dbl_prime_msg | Get a received double prime message| None | `data`(`bytearray`): data, includes 2 byte header |
715+
716+
### Events
717+
718+
<!-- prettier-ignore -->
719+
| Method | Description |
720+
| ------ | ----------- |
721+
| BadgeAsDeviceAttachEvent | The badge has detected another badge and connected as a device |
722+
| BadgeAsDeviceDetachEvent | The badge has disconnected |
723+
| BadgeAsHostAttachEvent | The badge has detected another badge and connected as a host |
724+
| BadgeAsHostDetachEvent | The badge has disconnected |
725+
| VendorMsgDevRxEvent | The badge has received a message on the USB in port |
726+
| VendorMsgHostRxEvent | The badge has received a message on the USB out port |
727+
| PrimeMsgHostRxEvent | The badge has received a prime message on the USB out port |
728+
| DblPrimeMsgHostRxEvent | The badge has received a double prime message on the USB out port |
729+
730+
## PD helper
731+
732+
Here is the helper api. It can be used to create structured and unstructured vendor headers and send the badge id message. The badge id message is sent automatically on connection to the usb out port. If this is detected by another badge on the usb in port it will respond with the same message and set the badge connected state to true. The vendor header is only required when not communicating with another badge.
733+
734+
### Example
735+
736+
```python
737+
from system.power.pd_helper import pdHelper
738+
739+
pdh = pdHelper()
740+
pdh.device_send_badge_id()
741+
```
742+
743+
### Usage
744+
The helper can be used as follows to create the headers required for a discover identity command.
745+
746+
```python
747+
from system.power.pd_helper import pdHelper, vdmCmd
748+
749+
pdh = pdHelper()
750+
header = pdh.header(dataType.VENDOR_DEFINED, 1)
751+
vendor_header = pdh.vdm_structured_header(vdmCmd.DISCOVER_IDENTITY, 0xFF00, 0, 0)
752+
usb_out = Host()
753+
usb_out.send_prime_msg(
754+
header.to_bytes(2, "little") + vendor_header.to_bytes(4, "little")
755+
)
756+
```
757+
758+
### Methods
759+
760+
<!-- prettier-ignore -->
761+
| Method | Description | Arguments | Returns |
762+
| ------ | ----------- | --------- | ------- |
763+
| device_send_badge_id | Sends the id used to detect another badge on the USB in port | None | None |
764+
| host_disc_id_dbl_prime | Sends the discover identity command to a cables plug | None | None |
765+
| host_disc_id_prime | None | None |
766+
| host_send_badge_id | Sends the id used to detect another badge on the USB out port | None | None |
767+
| pd_header | Create a message header with space for the badge to fill in physical layer info | `message_type`(`int`): see dataType and cmdType below, `no_objects`(`int`): number of 4 byte objects, optional, default 0 | `header`(`int`): 16 bit header |
768+
| vdm_structured_header | Creates a structured vendor header | `command`(`int`): see vdmCmd below, `SVID`(`int`): Standard or Vendor ID, optional, default 0xFF00, `obj_pos`(`int`):For the Enter Mode, Exit Mode and Attention Commands, optional, default 0, `version`(`int`): Structured VDM Version, optional, default 0, | `vendor_header`(`int`): 32 bit vendor header |
769+
| vdm_unstructured_header | Creates an unstructured vendor header | `SVID`(`int`): optional, default 0xFF00, `data`(`int`): 15 bits of vendor defined data | `vendor_header`(`int`): 32 bit vendor header |
770+
| vdm_header_extract | extract the fields of a vendor header | `vendor_header`(`int`): 32 bit vendor header | `vendor_header`(`dict`): dictionary containing each field of the header |
771+
772+
### Constants
773+
774+
The following constants are available for use in the two headers.
775+
776+
<!-- prettier-ignore -->
777+
| Class | Constant |
778+
| ------ | ----------- |
779+
| vdmCmd | DISCOVER_IDENTITY |
780+
| vdmCmd | DISCOVER_SVIDS |
781+
| vdmCmd | DISCOVER_MODES |
782+
| vdmCmd | ENTER_MODE |
783+
| vdmCmd | EXIT_MODE |
784+
| vdmCmd | ATTENTION |
785+
| dataType | BIST |
786+
| dataType | VENDOR_DEFINED |
787+
| cmdType | ACCEPT |
788+
| cmdType | REJECT |
789+
| cmdType | SOFT_RESET |
790+
601791
## I2C
602792

603793
The badge supports the [I2C communication protocol](https://www.circuitbasics.com/basics-of-the-i2c-communication-protocol/) on a bus for each hexpansion slot. Hexpansion slots are numbered

0 commit comments

Comments
 (0)