diff --git a/ports/stm32f4xx/Makefile b/ports/stm32f4xx/Makefile index d046c200..816c1f74 100644 --- a/ports/stm32f4xx/Makefile +++ b/ports/stm32f4xx/Makefile @@ -153,6 +153,15 @@ BACNET_FLAGS += -DMAX_OCTET_STRING_BYTES=64 # if called from root Makefile, PRINT was already defined BACNET_FLAGS += -UPRINT_ENABLED BACNET_FLAGS += -DPRINT_ENABLED=0 +ifeq (${SHIELD},) +BACNET_FLAGS += -DRS485_DFR0259_ENABLED=1 +endif +ifeq (${SHIELD},dfr0259) +BACNET_FLAGS += -DRS485_DFR0259_ENABLED=1 +endif +ifeq (${SHIELD},linksprite) +BACNET_FLAGS += -DRS485_LINKSPRITE_ENABLED=1 +endif ifeq (${LEGACY},true) # disable deprecated function warnings for legacy builds BACNET_FLAGS += -DBACNET_STACK_DEPRECATED_DISABLE diff --git a/ports/stm32f4xx/rs485.c b/ports/stm32f4xx/rs485.c index 130d7505..d1fb192b 100644 --- a/ports/stm32f4xx/rs485.c +++ b/ports/stm32f4xx/rs485.c @@ -37,6 +37,39 @@ #include "bacnet/datalink/mstpdef.h" #include "rs485.h" +#ifndef RS485_LINKSPRITE_ENABLED + #ifndef RS485_DFR0259_ENABLED + #define RS485_DFR0259_ENABLED 1 + #endif +#endif + +#if defined(RS485_DFR0259_ENABLED) || defined(RS485_LINKSPRITE_ENABLED) + /* DFR0259 RS485 Shield - TXD=PG14, RXD=PG9, USART6 */ + #define RS485_USARTx USART6 + #define RS485_NVIC_IRQ USART6_IRQn + #define RS485_USARTx_ISR USART6_IRQHandler + #define RS485_USARTx_RCC RCC_APB2Periph_USART6 + #define RS485_GPIO_RCC RCC_AHB1Periph_GPIOG + #define RS485_GPIO_PINS GPIO_Pin_9 | GPIO_Pin_14 + #define RS485_GPIO GPIOG + /* alternate function (AF) */ + #define RS485_AF_PINSOURCE_RX GPIO_PinSource9 + #define RS485_AF_PINSOURCE_TX GPIO_PinSource14 + #define RS485_AF_FUNCTION GPIO_AF_USART6 +#endif +#if defined(RS485_DFR0259_ENABLED) + /* DFR0259 RS485 Shield - CE=PF15 */ + #define RS485_RTS_RCC RCC_AHB1Periph_GPIOF + #define RS485_RTS_PIN GPIO_Pin_15 + #define RS485_RTS_GPIO GPIOF +#endif +#if defined(RS485_LINKSPRITE_ENABLED) + /* LINKSPRITE RS485 Shield - CE=PD15 */ + #define RS485_RTS_RCC RCC_AHB1Periph_GPIOD + #define RS485_RTS_PIN GPIO_Pin_15 + #define RS485_RTS_GPIO GPIOD +#endif + /* buffer for storing received bytes - size must be power of two */ /* BACnet DLMSTP_MPDU_MAX for MS/TP is 1501 bytes */ static uint8_t Receive_Queue_Data[NEXT_POWER_OF_2(DLMSTP_MPDU_MAX)]; @@ -88,55 +121,55 @@ bool rs485_receive_error(void) /** * @brief USARTx interrupt handler sub-routine */ -void USART6_IRQHandler(void) +void RS485_USARTx_ISR(void) { uint8_t data_byte; - if (USART_GetITStatus(USART6, USART_IT_RXNE) != RESET) { + if (USART_GetITStatus(RS485_USARTx, USART_IT_RXNE) != RESET) { /* Read one byte from the receive data register */ - data_byte = USART_ReceiveData(USART6); + data_byte = USART_ReceiveData(RS485_USARTx); if (!Transmitting) { FIFO_Put(&Receive_Queue, data_byte); RS485_Receive_Bytes++; } - USART_ClearITPendingBit(USART6, USART_IT_RXNE); + USART_ClearITPendingBit(RS485_USARTx, USART_IT_RXNE); } - if (USART_GetITStatus(USART6, USART_IT_TXE) != RESET) { + if (USART_GetITStatus(RS485_USARTx, USART_IT_TXE) != RESET) { if (FIFO_Count(&Transmit_Queue)) { - USART_SendData(USART6, FIFO_Get(&Transmit_Queue)); + USART_SendData(RS485_USARTx, FIFO_Get(&Transmit_Queue)); RS485_Transmit_Bytes += 1; rs485_silence_reset(); } else { /* disable the USART to generate interrupts on TX empty */ - USART_ITConfig(USART6, USART_IT_TXE, DISABLE); + USART_ITConfig(RS485_USARTx, USART_IT_TXE, DISABLE); /* enable the USART to generate interrupts on TX complete */ - USART_ITConfig(USART6, USART_IT_TC, ENABLE); + USART_ITConfig(RS485_USARTx, USART_IT_TC, ENABLE); } - USART_ClearITPendingBit(USART6, USART_IT_TXE); + USART_ClearITPendingBit(RS485_USARTx, USART_IT_TXE); } - if (USART_GetITStatus(USART6, USART_IT_TC) != RESET) { + if (USART_GetITStatus(RS485_USARTx, USART_IT_TC) != RESET) { rs485_rts_enable(false); /* disable the USART to generate interrupts on TX complete */ - USART_ITConfig(USART6, USART_IT_TC, DISABLE); + USART_ITConfig(RS485_USARTx, USART_IT_TC, DISABLE); /* enable the USART to generate interrupts on RX not empty */ - USART_ITConfig(USART6, USART_IT_RXNE, ENABLE); - USART_ClearITPendingBit(USART6, USART_IT_TC); + USART_ITConfig(RS485_USARTx, USART_IT_RXNE, ENABLE); + USART_ClearITPendingBit(RS485_USARTx, USART_IT_TC); } /* check for errors and clear them */ - if (USART_GetFlagStatus(USART6, USART_FLAG_ORE) == SET) { + if (USART_GetFlagStatus(RS485_USARTx, USART_FLAG_ORE) == SET) { /* note: enabling RXNE interrupt also enables the ORE interrupt! */ /* dummy read to clear error state */ - data_byte = USART_ReceiveData(USART6); - USART_ClearFlag(USART6, USART_FLAG_ORE); + data_byte = USART_ReceiveData(RS485_USARTx); + USART_ClearFlag(RS485_USARTx, USART_FLAG_ORE); } - if (USART_GetFlagStatus(USART6, USART_FLAG_NE) == SET) { - USART_ClearFlag(USART6, USART_FLAG_NE); + if (USART_GetFlagStatus(RS485_USARTx, USART_FLAG_NE) == SET) { + USART_ClearFlag(RS485_USARTx, USART_FLAG_NE); } - if (USART_GetFlagStatus(USART6, USART_FLAG_FE) == SET) { - USART_ClearFlag(USART6, USART_FLAG_FE); + if (USART_GetFlagStatus(RS485_USARTx, USART_FLAG_FE) == SET) { + USART_ClearFlag(RS485_USARTx, USART_FLAG_FE); } - if (USART_GetFlagStatus(USART6, USART_FLAG_PE) == SET) { - USART_ClearFlag(USART6, USART_FLAG_PE); + if (USART_GetFlagStatus(RS485_USARTx, USART_FLAG_PE) == SET) { + USART_ClearFlag(RS485_USARTx, USART_FLAG_PE); } } @@ -148,9 +181,9 @@ void rs485_rts_enable(bool enable) { Transmitting = enable; if (Transmitting) { - GPIO_WriteBit(GPIOF, GPIO_Pin_15, Bit_SET); + GPIO_WriteBit(RS485_RTS_GPIO, RS485_RTS_PIN, Bit_SET); } else { - GPIO_WriteBit(GPIOF, GPIO_Pin_15, Bit_RESET); + GPIO_WriteBit(RS485_RTS_GPIO, RS485_RTS_PIN, Bit_RESET); } } @@ -197,9 +230,9 @@ void rs485_bytes_send(uint8_t *buffer, uint16_t nbytes) rs485_silence_reset(); rs485_rts_enable(true); /* disable the USART to generate interrupts on RX not empty */ - USART_ITConfig(USART6, USART_IT_RXNE, DISABLE); + USART_ITConfig(RS485_USARTx, USART_IT_RXNE, DISABLE); /* enable the USART to generate interrupts on TX empty */ - USART_ITConfig(USART6, USART_IT_TXE, ENABLE); + USART_ITConfig(RS485_USARTx, USART_IT_TXE, ENABLE); /* TXE interrupt will load the first byte */ } } @@ -220,7 +253,7 @@ static void rs485_baud_rate_configure(void) USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* Configure USARTx */ - USART_Init(USART6, &USART_InitStructure); + USART_Init(RS485_USARTx, &USART_InitStructure); } /** @@ -291,16 +324,14 @@ void rs485_init(void) FIFO_Init(&Transmit_Queue, &Transmit_Queue_Data[0], (unsigned)sizeof(Transmit_Queue_Data)); - /* DFR0259 RS485 Shield - TXD=PG14, RXD=PG9, USART6 */ /* Enable GPIOx clock */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); + RCC_AHB1PeriphClockCmd(RS485_GPIO_RCC, ENABLE); /* Enable USARTx Clock */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); + RCC_APB2PeriphClockCmd(RS485_USARTx_RCC, ENABLE); /* Configure USARTx Rx and Tx pins for Alternate Function (AF) */ - /* DFR0259 RS485 Shield - TXD=PG14, RXD=PG9 */ GPIO_StructInit(&GPIO_InitStructure); - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_14; + GPIO_InitStructure.GPIO_Pin = RS485_GPIO_PINS; /* GPIO_Speed_2MHz/GPIO_Speed_25MHz/GPIO_Speed_50MHz/GPIO_Speed_100MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* GPIO_Mode_IN/GPIO_Mode_OUT/GPIO_Mode_AF/GPIO_Mode_AN */ @@ -309,36 +340,36 @@ void rs485_init(void) GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* GPIO_PuPd_NOPULL, GPIO_PuPd_UP, GPIO_PuPd_DOWN */ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(GPIOG, &GPIO_InitStructure); + GPIO_Init(RS485_GPIO, &GPIO_InitStructure); /* alternate function (AF) */ - GPIO_PinAFConfig(GPIOG, GPIO_PinSource9, GPIO_AF_USART6); - GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_USART6); + GPIO_PinAFConfig(RS485_GPIO, RS485_AF_PINSOURCE_RX, RS485_AF_FUNCTION); + GPIO_PinAFConfig(RS485_GPIO, RS485_AF_PINSOURCE_TX, RS485_AF_FUNCTION); /* DFR0259 RS485 Shield - CE=PF15 */ /* Enable GPIOx clock */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); + RCC_AHB1PeriphClockCmd(RS485_RTS_RCC, ENABLE); /* Configure the Request To Send (RTS) aka Transmit Enable pin */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; + GPIO_InitStructure.GPIO_Pin = RS485_RTS_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOF, &GPIO_InitStructure); + GPIO_Init(RS485_RTS_GPIO, &GPIO_InitStructure); /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /* Enable the USARTx Interrupt */ - NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; + NVIC_InitStructure.NVIC_IRQChannel = RS485_NVIC_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* enable the USART to generate interrupts on RX */ - USART_ITConfig(USART6, USART_IT_RXNE, ENABLE); + USART_ITConfig(RS485_USARTx, USART_IT_RXNE, ENABLE); rs485_baud_rate_set(Baud_Rate); - USART_Cmd(USART6, ENABLE); + USART_Cmd(RS485_USARTx, ENABLE); rs485_silence_reset(); } diff --git a/ports/stm32f4xx/st_nucleo_f429.cfg b/ports/stm32f4xx/st_nucleo_f429.cfg new file mode 100644 index 00000000..0ae41020 --- /dev/null +++ b/ports/stm32f4xx/st_nucleo_f429.cfg @@ -0,0 +1,14 @@ +# This is for all ST NUCLEO with any STM32F429. Known boards at the moment: +# NUCLEO-F429ZI +# http://www.st.com/en/evaluation-tools/nucleo-f429zi.html + +source [find interface/stlink-v2-1.cfg] + +transport select hla_swd + +# increase working area to 128KB +set WORKAREASIZE 0x20000 + +source [find target/stm32f4x.cfg] + +reset_config srst_only