|
- // ArduinoCompat/HardwareSerial.cpp
- //
- // Author: mikem@airspayce.com
-
- #include <RadioHead.h>
- #if (RH_PLATFORM == RH_PLATFORM_STM32STD)
- #include <HardwareSerial.h>
- #include <stm32f4xx_usart.h>
-
- // Preinstantiated Serial objects
- HardwareSerial Serial1(USART1);
- HardwareSerial Serial2(USART2);
- HardwareSerial Serial3(USART3);
- HardwareSerial Serial4(UART4);
- HardwareSerial Serial5(UART5);
- HardwareSerial Serial6(USART6);
-
- ///////////////////////////////////////////////////////////////
- // RingBuffer
- ///////////////////////////////////////////////////////////////
-
- RingBuffer::RingBuffer()
- : _head(0),
- _tail(0),
- _overruns(0),
- _underruns(0)
- {
- }
-
- bool RingBuffer::isEmpty()
- {
- return _head == _tail;
- }
-
- bool RingBuffer::isFull()
- {
- return ((_head + 1) % ARDUINO_RINGBUFFER_SIZE) == _tail;
- }
-
- bool RingBuffer::write(uint8_t ch)
- {
- if (isFull())
- {
- _overruns++;
- return false;
- }
- _buffer[_head] = ch;
- if (++_head >= ARDUINO_RINGBUFFER_SIZE)
- _head = 0;
- return true;
- }
-
- uint8_t RingBuffer::read()
- {
- if (isEmpty())
- {
- _underruns++;
- return 0; // What else can we do?
- }
- uint8_t ret = _buffer[_tail];
- if (++_tail >= ARDUINO_RINGBUFFER_SIZE)
- _tail = 0;
- return ret;
- }
-
- ///////////////////////////////////////////////////////////////
- // HardwareSerial
- ///////////////////////////////////////////////////////////////
-
- // On STM32F4 Discovery, USART 1 is not very useful conflicts with the Green lED
- HardwareSerial::HardwareSerial(USART_TypeDef* usart)
- : _usart(usart)
- {
- }
-
- void HardwareSerial::begin(unsigned long baud)
- {
- USART_InitTypeDef USART_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure_TX;
- GPIO_InitTypeDef GPIO_InitStructure_RX;
-
- // Common GPIO structure init:
- GPIO_InitStructure_TX.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure_TX.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure_TX.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure_TX.GPIO_PuPd = GPIO_PuPd_UP;
-
- GPIO_InitStructure_RX.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure_RX.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure_RX.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure_RX.GPIO_PuPd = GPIO_PuPd_UP;
- // CTS or SCLK outputs are not supported.
-
- USART_InitStructure.USART_BaudRate = baud * 25/8; // Why?
- // Only 8N1 is currently supported
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
-
- // Different for each USART:
- if (_usart == USART1)
- {
- // Initialise the clocks for this USART and its RX, TX pins port
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
-
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
-
- GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_10;
- GPIO_Init(GPIOA, &GPIO_InitStructure_TX);
- GPIO_Init(GPIOA, &GPIO_InitStructure_RX);
- // Initialise the USART
- USART_Init(USART1, &USART_InitStructure);
- // Enable the RXNE interrupt
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
- // Enable global interrupt
- NVIC_EnableIRQ(USART1_IRQn);
- }
- else if (_usart == USART2)
- {
- // Initialise the clocks for this USART and its RX, TX pins port
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
-
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
-
- GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_3;
- GPIO_Init(GPIOA, &GPIO_InitStructure_TX);
- GPIO_Init(GPIOA, &GPIO_InitStructure_RX);
- // Initialise the USART
- USART_Init(USART2, &USART_InitStructure);
- // Enable the RXNE interrupt
- USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
- // Enable global interrupt
- NVIC_EnableIRQ(USART2_IRQn);
- }
- else if (_usart == USART3)
- {
- // Initialise the clocks for this USART and its RX, TX pins port
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
-
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);
-
- GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_8;
- GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_9;
- GPIO_Init(GPIOD, &GPIO_InitStructure_TX);
- GPIO_Init(GPIOD, &GPIO_InitStructure_RX);
- // Initialise the USART
- USART_Init(USART3, &USART_InitStructure);
- // Enable the RXNE interrupt
- USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
- // Enable global interrupt
- NVIC_EnableIRQ(USART3_IRQn);
- }
- else if (_usart == UART4)
- {
- // Initialise the clocks for this USART and its RX, TX pins port
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
-
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_UART4);
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_UART4);
-
- GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_1;
- GPIO_Init(GPIOA, &GPIO_InitStructure_TX);
- GPIO_Init(GPIOA, &GPIO_InitStructure_RX);
- // Initialise the USART
- USART_Init(UART4, &USART_InitStructure);
- // Enable the RXNE interrupt
- USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
- // Enable global interrupt
- NVIC_EnableIRQ(UART4_IRQn);
- }
- else if (_usart == UART5)
- {
- // Initialise the clocks for this USART and its RX, TX pins port
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);
-
- GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
-
- GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_12;
- GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_2;
- GPIO_Init(GPIOC, &GPIO_InitStructure_TX);
- GPIO_Init(GPIOD, &GPIO_InitStructure_RX);
- // Initialise the USART
- USART_Init(UART5, &USART_InitStructure);
- // Enable the RXNE interrupt
- USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
- // Enable global interrupt
- NVIC_EnableIRQ(UART5_IRQn);
- }
- else if (_usart == USART6)
- {
- // Initialise the clocks for this USART and its RX, TX pins port
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
-
- GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
- GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);
-
- GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_7;
- GPIO_Init(GPIOC, &GPIO_InitStructure_TX);
- GPIO_Init(GPIOC, &GPIO_InitStructure_RX);
- // Initialise the USART
- USART_Init(USART6, &USART_InitStructure);
- // Enable the RXNE interrupt
- USART_ITConfig(USART6, USART_IT_RXNE, ENABLE);
- // Enable global interrupt
- NVIC_EnableIRQ(USART6_IRQn);
- }
-
- USART_Cmd(_usart, ENABLE);
- }
-
- void HardwareSerial::end()
- {
- USART_Cmd(_usart, DISABLE);
- USART_DeInit(_usart);
- }
-
- int HardwareSerial::available(void)
- {
- return !_rxRingBuffer.isEmpty();
- }
-
- int HardwareSerial::read(void)
- {
- return _rxRingBuffer.read();
- }
-
- size_t HardwareSerial::write(uint8_t ch)
- {
- _txRingBuffer.write(ch); // Queue it
- USART_ITConfig(_usart, USART_IT_TXE, ENABLE); // Enable the TX interrupt
- return 1;
- }
-
- extern "C"
- {
- void USART1_IRQHandler(void)
- {
- if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
- {
- Serial1._rxRingBuffer.write(USART_ReceiveData(USART1));
- }
- if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
- {
- // Transmitter is empty, maybe send another char?
- if (Serial1._txRingBuffer.isEmpty())
- USART_ITConfig(USART1, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
- else
- USART_SendData(USART1, Serial1._txRingBuffer.read());
- }
- }
- void USART2_IRQHandler(void)
- {
- if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
- {
- // Newly received char, try to put it in our rx buffer
- Serial2._rxRingBuffer.write(USART_ReceiveData(USART2));
- }
- if (USART_GetITStatus(USART2, USART_IT_TXE) != RESET)
- {
- // Transmitter is empty, maybe send another char?
- if (Serial2._txRingBuffer.isEmpty())
- USART_ITConfig(USART2, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
- else
- USART_SendData(USART2, Serial2._txRingBuffer.read());
- }
- }
- void USART3_IRQHandler(void)
- {
- if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
- {
- // Newly received char, try to put it in our rx buffer
- Serial3._rxRingBuffer.write(USART_ReceiveData(USART3));
- }
- if (USART_GetITStatus(USART3, USART_IT_TXE) != RESET)
- {
- // Transmitter is empty, maybe send another char?
- if (Serial3._txRingBuffer.isEmpty())
- USART_ITConfig(USART3, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
- else
- USART_SendData(USART3, Serial3._txRingBuffer.read());
- }
- }
- void UART4_IRQHandler(void)
- {
- if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
- {
- // Newly received char, try to put it in our rx buffer
- Serial4._rxRingBuffer.write(USART_ReceiveData(UART4));
- }
- if (USART_GetITStatus(UART4, USART_IT_TXE) != RESET)
- {
- // Transmitter is empty, maybe send another char?
- if (Serial4._txRingBuffer.isEmpty())
- USART_ITConfig(UART4, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
- else
- USART_SendData(UART4, Serial4._txRingBuffer.read());
- }
- }
- void UART5_IRQHandler(void)
- {
- if (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
- {
- // Newly received char, try to put it in our rx buffer
- Serial5._rxRingBuffer.write(USART_ReceiveData(UART5));
- }
- if (USART_GetITStatus(UART5, USART_IT_TXE) != RESET)
- {
- // Transmitter is empty, maybe send another char?
- if (Serial5._txRingBuffer.isEmpty())
- USART_ITConfig(UART5, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
- else
- USART_SendData(UART5, Serial5._txRingBuffer.read());
- }
- }
- void USART6_IRQHandler(void)
- {
- if (USART_GetITStatus(USART6, USART_IT_RXNE) != RESET)
- {
- // Newly received char, try to put it in our rx buffer
- Serial6._rxRingBuffer.write(USART_ReceiveData(USART6));
- }
- if (USART_GetITStatus(USART6, USART_IT_TXE) != RESET)
- {
- // Transmitter is empty, maybe send another char?
- if (Serial6._txRingBuffer.isEmpty())
- USART_ITConfig(USART6, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
- else
- USART_SendData(USART6, Serial6._txRingBuffer.read());
- }
- }
- }
-
- #endif
|