Custom Serial bit / parity with Spark Core (e.g. SERIAL_8N2)

Hey folks!

I’m trying to interface my Spark Core with a medical device that puts out serial data in ASCII format @ 9600 baud, 1 start bit, 2 stop bits, 8 data bits (e.g. SERIAL_8N2 if I was using an Arduino). It looks like the core is hard-coded to use 1 stop bit (hence the junk data I’m getting when trying to capture serial data after passing the RS-232 signal through a logic level shifter).

It looks like there are plans to enable these custom bit/parity configurations, they’re just not implemented yet in firmware/src/spark_wiring_usartserial.cpp

// TODO
void USARTSerial::begin(unsigned long baud, byte config)
{

}

Can anyone provide any guidance on how to go about adding SERIAL_8N2 (and other bit/parity configurations) on the core? Can I make these changes using the web IDE or do I need to download the firmware and make the changes / flash those changes using DFU-util?

Thanks much!

@jmekler, in order to pass the configuration parameters to the USART, you would need to modify the HAL begin() code. That would mean parsing the “config” byte to then set the USART_InitStructure correctly. None of this can be done on the web IDE so you will have to install the toolchain and pull in the HAL branch. If you get things working, you could put in a pull request with your changes :wink:

@peekay123 I took a cut at modifying the firmware, building, and flashing to the core. I haven’t had a chance to test whether the USART is working yet, but will plan to give it a go as soon as I can get my hands the device I’m working with (sometime later this week).

I forked the spark/firmware repo, and you can take a look at the commit with changes here: https://github.com/jmekler/firmware/commit/926a5899e93c59c130210531b763091842aee06c. Happy to field your thoughts on any changes (coding style, bugs, etc)?

The current commit exposes most of the STM32’s USART functionality (e.g. everything except disabling RX/TX), and the USART configuration can be specified from a predefined configuration (e.g. Serial1.begin(9600, SERIAL_8N2);) or by combining different configuration flags (e.g. Serial1.begin(9600, FLOW_NONE | WL_8 | PAR_NONE | SB_1);). It might make sense to provide the most common configurations and allow users to access the configuration flags for less common configurations (e.g. 9N1.5).

Thanks again for the guidance.

@jmekler, just some quick feedback. Hardware flow control on the STM32 requires specific GPIO pins. Those pins are not currently mapped onto physical pins of the Core, explaining why HW flow control is not implemented. Also, if you are defining 9-bit operation, then the ISR , all buffers and supporting code will need to change since they are currently setup for 8-bit operation.

In my own experience I have only seen 7-bit and 8-bit configurations with variations on parity (none, odd, even) and stop bits (1 or 2). The STM32 does not support 7-bit operation so that leaves 8-bit as most common. My recommendation is to support variations of the 8-bit protocol only, keeping the base code compatible with Arduino. :smile:

@peekay123 thanks for the feedback.

I realized I wasn’t working on the HAL branch, so I switched over an implemented the code on that branch. Hopefully I put things in the right places… Here’s the diff from the spark/feature/hal branch and summary of changes:

https://github.com/spark/firmware/compare/feature/hal...jmekler:feature/hal

wiring/src/spark_wiring_usartserial.h

  • Included define statements here for all of the serial configurations
    supported by arduino (5-8 data bits, none/even/odd parity, and 1/2
    stop bits).
  • Even though the STM32 only supports the 8 data bit configurations,
    I included them all in case some future chip supports
    other serial modes.

wiring/src/spark_wiring_usartserial.cpp

  • Basic refactor to call HAL_USART_Begin from the
    USARTSerial::begin(baud, config) instead of begin(baud). Defaults
    the simpler implementation to SERIAL_8N1

hal/inc/usart_hal.h

  • Updated the HAL_USART_Begin(HAL_USART_Serial serial, uint32_t baud, uint8_t config); to require a configuration byte.

hal/src/core-v1/usart_hal.c

  • Added a macro to see whether the specified configuration is valid for the STM32 architecture
  • If the configuration is invalid, sets the usart_enabled flag to false
  • Should we include checks on this flag in all of the other HAL_USART functions (e.g. read/write)?
  • Configured USART_InitStructure based on passed in config value

Built and tested on Serial1 with SERIAL_8N1 configuration sending data to an Arduino Nano (no TX test because I didn’t feel like setting up logic level shifters to convert from 5V to 3V3)

On second thought, it might make more sense to put the SERIAL_XXX definitions in a conditional macro so that the compiler throws an error if someone tries to use an invalid configuration (e.g. SERIAL_5N1 on the Core).

Something like this:

// Enable serial configurations for Spark Core (PLATFORM_ID: 0)
#if defined(PLATFORM_ID) && (PLATFORM_ID == 0)
#define SERIAL_8N1 0b00110000
#define SERIAL_8N2 0b00110001
#define SERIAL_8E1 0b00110100
#define SERIAL_8E2 0b00110101
#define SERIAL_8O1 0b00111000
#define SERIAL_8O2 0b00111001
#endif

@jmekler, nice work! I agree with the SERIAL_XXX conditional macro since the full list can be misconstrued as being supported by all platforms. You may want to put default cases in your switch statements as an extra precaution OR have PLATFORM_ID specific IS_USART_CONFIG_VALID macros.

Also, after looking at the pin mapping on the Core (not sure about Photon yet), hardware CTS and RTS lines are brought out at the expense of using a GPIO line. Not sure if this is really necessary to support. :grinning:

1 Like

Just want to say that I am eager to see this enhancement (i.e. support of parity) as I need it to communicate with a heat pump! Great to see someone is working on it already. I was afraid I had much more work ahead of me!

@jmekler

Any chance that mark and space parity can be defined ? Need to communicate to a device as per this post

TIA
Ian

@iwalker, good question though it will require some reading of the STM32F205 reference docs.

Hi all,

Thx for working on this. I need to use serial communication to 8 bits, even parity, 1 stop bit. Is there any easy way how to change default no parity to even parity?

thx a lot
mirek

Hi guys! I also need to use something like SERIAL_9N1 in arduino…
How can I do? is it possible? Thanks a lot,
Flavio

Hi,

Before I dig into the STM reference docs has anyone managed to work out a way to enable 9N1?

Cheers
Michael

Look here
https://github.com/spark/firmware/pull/757

This is part of v0.5.0-rc.1 which is ready for beta testing
Particle Firmware Updates Thread

Hi.

Thanks I missed your reply - I will work through the github link you sent

Cheers
Michael

Hi all,

thx a lot. It works fine with SERIAL_8E1 at 0.50_rc2. I can continue in my project.

Thank you again
mirek