-
Hi there !
I finally took the time to write a "little" helper after digging stuff online & not finding exactly what I was after ..
.. "tadaa": https://github.com/stephaneAG/EAGLE-stuff/blob/master/Protographer/README.MD
The above, while not yet supporting "pads", was indeed quite useful to quickly draw stuff Eagle side :)
The below image shows the footprints created by it ( the one with the pads had the pads added manually )
I'll have to add the needed buttons to the schematic ( as well as battery charging & cie ) & the footprint for an HC-05 & an XS3868
For the uC part, I guess I'll prepare a "breakout" embedding all the necessary & then provide declinations offering different uC pins ( or the pads for directly soldering a uC - I wonder if I'll be precise enough to solder some SMD parts, since I only practiced that while switching memory ICs on ESP8266 :| .. so wayyy not confident on drag soldering a stm32f407VGT6 myself .. ;p )
-
Hi there :)
nice work !
For the rumble & LEDs, this could be really cool since we could update onboard stuff to reflect that ;)
For the "more than one controller connect" / Xbox co-pilot feature, it's also pretty cool ( I actually didn't know Microsoft offered such functionality ).
I didn't took the time to test the PJRC Joystick/gamepad example, only dogged through it among many other files to get an overview of how things were implemented ( I was planning to mod MSF-XINPUT to not auto-release stuff & press stuff received over serial as latest test using a teensy & the xbox360 part of things )
If mapping it all that's needed to get rid of the flakiness of the PS4 controller, I'd be happy to Digg that part when having time to doing so :)
On the controller auth part, I honestly am still way too weak to produce it by myself, but I plan to continue digging the USB Host stack on the smt32 as well as figuring out how to handle that kind of event ( I guess the author of MSF-XINPUT may know or have some hints, since this boils down to knowing when a "led event" is received for the first time ( providing visual feedback of connection & on which player number is assigned to which controller ) & passing stuff through a different pipe when receiving some from the host console )
If you say so, I guess I'll then hold on to it for later ..
For the usefulness of an adaptive controller ( Teensy or Espruino based ) for Windows/Linux/Steam/Mac, I totally agree, and I guess this will be the first version released ( able to connect over bluetooth or usb as HID since Windows/Linux/Mac need no drivers whatsoever & Steam surely can use HID-compliant devices )
On the way assistive tech devices works, I'll have to investigate too, and was indeed planning for such implementation ( the joystick connected to the sides of the adaptive controller will get 4 lines though, +V, X, Y & Gnd )
Last but not least, I'd be happy to fiddle with your code if you were to drop by some zip file ;)
-
-
@gdsports Hi there ! -> Kinda-still-very-much-interested indeed :D
I was coming here for a quick update & few questions, and your intervention is unexpected & full of hope ^^
If you want some more infos on controller authentication, I can provide you the links I used while digging the subject :)
And yes, If you do manage to get an xbox360 passthrough, it should work as expected ( allowing buttons to be either really pressed or "simulated" by the MitM code & gamepad updates to be received (rumble, leds, ..) ).
Although I bet you could produce code that 'd work as expected to bypass the auth part only from enough infos on the way the gamepad responds once it has been fully authenticated, what about a "little" helper" ? -> as I resurrected my 1st xbox360 & until I send it to my cousin as a gift, what about sending it to you so that you can better work on that hack & have some fun doing so ? :PSorry for the confusion:
The "Xbox360 passthrough" project would be a very neat addition to the "Espruino adaptive controller" project, since it could allow using it on ALL consoles ( additionally to a computer whatever the operating system its running, as appearing as standard HID peripheral ).
Once of the reasons I'm digging a board other than the standard Espruino ones while keeping stuff on stm32 platform is:
- to have more pins available to be used as GPIOs, for bluetooth (hc-05) & for wifi (esp8266) without using an expander/shift register/mux & cie
- to be able to support a "USB Host" mode with an additional USB connector
- to be able to reuse code on official Espruino boards
Hence, two ways to achieve the desired goal(s):
- have a Teensy + an Espruino ( or run Espruino on the Teensy ? not my case currently .. )
- have Espruino running on an STM32 board than provides USB Host capability & handling such feature in C++ while providing wrapper(s)/callback(s) in js
The project is also intended as a rough template for other Espruino-based gamepads & cie ;)
I successfully achieved HID gamepad on the STM32F407VGT6diymrOE board running only ST's code ( not Espruino ) when connecting to Windows, but for some reason it doesn't appear on Mac OS ( even with the external pull-up resistor trick, and even when pressing the btn prior to connecting the board :/ .. )
I also had success running an Espruino build meant for the STM32F4DISCOVERY on the STM32F407VGT6diymrOE board & connecting to it via Bluetooth using an hc-05, but not via USB :/
I'm currently digging ST's USB Host stuff & it's wayyyy over my head tight now :| ( too bad, gotta have to Digg more & harder :p )
I recently ( yesterday actually ) created a board.py to be able to better match the STM32F407VGT6diymrOE onboard components, but for some reason I can't use 'setUSBHID()' nor the related 'send()' fcn :/ ( I guessed this comes from a flag that isn't set when building - 'USEUSBHID' if I remember correcly, but I didn't intend a custom build yet, as this was one of my questions ;) )
On the same subject, I wonder if there's a way to set some pins as high by default within the board.py file ? ( I now know it's done in CubeMX or ST's main.c via stuff like
HAL_GPIO_WritePin(EXTLED_GPIO_Port, EXTLED_Pin, GPIO_PIN_RESET);
) but I'm not sure how this is handled in the board.py file ..I received some necessary parts ( TRRS & TRS connectors, USB connectors ) today & since I can't find the footprints of those, I just finished digging how to do custom footprints on Eagle to "port" my Illustrator drawings as soon as I finish reporting the dimensions & pinouts & go further on this part of the project
( I'll post those as well as a link to where they can be purchased in few mins or tomorrow ;) )This being said, the following is the board.py file I intend to use for building Espruino from the latest source ( same as the F4discovery but with less stuff / different on it ): I'm still unsure if this 'll work & the exact procedure to produce a clean build but I bet digging the "building" section won't hurt ( should be one of the easier methods since this is a stm32 board .. hoping so ;) )
#!/bin/false # This file is part of Espruino, a JavaScript interpreter for Microcontrollers # # Copyright (C) 2013 Gordon Williams <gw@pur3.co.uk> # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # ---------------------------------------------------------------------------------------- # This file contains information for a specific board - the available pins, and where LEDs, # Buttons, and other in-built peripherals are. It is used to build documentation as well # as various source and header files for Espruino. # ---------------------------------------------------------------------------------------- import pinutils; info = { 'name' : "STM32 F407VGT6 diymroe", 'link' : [ "https://edoc.site/diy-more-stm32f407vgt6-boar1-pdf-free.html" ], 'default_console' : "EV_SERIAL2", # FIXME: This was S2 because of pin conflict. Not sure if it's really an issue? - seemed to work for me for now .. 'variables' : 5450, 'binary_name' : 'espruino_%v_stm32f407vgt6diymroe.bin', 'build' : { 'optimizeflags' : '-O3', 'libraries' : [ 'NET', 'GRAPHICS', 'NEOPIXEL' ], 'makefile' : [ [#DEFINES](https://forum.espruino.com/search/?q=%23DEFINES)+=-DUSE_USB_OTG_FS=1', 'DEFINES+=-DUSE_USB_OTG_FS=1 -DUSE_USB_HID=1', # trying to do USB HID stuff on the STM32F4 .. 'd be AWESOME considering the number of pins available 'STLIB=STM32F407xx', 'PRECOMPILED_OBJS+=$(ROOT)/targetlibs/stm32f4/lib/startup_stm32f40_41xxx.o' ] } }; chip = { 'part' : "STM32F407VGT6", 'family' : "STM32F4", 'package' : "LQFP100", 'ram' : 192, 'flash' : 1024, 'speed' : 168, 'usart' : 6, 'spi' : 3, 'i2c' : 3, 'adc' : 3, 'dac' : 2, }; devices = { 'OSC' : { 'pin_1' : 'H0', 'pin_2' : 'H1' }, 'OSC_RTC' : { 'pin_1' : 'C14', 'pin_2' : 'C15' }, 'LED1' : { 'pin' : 'E0', 'pinstate' : 'IN_PULLDOWN' }, # may have to be changed to IN_PULLUP ( R: LED goes on when E0 is low - uC sinks it on ) 'BTN1' : { 'pin' : 'D15', 'pinstate' : 'IN_PULLDOWN' }, 1 should be ok ? 'USB' : { 'pin_otg_pwr' : 'C0', 'pin_dm' : 'A11', 'pin_dp' : 'A12', 'pin_vbus' : 'A9', 'pin_id' : 'A10', }, 'JTAG' : { 'pin_MS' : 'A13', 'pin_CK' : 'A14', 'pin_DI' : 'A15' }, }; # left-right, or top-bottom order - TODO: find a way to accomodate that ? ( ex: loading my svg with static stuff for now ? ) board = { 'left' : [ 'GND', 'VDD', 'GND', 'C1','C3','A1','A3','A5','A7','C5','B1','GND','E7','E9','E11','E13','E15','B11','B13','B15','D9','D11','D13','D15','GND'], 'left2' : [ 'GND', 'VDD', 'NRST', 'C0','C2','A0','A2','A4','A6','C4','B0','B2','E8','E10','E12','E14','B10','B12','B14','D8','D10','D12','D14','NC','GND'], 'right2' : [ 'GND', '5V', '3V3', 'H0', 'C14','E6','E4','E2','E0','B8','BOOT0','B6','B4','D7','D5','D3','D1','C12','C10','A14','A10','A8','C8','C6','GND'], 'right' : [ 'GND', '5V', '3V3', 'H1', 'C15','C13','E5','E3','E1','B9','VDD','B7','B5','B3','D6','D4','D2','D0','C11','A15','A13','A9','C9','C7','GND'], }; board["_css"] = """ [#board](https://forum.espruino.com/search/?q=%23board) { width: 680px; height: 1020px; left: 200px; background-image: url(img/STM32F407VGT6diymroe.jpg); } [#boardcontainer](https://forum.espruino.com/search/?q=%23boardcontainer) { height: 1020px; } [#left](https://forum.espruino.com/search/?q=%23left) { top: 375px; right: 590px; } [#left2](https://forum.espruino.com/search/?q=%23left2) { top: 375px; left: 105px; } [#right](https://forum.espruino.com/search/?q=%23right) { top: 375px; left: 550px; } [#right2](https://forum.espruino.com/search/?q=%23right2) { top: 375px; right: 145px; } """; def get_pins(): pins = pinutils.scan_pin_file([], 'stm32f40x.csv', 6, 9, 10) return pinutils.only_from_package(pinutils.fill_gaps_in_pin_list(pins), chip["package"])
The attached file ( if upload works ) is the pinout for the board + few handy wip notes ( I didn't take/have the time to do a proper "background-image" for the doc part, but this is incredibly handy as is as well ;P )
- to have more pins available to be used as GPIOs, for bluetooth (hc-05) & for wifi (esp8266) without using an expander/shift register/mux & cie
-
-
Hi there !
Thanks for all that :)
Good to know for the L4 ( I bet the ST guys find Espruino very neat ;p )
Understood ( for "on my own" on the other board ): so I'll have that kind of fun if trying to do so ;)
For the 52840, I just checked the topic you linked to: this is pretty cool ( can't wait to test/help on that subject .. & get fully custom HID over USB/bluetooth :D ) !!
For porting to other boards, I bet you're more than busy hence I'll rely on digging myself & the community to sort things out ;)
On the build process / build changes / improving Espruino side of things, I wish I had a solution to this but aside from more people full time I have no clues on how to help that ( other than digging & helping myself when I can afford to do so :) ) :/
On the "xbox360 passthrough" side of things, it seems the Teensy 3.6 offers usb host capability, so I'll try that as well as a tacky transistors+diodes setup ( just to see HOW it fails ;) )
( related post on dedicated forum: https://forum.pjrc.com/threads/54026-Teensy-3-6-Xbox360-USB-Passthrough?p=189233#post189233)I'll give back updates as I go :)
Keep up the good work ++ -
All right, I checked some things out, but it seems the F4 discovery board has been replaced by the STM32F407VG
Looking for it online, I guess the following is fully ok with Espruino ? https://www.ebay.fr/itm/Stm32f4-Discovery-Stm32f407-Cortex-m4-Development-Board-st-link-V2/263287563871?hash=item3d4d29665f:g:EsEAAOSwhUtbUwub:rk:3:pf:0Also, do you think the following could work ok ( maybe with some tweaks* ? ) https://www.ebay.fr/itm/STM32F407VGT6-ARM-Cortex-M4-32-bit-MCU-Core-Discovery-Development-Board-STM32F4/263106386751
*reading the following's 1st page, is seems that the onboard chip is the same ? https://ucilnica.fri.uni-lj.si/pluginfile.php/21843/mod_resource/content/0/user_manual_stm_discovery.pdf
If so, I guess the latter would just require using another board ST-LINK embed programmer or USB-FTDI adapter to get things ready for dev, right ? ( I found this on the topic: https://www.stm32duino.com/viewtopic.php?f=39&t=2666)I 'll have to check the diffs between the former & the latter ( don't know yet what 'T6' stands for ), but the 2nd one's pricing sparks my interest .. ;)
On this, do you have the formulas to calculate how many jsvars 'd fit for a particular board's flash size ? ( I'd hugely prefer to Digg by myself & not take someone else's time for further investigations )thanks :)
-
@allObjects haha ^^, it seemed so ;P
On the link you posted, nice Morse code logging ! ( although it was a little cryptic for me at first ;) )@Gordon I just had a look at the beast .. indeed, but so sad that it doesn't offer every pins it provides on connectors :/ For my current needs & considering the price I guess an STM32F4DISCOVERY 'd be a nice fit if fully supported by Espruino :)
On the nRF side, I just saw these & they seem quite neat ;)
Since I don't know at all the nRF platform, I currently can't be of any help on these :/
But hey, if the stack doesn't change ( too much ? ) between the kit I have yet to try & the said one, I'll be glad to digg the subject & try things out ;)For the struct size stuff, I tried the following quick test ( on laptop since I don't know yet how to get logs .. using stg else than leds now ;p ) and the result is the expected 6 ..
// gcc test.c -Wall -o test.a // nb: could the makefile used set some padding ? [#include](https://forum.espruino.com/search/?q=%23include) <stdio.h> [#include](https://forum.espruino.com/search/?q=%23include) <stdint.h> /* to use uint16_t & cie */ int main(void){ //int main(int argc, char *argv[]){ struct gamepadHID_t { uint16_t buttons; //uint8_t buttons1; //uint8_t buttons2; int8_t left_x; int8_t left_y; int8_t right_x; int8_t right_y; }; struct gamepadHID_t gamepadHID; gamepadHID.buttons = 0b0000000000000000; //gamepadHID.buttons1 = 0b00000000; //gamepadHID.buttons2 = 0b00000000; gamepadHID.left_x = 0b00000000; gamepadHID.left_y = 0b00000000; gamepadHID.right_x = 0b00000000; gamepadHID.right_y = 0b00000000; // debug printf("struct size (unsigned long): %lu \n", sizeof(gamepadHID) ); return 0; }
I'll try things out later today & report back :)
& before I forget, I saw these links on some way to flash the HM-10 for custom HID stuff if I'm correct :)
https://geekhack.org/index.php?topic=62236.0 -
Back ;)
@allObjects thanks for the confirmation, I guessed so but wasn't quite sure ;)
This being said, in your 'HLHKLHL' chunk, does 'K' stands for tri-state/floating ? ( or is it just that you typed quite fast & that the 'K' keystroke was not meant to happen ? ^^ )
I read so for the 'bundle auto configured pins' & cie in the pinMode ref, but didn't actually do tests on pinMode to consider it a resource hog ;)
If theres' no need to 'force' it by using pinMode ( as Gordon says ) I guess I can consider this 'solved' ('d be better actually test 1st, but the logic is validated :) )@Gordon I don't know enough yet on the F3 USB stack to even consider being able to see the differences between it & the F1's / F4's so yup, switching boards is 'd be indeed a 'faster & safer' way ( although I could acquire quite a - not that useful afterward- knowledge on their particular implm changes ..)
Digging how to do stuff directly on the F3 already showed me some changes that did happen// basic example of changes in namings of constants USER_BUTTON_GPIO_Port, USER_BUTTON_Pin // are now B1_GPIO_Port, B1_Pin // same goes for LEDS - some consts are kept ( fcn name, GPIO_PIN_SET, GPIO_PIN_RESET, ..) HAL_GPIO_WritePin(USER_LED_9_GPIO_Port, USER_LED_9_Pin, GPIO_PIN_SET); // is now HAL_GPIO_WritePin(LD9_GPIO_Port, LD9_Pin, GPIO_PIN_SET);
If I recall coreectly, I noticed some Espruino files you pointed me to use 'stdPeriph' stuff & not HAL ? ( I may be incorrect on this, I'm still getting my head around the stm32f platform ..)
On the examples I'm currently trying, I gotta switch from HID to CDC* ( then try the combo ;p ) & implement the xbox360 controller on that. If I manage to do so, adding its functionnality to Espruino builds would then 'just' be some js wrappers for C++ calls ( but this is a part I have yet to discover & cover ;P )
*to try an example doing UART communication with either a laptop or another uC. next on the list is I2C, then SPI ;)
Do you have in mind a F4 board that would be a kick ass with many pins ? I plan ( & 'd love ) to use Espruino on a client project but I have to use something reliable ( so not my own mess around the F3 .. ), and since it focuses on an 'Escape Game' room, having plenty of pins is quite handy :D
On the "Espruino Open Adaptive gamepad' topic, I was wondering if there's any USB stack on the nRF boards or the MDBT42Q ?
My reasons:
- I really wished a flashed HC-05 allowed custom HID over bluetooth, but it doesn't ( only presets )
- I need something that can appear as a custom periph( HID or xbox360controller ) over USB
- having embed WiFi is a plus, allowing realtime buttons mapping changes through an app on laptop/tablet/smartphone when connecting the uC as either a server or client while acting as a bluetooth or usb device
Currently, I'm using an Espruino WiFi for the wifi part & the usb HID part, & a teensy for the xbox360controller part
Once I achieve an xbox360controller on the Espruino WiFi over USB, I won't need the teensy anymore, but 'd still need a platform to do custom HID ( & more ? ) over bluetooth ..
The best 'd be a board that offers both & works fully with Espruino with plenty of pins :p.. GCC/whatever is padding the elements inside gamepadHID_t to 4 byte boundaries* ..
.. ooks like it's 6 bytes but it may get reported as 8**. ..
I'll have to digg those, yet it seems the Gamepad HID I implemented on the f3 acts as expected using the following:// while(1) if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == GPIO_PIN_SET){ HAL_GPIO_WritePin(LD9_GPIO_Port, LD9_Pin, GPIO_PIN_SET); // stuff is set above in code, whatever the 'actual' state of the button press .. USBD_HID_SendReport(&hUsbDeviceFS, &gamepadHID, sizeof(struct gamepadHID_t)); HAL_Delay(50); gamepadHID.buttons = 0; gamepadHID.left_x = 0; gamepadHID.left_y = 0; gamepadHID.right_x = 0; gamepadHID.right_y = 0; USBD_HID_SendReport(&hUsbDeviceFS, &gamepadHID, sizeof(struct gamepadHID_t)); HAL_Delay(200); HAL_GPIO_WritePin(LD9_GPIO_Port, LD9_Pin, GPIO_PIN_RESET); }
*, ** how to know if padding is allowed by GCC ? do you have a quick way to log the size of a report being sent ? ( I'm windering how much I'd need to mod the HID code I'm using to be able to use one of the available uarts to print debig stuff .. since I don't know gdb yet :/ .. )
From my tests on another little program, using the struct with on uint16_t or 2 uint8t led, quite logically, to 6 bytes, but I wonder how to get the 'final' report size before its gets sent over ..RN42 links and code
-> my pleasure ;Pps: I plan to produce 3ds for the 'espruino_OpenAdaptiveController.pdf ' at the end of the week :)
ps2: I wonder how much more 'd be involved to get a 'modified' Espruino WiFi board with more broken out pins ( fro the datasheet, 35/50/81 ? :D )I'll be back with updates as soon as can do, as usual :)
Big thanks for the hints ;)
+ - I really wished a flashed HC-05 allowed custom HID over bluetooth, but it doesn't ( only presets )
-
Since attaching a file didn't work for the image I tried to attach & I just finished testing basic stuff around on Espruino 1V50 firmware for stm32f3discovery, here I try again the attachement ( & post stm's test code here as well ;) )
/* Espruino on STM32F3DISCOVERY Docs: https://github.com/espruino/Espruino/blob/master/boards/pins/stm32f303.csv https://github.com/espruino/Espruino/blob/master/boards/STM32F3DISCOVERY.py R: connect 'USB ST-LINK' to update Espruino firmware using st-flash utility R: connect 'USB USER' only for using Espruino R: to 'refresh' the board, unplug/replug 'USB USER' Nb: currently has troubles when code is 'sent' from right side of IDE, even at 9600 bauds & with throttling .. //> Prompt not detected - upload failed. Trying to recover... */ function buttonWatcher(e) { console.log('Hello World Espruino STM32F3DISCOVERY !'); } function btnPressed(){ var btnState = digitalRead(BTN1); if( btnState == 1 ){ console.log(e.time); } } var btnPollT; //pinMode(BTN1, 'input'); // on A0 - same as below //pinMode(BTN1, 'input_pulldown'); // on press, digitalRead displays 1 //setWatch(buttonWatcher, BTN1, {edge:"falling", repeat:true}); // USB.setConsole(); to prevent 'Console Moved from Serial1' on boot ? // WARNING: Parent must be a proper object - not a String, Integer, etc. ? //E.on('init', function() { // didn't work // worked :) function onInit(){ digitalWrite(LED2, 1); // blue led on console.log("Hello World!"); digitalWrite(LED3, 1); // orange led on //setWatch(buttonWatcher, BTN1, {edge:"falling", repeat:true}); // nope //setWatch(buttonWatcher, BTN1, {edge:"rising", repeat:true}); // nope btnPollT = setTimeout(btnPressed, 1000); // btn polling - nope digitalWrite(LED4, 1); // green led on USB.setConsole(); digitalWrite(LED1, 1); // red led on } //});
-
All right !
So:
Thanks to @Frida, I checked few versions of the Espruino firmwares & found one working:1V50 ( yup, a nice release from 2014-02-06 ;p )Heading to the http://www.espruino.com/ReferenceSTM32F3DISCOVERY page, I hacked something up to better visualize the overlay legends for the row of pins: this solution is the best I have in mind ( doesn't move the pins legends ), involves no modification of the page html structure & is purely css.
I didn't take the time to check if other boards overlay legends had the same overlapping problem, but I think this solution may come quite handy for some :)// proposal for the ReferenceSTM32F3DISCOVERY page ( & others ? ) // generic css way to prevent overlapping pin rows legends ;) [#boardcontainer](https://forum.espruino.com/search/?q=%23boardcontainer):hover [#left](https://forum.espruino.com/search/?q=%23left) { opacity: 0.1; } [#boardcontainer](https://forum.espruino.com/search/?q=%23boardcontainer):hover [#left2](https://forum.espruino.com/search/?q=%23left2) { opacity: 0.1; } [#boardcontainer](https://forum.espruino.com/search/?q=%23boardcontainer):hover [#right](https://forum.espruino.com/search/?q=%23right) { opacity: 0.1; } [#boardcontainer](https://forum.espruino.com/search/?q=%23boardcontainer):hover [#right2](https://forum.espruino.com/search/?q=%23right2) { opacity: 0.1; } [#boardcontainer](https://forum.espruino.com/search/?q=%23boardcontainer):hover [#left](https://forum.espruino.com/search/?q=%23left):hover { opacity: 1; z-index: 10; } [#boardcontainer](https://forum.espruino.com/search/?q=%23boardcontainer):hover [#left2](https://forum.espruino.com/search/?q=%23left2):hover { opacity: 1; z-index: 10; } [#boardcontainer](https://forum.espruino.com/search/?q=%23boardcontainer):hover [#right2](https://forum.espruino.com/search/?q=%23right2):hover { opacity: 1; z-index: 10; } [#boardcontainer](https://forum.espruino.com/search/?q=%23boardcontainer):hover [#right](https://forum.espruino.com/search/?q=%23right):hover { opacity: 1; z-index: 10; }
This got me wondering if we could have ( or if there is ) a way to have js as well as css for /boards/STM32F3DISCOVERY.py & others ?
board["_js"] = """ /* Espruino - prevent pins overlay legends from overlapping when hovering */ var customStyle = document.createElement('style'); customStyle.textContent = '#boardcontainer:hover [#left](https://forum.espruino.com/search/?q=%23left) { opacity: 0.1; }' + '#boardcontainer:hover [#left2](https://forum.espruino.com/search/?q=%23left2) { opacity: 0.1; }' + '#boardcontainer:hover [#right](https://forum.espruino.com/search/?q=%23right) { opacity: 0.1; }' + '#boardcontainer:hover [#right2](https://forum.espruino.com/search/?q=%23right2) { opacity: 0.1; }' + '#boardcontainer:hover [#left](https://forum.espruino.com/search/?q=%23left):hover { opacity: 1; z-index: 10; } ' + '#boardcontainer:hover [#left2](https://forum.espruino.com/search/?q=%23left2):hover { opacity: 1; z-index: 10; } ' + '#boardcontainer:hover [#right2](https://forum.espruino.com/search/?q=%23right2):hover { opacity: 1; z-index: 10; } ' + '#boardcontainer:hover [#right](https://forum.espruino.com/search/?q=%23right):hover { opacity: 1; z-index: 10; } '; document.body.appendChild(customStyle); """
This being said, I don't know yet which file to edit to add a little more content to the generated page ( espruino.com/ReferenceSTM32F3DISCOVERY ): I took some notes on the LEDS positions, colors & mapping that could be neat to have on this page as a reminder
pin onboard label Espruino label color position E9 LD3 LED1 RED UP E8 LD4 LED2 BLUE UP-LEFT E10 LD5 LED3 ORANGE UP-RIGHT E15 LD6 LED4 GREEN LEFT E11 LD7 LED5 GREEN RIGHT E14 LD8 LED6 ORANGE DOWN-LEFT E12 LD9 LED7 BLUE DOWN-RIGHT E13 LD10 LED8 RED DOWN I could as well add code for the supported* onboard peripherals
*I read CAN is not supported ( or is it ? ), but I'm wondering about the 'audio' pins ..Last but not least, I wonder if there is a typo in one of the labels in the corresponding .py file ?
// https://github.com/espruino/Espruino/blob/master/boards/STM32F3DISCOVERY.py#L78 'MEMS' : { 'device' : 'LSM303DLHC)', // is the ')' at the end ok ?
This being said, hopefully @Gordon has an idea on how to fix the 'broken' USB & I'll learn the necessary to free him the time it 'd take to implement the fixes ^^ ( to find where it 'broke', the 1st thing I think about is testing firmwares from the 1V50 one up to where it no longer work & then check the diffs between their respective sources, but I don't know how much & which files are :/ )
I'll digg few more tuts on the stm32f3 to better grasp the subject before being able to investigate the troubles & also port the xbox360 controller code to it ( .. )
now onto doing few quick tests with the freshly flashed Espruino 1V50 firmware ;)
-
Hi !
Thanks for your hint, I actually didn't check the readme on https://github.com/espruino/Espruino :/ ..I'd be happy to fix things up, but I'm wondering what it'd imply & "how" is USB broken: I guess simply checking <1V8 implm & get back that code for >1V8 wouldn't work as expected ..
anyway, thanks a lot: I'll be checking quickly a build <1V8 & see I can get something working/connecting ;)
-
a quick update on "fixing stuff": it seems I can get the buttons to appear but not in a reliable manner ( I'd say if I'm fast enough plugging the usb cable ? this is weird .. ) and while code shouldn't work ?!
could this in part come from not waiting enough on init or within the main while loop ?
also, it could also come from the page I'm using for my tests ( http://html5gamepad.com/ ), but since it worked great until now, I bet the error in in my messy code ;p/* ==== main.c ==== */ // still trying .. and 'sometimes' works with "#define HID_EPIN_SIZE 0x04" in "usbd_hid.h" ?! ;D //uint8_t bufferHID[6] = {0, 0, 0, 0, 0}; uint8_t bufferHID[6] = {0, 0, 0, 0, 0, 0}; // nope ?! //uint8_t bufferHID[6] = {}; // gives 'implicit declaration ..' but works ? .. //uint8_t bufferHID[6]; bufferHID[0] = (gamepadHID.buttons & 0xFF); bufferHID[1] = ( (gamepadHID.buttons >> 8) & 0xFF); bufferHID[2] = gamepadHID.left_x; bufferHID[3] = gamepadHID.left_y; bufferHID[4] = gamepadHID.right_x; bufferHID[5] = gamepadHID.right_y; USBD_HID_SendReport(&hUsbDeviceFS, &bufferHID, sizeof(bufferHID)); //USBD_HID_SendReport(&hUsbDeviceFS, &bufferHID, sizeof(struct gamepadHID_t)); //USBD_HID_SendReport(&hUsbDeviceFS, &gamepadHID, sizeof(struct gamepadHID_t)); HAL_Delay(30);
/* ==== usbd_hid.h ==== */ [#define](https://forum.espruino.com/search/?q=%23define) HID_EPIN_SIZE 0x04 // shouldn't be enough, right ?
-
Hi there !
I'll be writing the hc-05->RN42 guide the coming week ( with screenshots ;p )
on another subject, I uncovered dust from a STM32F3DISCOVERY yesterday & this time, took enough time to experiment with CubeMX-generated & modded stuff as well as flashing the thing.
( the goal is to familiarize myself enough with the stm32 environment without messing with one of my Espruino boards ;) ).
I succefully flashed a mouse HID & a keyboard+media HID to it, but for some reason, I can't get the GamePad HID to work as intended: it's detected as such, but I still have a byte-related trouble with the buttons ( the joysticks works fine ).Thing is: I'm still wondering why the heck is doing so, since after multiple readings of the following code, I see no errors ? :|
Shouldn't it work if "sizeof(struct gamepadHID_t)" equals to "HID_EPIN_SIZE" ?/* ==== main.c ==== */ /* USER CODE BEGIN 1 */ struct gamepadHID_t { //uint16_t buttons; uint8_t buttons1; uint8_t buttons2; int8_t left_x; int8_t left_y; int8_t right_x; int8_t right_y; }; struct gamepadHID_t gamepadHID; //gamepadHID.buttons = 0b0000000000000000; gamepadHID.buttons1 = 0b00000000; gamepadHID.buttons2 = 0b00000000; gamepadHID.left_x = 0b00000000; gamepadHID.left_y = 0b00000000; gamepadHID.right_x = 0b00000000; gamepadHID.right_y = 0b00000000; /* USER CODE END 1 */ /* USER CODE BEGIN 3 */ //gamepadHID.buttons = 0x55AA; //gamepadHID.buttons = 0b0000000011111111; // works ?! //gamepadHID.buttons = 0b0000000111111111; // also works ?!! //gamepadHID.buttons = 0b0111111111111111; // also works .. //gamepadHID.buttons = 0b1111111111111111; //gamepadHID.buttons1 = 0x55; //gamepadHID.buttons2 = 0xAA; //gamepadHID.buttons1 = 0b11111111; //gamepadHID.buttons2 = 0b11111111; gamepadHID.buttons1 = 0b01111111; gamepadHID.buttons2 = 0b01111111; gamepadHID.left_x = 127; gamepadHID.left_y = 127; gamepadHID.right_x = -127; gamepadHID.right_y = -127; //USBD_HID_SendReport(&hUsbDeviceFS, &gamepadHID, sizeof(struct gamepadHID_t)); //USBD_HID_SendReport(&hUsbDeviceFS, &gamepadHID, sizeof(struct gamepadHID_t)+2); //USBD_HID_SendReport(&hUsbDeviceFS, &gamepadHID, 8); //USBD_HID_SendReport(&hUsbDeviceFS, &gamepadHID, sizeof(struct gamepadHID_t)+1); //HAL_Delay(30); //gamepadHID.buttons = 0; USBD_HID_SendReport(&hUsbDeviceFS, &gamepadHID, sizeof(struct gamepadHID_t)); //HAL_Delay(30); //unsigned char data[HID_DATA_IN_PACKET_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //unsigned char data[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //uint8_t data[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //uint8_t data[6] = { 0x00, 0x00, 127, 127, 127, 127}; // works with below T //uint8_t data[6] = { 127, 00, 127, 127, 127, 127}; // nope //USBD_HID_SendReport(data, 6); //USBD_HID_SendReport(&hUsbDeviceFS, &data, sizeof(data)); // "T" works, but 'implicit declaration' .. /* USER CODE END 3 */ /* ==== usb_hid.h ==== */ /** @defgroup USBD_HID_Exported_Defines * @{ */ [#define](https://forum.espruino.com/search/?q=%23define) HID_EPIN_ADDR 0x81 [#define](https://forum.espruino.com/search/?q=%23define) HID_EPIN_SIZE 0x06 /* max report size - for GamePad */ // ( .. ) [#define](https://forum.espruino.com/search/?q=%23define) HID_CUSTOM_REPORT_DESC_SIZE 46 /* GamePad HID report size */ /* ==== usb_hid.c ==== */ // TEF Edit: change 'bInterfaceSubClass' to 0 ( gamepad does not respect boot specifications ) // & 'nInterfaceProtocol' to 5 ( gamepad ) __ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = { // ( .. ) 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ 0x05, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse, 5=gamepad */ // ( .. ) // custom descriptor for GamePad __ALIGN_BEGIN static uint8_t HID_CUSTOM_ReportDesc[HID_CUSTOM_REPORT_DESC_SIZE] __ALIGN_END = { // 46 bytes 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x05, // USAGE (Game Pad) - Hut1_12v2.pdf p28 of 128 0xA1, 0x01, // COLLECTION (Application) 0xA1, 0x00, // COLLECTION (Physical) 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) 0x29, 0x10, // USAGE_MAXIMUM (Button 16) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x95, 0x10, // REPORT_COUNT (16) 0x75, 0x01, // REPORT_SIZE (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) 0x09, 0x32, // USAGE (Z) - Hut1_12v2.pdf p26 = represents R X-axis 0x09, 0x33, // USAGE (Rx) - Hut1_12v2.pdf p26 = represents R Y-axis 0x15, 0x81, // LOGICAL_MINIMUM (-127) 0x25, 0x7F, // LOGICAL_MAXIMUM (127) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x04, // REPORT_COUNT (4) 0x81, 0x06, // INPUT (Data,Var,Abs) - absolute for joysticks ( != rel for mouse ) 0xC0, // END_COLLECTION 0xc0 // END_COLLECTION };
Once the above is fixed, one of the next steps is porting the Xbox360 controller code to it ( and then continue digging how to use an existing controller for the handshake part .. ).
As a side note, I tried but coouldn't get Espruino on the board ?
I used the Espruino_1V92 & Espruino_1V92.3 firmwares ( it seems 1V99 isn't available on the repos for the STM32F3DISCOVERY )
( I took not of the need for unplugging & replugging the 'USB USER' plug, but no /dev/tty<..> ever appear on my mac :/ )
The cli commands I used are the following:// to flash any firmware generated from a 'make' call on CubeMX-generated files st-flash --format ihex write ./build/stm32f3discovery_hidTest1.hex // to flash Espruino firmware ? :| st-flash erase // to clean stuff st-flash write ./espruino_1v92/espruino_1v92.3_stm32f3discovery.bin 0x08000000
-
-
-
Hi there !
On the RN42 subject, some readers of this topic may found the following useful:
http://forum.espruino.com/comments/14444935/cheers ++
-
Hi there !
Indeed :)
BUT it didn't became a "magic configurable USB HID device": it now allows to specifiy via AT-like commands which HID profile to use & then pass serially the stuff related to that HID reportIn short, you'll need:
- BlueSuite_2_6_6_1311.zip
- csr-spi-ftdi-0.5.3-a5.zip // IMPORTANT ( else you could get an error looking like you may have wire shorts )
- zadig-2.4.exe
- an RN42 with HID firmware to be dumped ..
- an HC-05 from which we'll dump, mod & reflash the firmware
I'll be doing a quick writeup of my notes on the subject, but you can already follow these:
Alternative method ( using FTDI adapter instead of parallel port):
https://www.youtube.com/watch?v=y8PcNbAA6AQ
Evan Kale's Bluetooth PS2 controller mod:
https://www.youtube.com/watch?v=mt8uF9IblUU
same authors' PS2 keyboard/mouse Bluetooth adapter:
https://www.youtube.com/watch?v=UJaqHnPR-XE&feature=youtu.be
HC-05 infos:
https://components101.com/wireless/hc-05-bluetooth-module
In the attached archive, you'll find all the necessary ;p
nb: for the "Open Adaptive Controller" I'm working on ( currently using Espruino WiFi & flashed HC-05* .. and teensy for xbox360 stuff that I hope to move onto Espruino USB stuff ), I am trying to optimize the usage of the available pins & was wondering what was the best way to put a pin on "high impedance" ( floating ? ) to be able to light either 2 leds: both at same time, only former, only latter
The above goal is somewhat close to what does the "STAT" pin in the below schematic
*same for me: I guess for the final implementation of the said controller, I'll have to switch to Espruino bluetooth + wifi to be able to achieve fully custom Bluetooth HID reports ( I plan to retry the Puckjs code posted above & maybe soon purchase your latest board ;) ).
Of course, I'll be posting the blueprints here ( I am currently finishing those & 'll be moving to the 3d part soon ) ;p
last but not least, the debug code I used to interface the freshly flashed HC-05 .. and it worked ;p
ps: yes, I could have done things better the way// setting the RN42 firmware as a HID gamepad device // we connect to the hc05 module using itd breakout's Vcc,Gnd, Txd & Rxd Serial1.setup(115200, { tx:B6, rx:B7 }); Serial1.on('data', function (data) {console.log(data);}); // R: using PIO11: HIGH ? HID selected, LOW ? using profile selected in flash // ==== CMD mode ==== // wait a little bit then send '$$$' THEN SILENCE ( no line ending ) to enter command mode /* >Serial1.print('$$$'); =undefined C MD */ // then enter commands with CR line ending /* SF,1 // factory reset: //> AOK D // see current settings E // see advanced settings SM,6 // pairing //> AOK SN,OpenAdaptiveController // set name //> AOK S~,0 // SPP mode //> AOK S~,6 // HID mode //> AOK // HID report descriptors //SH,0230 // appear as keyboard+mouse combo SH,0240 // appear as a gamepad //> AOK GH // get current value of HID flag register R,1 // reboot module */ /* Current sequence used from above stuff to setup an "RN42" as a Bluetooth Gamepad: Serial1.println('SF,1'); Serial1.println('S~,6'); Serial1.println('SN,EspruinoGamepad'); Serial1.println('SH,0240'); Serial1.println('GH'); Serial1.println('R,1'); */ /* Gamepad HID report format: 1 2 3 4 0xFD,0x06,0x00,0x00,0x00,0x00,0x55,0xAA 1: Raw report decriptor 2: length, must be 6 3: joysticks states 4: buttons states bitmasks */ // Ex: //Serial1.write(0xFD,0x06,0x00,0x00,0x00,0x00,0x55,0xAA); // the following gives enough time to focus the HTML5 gamepad tester page ;) setTimeout(function(){ Serial1.write(0xFD,0x06,0x00,0x00,0x00,0x00,0x55,0xAA); },5000);
Enjoy :D
- BlueSuite_2_6_6_1311.zip
-
quick update & good news on the RN42 topic: I received the neccessary & succefully flashed an hc-05's firmware, then enabled HID gamepad, to finish by quickly testing connection to a laptop & sending gampepad states: it just "worked" ( too bad we currently don't have any way to access a less high-level API to be able to set custom HID descriptors instead of the provided ones .. )
I plan to digg the SPP||HID GPIO toggle pin stuff, why I don't have any LEDs & things on the PCM audio pins later today, additionally to updating the Gamepad.js "draft" API ;)
( & maybe flash some more hc-05 ? .. too bad software used is currently only for Windows :/ .. )So, a little teaser for now .. ;P
-
allright, I'll try to find a screen or make use of that ;)
on the i2c subject, did you have something like this in mind http://amitesh-singh.github.io/stm32/2018/01/07/making-i2c-slave-using-stm32f103.html ?
I honestly don't have enough skills to tell you if it'd work ( but a huge part of me thinks why not considering my quick & ugly arduino code worked ? )
I also wonder if it' be useful to have a callback called once data has been accessed ? ( or if it would just slow down the entire process .. )
-
back :)
I updated/completed the "roadmap" from Zack zlittell's series of posts on the subject ( http://www.zlittell.com/2015/07/msf-fightstick-teensylc-xinput-controller-8/ ).
The same author published a more-arduino-library-like version of his code, but as his writeup focuses on the former, I'll start with that & see how it goes before trying porting the latter ( which I'm already using in my Espruino<->Teensy tests )On the current "deadend" I'm facing regarding the way genuine controllers are recognized, the following posts seems of interest but I have no clues yet on how to trick/bypass this ( and this is mandatory for the controller to be used on an actual console :/ .. )
- https://brandonw.net/360bridge/doc.php
- https://oct0xor.github.io/2017/05/03/xsm3/
- https://github.com/oct0xor/xbox_security_method_3
- https://www.tapatalk.com/groups/blissbox/working-with-xbox-360-protocal-t219.html
- http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/WirelessUsbInfo
This being said, I have some RFID code to produce before getting my hands dirty on the STM32 stuff ( nb: I have a discovery board not yet tested I consider trying on instead of messing with one of my Espruino boards ;p ), so I'll come back as usual when I got things done or with more questions ;)
- https://brandonw.net/360bridge/doc.php
-
Hi there !
( btw: I just added a pull request for another example on using a PN532 to read RFID cards ;p )Thanks for the hint, but it didn't come from sending ( I do the following ):
// .. this.btnState & 0xFF, // Byte0 (this.btnState>>8) & 0xFF, // ..
It actually came from being tired & not doing the right bitwise operations ;)
the following fixed itgamepad.btnState |= this.bValue; // to set stuff gamepad.btnState &=~ this.bValue; // to unset stuff
For the STM32F stuff, I'll have to digg what you suggested & more ..
(..) xbox 360 controller is a HID controller with the HID report descriptor removed and the device class, subclass, and protocol set to 0xFF (255)
Moreover, if I read correctly, the "Xbox 360 Controller Security" is not yet broken ( while said to be reverse engineered on a per console basis ? https://oct0xor.github.io/2017/05/03/xsm3/ ), so connecting to a console instead of a pc will be a harder than expected ..
Anyway, as I'll have to port the current code, here's a "roadmap" to be applied to the Espruino/STM32F platform ( attached pdf file )
-
Sorry, I just edited the above code excerpts to better reflect what has to be tried on the RN42 setup and the puck.js setup.
I guess it'd make sense merging all the possible "interfaces" for a gamepad module & pass the chosen one as param ? ( as well as accept a higher-level helper function if needed ? )Ex: possible choices of "interfaces":
- USB HID
- EspruinoBLE HID
- RN42 HID
- Xbox360 ( XInput )
- ..
the "gamepad higher level helper" could be close to the draft I wrote for another subject on the forums ( http://forum.espruino.com/conversations/325589/ )
- USB HID
-
Hi there !
thanks ;)
It indeed seems that Arduino <-serial->Espruino is the quickest & handy path to choose
( I am currently doing so to control & get feedbacks on a Teensy 3.6 - acting as an Xbox 360 controller - from Espruino ;) )As I get enough time to do so, I'll update the reader/decoder part & start building a lib from those ( nb: it 'd require a whole lot of work additionally to the current one to get all the infos for a particular monitor, though )
As I currently don't own a Pixl.js ( I'd be more interested in a MDBT42Q breakout ;p ), I'll just pack the interesting bits & give that away in the forums ( or try building a canvas pixl.js screen emulator ? )
On the I2C & SPI slave subject, it 'd be really awesome to have, as this is one of the reason I still need to keep an Arduino closeby when messing with stuff ( on a side note, I currently face somewhat close ends as I'm trying to use a custom usb device descriptor different that a HID one ( that's why I'm using a Teensy for now to do the USB talk ;p ).
I guess I can help on neither, as I currently don't know either enough to be of any actual help implementing those on the Espruino platform :/
Hi there !
I stumbled upon this thread ( 3 years old -> cute ^^) while looking for fixes to drive the following screen correctly:
https://www.ebay.fr/itm/1-44-inch-Full-Color-128x160-SPI-TFT-LCD-Screen-Panel-replace-OLED-for-Arduino/322569266920?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649
The breakout uses an ST7735 driver, as @Jorgen's & as within the Espruino tutorial
The issues:
Many tries, but I couldn't get the above fixed without further modding the ILI9163 library ( fiddling with g.setRotation didn't fix the offset no the italic text :/ .. )
After some time trying out stuff, I successfully fixed both issues ( yay ! ^^), and I think the fixes may as well be ported to other Espruino screen libraries ( to be as "generic" as possible while not increasing the libs drastically ;) )
From the above fixes, I don't know if a 'offset: { x: , y:}' could be added to an option object that could be passed while connecting to the screen ?
This being said, I have few questions on the graphics module ( & I'd be glad to format & add the answers fetched to the graphics page ;) ):
Q1: on screen colors & update speed for a "little bigger" chip, I was wondering If I could expect a nearly instant refresh for paletted ( & non paletted as well ? ) modes on this screen & the STM32F407VGT6 ( 1024kB flash, 192kB ram). 128*128*16bpp = 32768 bytes = 33kB -> ~159kB are ram left ? ( I bet this assumption is pretty naïve, since the amount of ram available to Espruino may not match the total amount of ram available or something of the same kind I'm not aware of ? .. )
Q2: would a mode with 'non palettes zones' & other stuff 'palettes' be of any interest ?
Q3: would a mod of the 'clear()' & 'flip()' methods accepting a rectangle x1,y1,x2,y2 be of any help ( to either clear or update only part of the screen ) ? ( then we could also have 'canvases' & do stuff like g.cnvs[0].clear(), .draw.. & maybe have x&y coords shifted by the top-left of such canvases - that may be rotated as well ? ;) )
Q4: could 'dynamic italic text' be come a feature ? ( I'll add visuals from my tests to better illustrate this 'glitch-not-yet-a-feature' ;p )
Q5: could an alternative behavior for the 'palettes' mode be handy ? ( if color is outa bounds, fallback to either black or white depending on a param passed or settings )
Q6: best way to get 'instant drawing' for a (colored or not but likely ) logo ? I tried using setPixel() & timing the time taken to draw the entire screen with sort of a gradient ( see hacks in code below ), then just using fillPoly() & while the latter seems way more promising than loading setting every pixel, getting it into the right colors quickly drawn from an array is I think possible, yet I'm not sure yet how to achieve that ( by using E.mapInPlace() & Cie ? - I also wonder how loading an image is done - and I failed but 'll retry to getting the Espruino logo example loading as an image ;) )
I currently have two possible scenarios of how to get that colored logo draw quickly ( 'll presumably happen on device boot or reboot - and may be used as a "background" while a loading bar is updated at the bottom - not sure how of much time a 'clearToBackground()' fcn would take ;p .. )
A:
B:
drawing to screen directly being slower than to memory then in-one-row to screen, I'm wondering how drawing from obj ( from an already painted in ArrayBuffer saved in flash ? ) to screen would preform ( I guess it'll take more time for more colors ) & how to minimize the ram used to do so ( if I get correctly the current paletted code, it send rows by rows what I'd like to load & send row-by-row ( to lessen ram used ), but I'm not sure how 'fillPoly()' is implemented & whether or not I may be able to just draw its points & then use 'ce.set' once all are drawn
Also, I'm quite curious if saving then loading an array buffer to only the part of screen needed would be fast enough ..
I'll try some stuff out & then post an update ;)
here some hacks for the adventurous readers ;p