-
Notifications
You must be signed in to change notification settings - Fork 72
Core api update interrupt #343
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
8499aa7
59f347b
83895b3
66d5f7e
eb65b85
5fdc74a
79a1e99
f39bc19
03f2668
ca9062d
e3daa78
f11dfa0
ed08fd9
46bd28c
6852bae
03eb83d
4343d53
654f138
f004b37
7da4d7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
/* | ||
Copyright (c) 2011 Arduino. All right reserved. | ||
|
||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
|
||
This library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
See the GNU Lesser General Public License for more details. | ||
|
||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; if not, write to the Free Software | ||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
//**************************************************************************** | ||
// @Project Includes | ||
//**************************************************************************** | ||
#include "Uart.h" | ||
#include "Arduino.h" | ||
|
||
//**************************************************************************** | ||
// @Local Functions | ||
//**************************************************************************** | ||
|
||
// Constructors //////////////////////////////////////////////////////////////// | ||
|
||
Uart::Uart(XMC_UART_t *xmc_uart_config, RingBuffer *rx_buffer) { | ||
_XMC_UART_config = xmc_uart_config; | ||
_rx_buffer = rx_buffer; | ||
} | ||
|
||
// Public Methods ////////////////////////////////////////////////////////////// | ||
|
||
void Uart::begin(unsigned long baud) { begin(baud, SERIAL_8N1); } | ||
|
||
void Uart::begin(unsigned long baud, unsigned short config) { | ||
begin(baud, static_cast<XMC_UART_MODE_t>(config)); | ||
} | ||
|
||
void Uart::begin(unsigned long baud, XMC_UART_MODE_t config) { | ||
XMC_UART_CH_CONFIG_t uart_ch_config; | ||
uart_ch_config.oversampling = 0; // Must be 0 or valid oversample for baud rate calculations | ||
uart_ch_config.baudrate = baud; | ||
uart_ch_config.data_bits = (uint8_t)(config & 0x00fU); | ||
uart_ch_config.frame_length = uart_ch_config.data_bits; // Set same as data bits length | ||
uart_ch_config.parity_mode = (XMC_USIC_CH_PARITY_MODE_t)(config & ~0xffU); | ||
uart_ch_config.stop_bits = (uint8_t)((config & 0x0f0U) >> 4); | ||
|
||
XMC_UART_CH_Init(_XMC_UART_config->channel, &uart_ch_config); | ||
|
||
// dx0 is UART RX: source must be set | ||
XMC_USIC_CH_SetInputSource(_XMC_UART_config->channel, XMC_USIC_CH_INPUT_DX0, | ||
_XMC_UART_config->input_source_dx0); | ||
|
||
// Additional input multiplexing | ||
// Check if dx1 is used | ||
if (_XMC_UART_config->input_source_dx1 != XMC_INPUT_INVALID) | ||
XMC_USIC_CH_SetInputSource(_XMC_UART_config->channel, XMC_USIC_CH_INPUT_DX1, | ||
_XMC_UART_config->input_source_dx1); | ||
|
||
// Check if dx2 is used | ||
if (_XMC_UART_config->input_source_dx2 != XMC_INPUT_INVALID) | ||
XMC_USIC_CH_SetInputSource(_XMC_UART_config->channel, XMC_USIC_CH_INPUT_DX2, | ||
_XMC_UART_config->input_source_dx2); | ||
|
||
// Check if dx3 is used | ||
if (_XMC_UART_config->input_source_dx3 != XMC_INPUT_INVALID) | ||
XMC_USIC_CH_SetInputSource(_XMC_UART_config->channel, XMC_USIC_CH_INPUT_DX3, | ||
_XMC_UART_config->input_source_dx3); | ||
|
||
XMC_UART_CH_EnableEvent(_XMC_UART_config->channel, XMC_UART_CH_EVENT_ALTERNATIVE_RECEIVE | | ||
XMC_UART_CH_EVENT_STANDARD_RECEIVE); | ||
XMC_USIC_CH_SetInterruptNodePointer(_XMC_UART_config->channel, | ||
XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE, | ||
_XMC_UART_config->irq_service_request); | ||
XMC_USIC_CH_SetInterruptNodePointer(_XMC_UART_config->channel, | ||
XMC_USIC_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE, | ||
_XMC_UART_config->irq_service_request); | ||
XMC_USIC_CH_SetInterruptNodePointer(_XMC_UART_config->channel, | ||
XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER, | ||
_XMC_UART_config->irq_service_request); | ||
NVIC_SetPriority(_XMC_UART_config->irq_num, 3); | ||
NVIC_EnableIRQ(_XMC_UART_config->irq_num); | ||
|
||
XMC_UART_CH_Start(_XMC_UART_config->channel); | ||
|
||
// TX pin setup put here to avoid startup corrupted characters being first sent | ||
XMC_GPIO_Init(_XMC_UART_config->tx.port, _XMC_UART_config->tx.pin, | ||
&(_XMC_UART_config->tx_config)); | ||
|
||
XMC_GPIO_Init(_XMC_UART_config->rx.port, _XMC_UART_config->rx.pin, | ||
&(_XMC_UART_config->rx_config)); | ||
} | ||
|
||
void Uart::end(void) { | ||
// Wait for any outstanding data to be sent | ||
flush(); | ||
// Disable UART interrupt in NVIC | ||
NVIC_DisableIRQ(_XMC_UART_config->irq_num); | ||
// Clear any received data after stopping interrupts | ||
_rx_buffer->clear(); | ||
} | ||
|
||
void Uart::setInterruptPriority(uint32_t priority) { | ||
NVIC_SetPriority(_XMC_UART_config->irq_num, priority & 0x03); | ||
} | ||
|
||
uint32_t Uart::getInterruptPriority() { return NVIC_GetPriority(_XMC_UART_config->irq_num); } | ||
|
||
int Uart::available(void) { return _rx_buffer->available(); } | ||
|
||
int Uart::availableForWrite(void) { | ||
return 1; | ||
} // TODO: there are no tx buffer so we awaly have 1 byte available | ||
|
||
int Uart::peek(void) { return _rx_buffer->peek(); } | ||
|
||
int Uart::read(void) { return _rx_buffer->read_char(); } | ||
|
||
void Uart::flush(void) { | ||
while (XMC_USIC_CH_GetTransmitBufferStatus(_XMC_UART_config->channel) == | ||
XMC_USIC_CH_TBUF_STATUS_BUSY) { | ||
}; | ||
} | ||
|
||
size_t Uart::write(const uint8_t uc_data) { | ||
// For sending, write immediately | ||
// This API already have a check for available buffer | ||
XMC_UART_CH_Transmit(_XMC_UART_config->channel, uc_data); | ||
return 1; | ||
} | ||
|
||
void Uart::IrqHandler(void) { | ||
// Receive data Interrupt handler | ||
uint32_t status = XMC_UART_CH_GetStatusFlag(_XMC_UART_config->channel); | ||
|
||
// Did we receive data? | ||
if ((status & (XMC_UART_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION | | ||
XMC_UART_CH_STATUS_FLAG_RECEIVE_INDICATION)) != 0U) { | ||
XMC_UART_CH_ClearStatusFlag(_XMC_UART_config->channel, | ||
(XMC_UART_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION | | ||
XMC_UART_CH_STATUS_FLAG_RECEIVE_INDICATION)); | ||
|
||
while (_XMC_UART_config->channel->RBUFSR & | ||
(USIC_CH_RBUFSR_RDV0_Msk | USIC_CH_RBUFSR_RDV1_Msk)) | ||
_rx_buffer->store_char(XMC_UART_CH_GetReceivedData(_XMC_UART_config->channel)); | ||
} | ||
} | ||
|
||
//**************************************************************************** | ||
// END OF FILE | ||
//**************************************************************************** |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
Copyright (c) 2011 Arduino. All right reserved. | ||
|
||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
|
||
This library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
See the GNU Lesser General Public License for more details. | ||
|
||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; if not, write to the Free Software | ||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
#pragma once | ||
|
||
//**************************************************************************** | ||
// @External Prototypes | ||
//**************************************************************************** | ||
|
||
#include "Arduino.h" | ||
//**************************************************************************** | ||
// @Project Includes | ||
//**************************************************************************** | ||
#include "api/HardwareSerial.h" | ||
#include "api/RingBuffer.h" | ||
|
||
//**************************************************************************** | ||
// @Typedefs | ||
//**************************************************************************** | ||
// Define config for Serial.begin(baud, config); | ||
#undef SERIAL_5N1 | ||
#undef SERIAL_6N1 | ||
#undef SERIAL_7N1 | ||
#undef SERIAL_8N1 | ||
#undef SERIAL_5N2 | ||
#undef SERIAL_6N2 | ||
#undef SERIAL_7N2 | ||
#undef SERIAL_8N2 | ||
#undef SERIAL_5E1 | ||
#undef SERIAL_6E1 | ||
#undef SERIAL_7E1 | ||
#undef SERIAL_8E1 | ||
#undef SERIAL_5E2 | ||
#undef SERIAL_6E2 | ||
#undef SERIAL_7E2 | ||
#undef SERIAL_8E2 | ||
#undef SERIAL_5O1 | ||
#undef SERIAL_6O1 | ||
#undef SERIAL_7O1 | ||
#undef SERIAL_8O1 | ||
#undef SERIAL_5O2 | ||
#undef SERIAL_6O2 | ||
#undef SERIAL_7O2 | ||
#undef SERIAL_8O2 | ||
|
||
typedef enum XMC_UART_MODE { | ||
SERIAL_5N1 = 0x15 | XMC_USIC_CH_PARITY_MODE_NONE, | ||
SERIAL_6N1 = 0x16 | XMC_USIC_CH_PARITY_MODE_NONE, | ||
SERIAL_7N1 = 0x17 | XMC_USIC_CH_PARITY_MODE_NONE, | ||
SERIAL_8N1 = 0x18 | XMC_USIC_CH_PARITY_MODE_NONE, | ||
SERIAL_5N2 = 0x25 | XMC_USIC_CH_PARITY_MODE_NONE, | ||
SERIAL_6N2 = 0x26 | XMC_USIC_CH_PARITY_MODE_NONE, | ||
SERIAL_7N2 = 0x27 | XMC_USIC_CH_PARITY_MODE_NONE, | ||
SERIAL_8N2 = 0x28 | XMC_USIC_CH_PARITY_MODE_NONE, | ||
SERIAL_5E1 = 0x15 | XMC_USIC_CH_PARITY_MODE_EVEN, | ||
SERIAL_6E1 = 0x16 | XMC_USIC_CH_PARITY_MODE_EVEN, | ||
SERIAL_7E1 = 0x17 | XMC_USIC_CH_PARITY_MODE_EVEN, | ||
SERIAL_8E1 = 0x18 | XMC_USIC_CH_PARITY_MODE_EVEN, | ||
SERIAL_5E2 = 0x25 | XMC_USIC_CH_PARITY_MODE_EVEN, | ||
SERIAL_6E2 = 0x26 | XMC_USIC_CH_PARITY_MODE_EVEN, | ||
SERIAL_7E2 = 0x27 | XMC_USIC_CH_PARITY_MODE_EVEN, | ||
SERIAL_8E2 = 0x28 | XMC_USIC_CH_PARITY_MODE_EVEN, | ||
SERIAL_5O1 = 0x15 | XMC_USIC_CH_PARITY_MODE_ODD, | ||
SERIAL_6O1 = 0x16 | XMC_USIC_CH_PARITY_MODE_ODD, | ||
SERIAL_7O1 = 0x17 | XMC_USIC_CH_PARITY_MODE_ODD, | ||
SERIAL_8O1 = 0x18 | XMC_USIC_CH_PARITY_MODE_ODD, | ||
SERIAL_5O2 = 0x25 | XMC_USIC_CH_PARITY_MODE_ODD, | ||
SERIAL_6O2 = 0x26 | XMC_USIC_CH_PARITY_MODE_ODD, | ||
SERIAL_7O2 = 0x27 | XMC_USIC_CH_PARITY_MODE_ODD, | ||
SERIAL_8O2 = 0x28 | XMC_USIC_CH_PARITY_MODE_ODD | ||
} XMC_UART_MODE_t; | ||
|
||
//**************************************************************************** | ||
// @Class Definitionsw | ||
//**************************************************************************** | ||
class Uart : public HardwareSerial { | ||
public: | ||
XMC_UART_t *_XMC_UART_config; | ||
Uart(XMC_UART_t *xmc_uart_config, RingBuffer *rx_buffer); | ||
|
||
void begin(unsigned long); | ||
void begin(unsigned long baudrate, uint16_t config) override; | ||
void begin(unsigned long, XMC_UART_MODE_t config); | ||
void end(); | ||
int available(void); | ||
int availableForWrite(void); | ||
int peek(void); | ||
int read(void); | ||
void flush(void); | ||
|
||
// virtual size_t readBytes(char *buffer, size_t length) ; // read chars from stream into buffer | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cleanup stale code or comment whey it is commented. |
||
// virtual size_t readBytes(uint8_t *buffer, size_t length) ; | ||
|
||
size_t write(const uint8_t); | ||
|
||
// virtual size_t write(const uint8_t *buffer, size_t size) ; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some or all of these functions are already provided by parent classes. Unless they are different, we don´t need to rewrite them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can remove the inline functions, here is the reason I keep it: If I had to severely rewrite the entire uart module, I would change this part There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For all the other types you would use the print() function. And these are handled here: The overloaded print() functions will eventually call write(). We need to provide mandatorily: |
||
inline size_t write(unsigned long n) { return write((uint8_t)n); } | ||
|
||
inline size_t write(long n) { return write((uint8_t)n); } | ||
|
||
inline size_t write(unsigned int n) { return write((uint8_t)n); } | ||
|
||
inline size_t write(int n) { return write((uint8_t)n); } | ||
|
||
using Print::write; // pull in write(str) and write(buf, size) from Print | ||
|
||
operator bool() { return true; } | ||
|
||
void setInterruptPriority(uint32_t priority); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these functions public ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hi juan, for uart we have another one branch please check other PR which is created by linjing , kindly do review also that one. i will remove the rewrite functions and let me test again for UART implementation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, i mean, if that is part of another PR it is fine. |
||
uint32_t getInterruptPriority(); | ||
|
||
void IrqHandler(void); | ||
|
||
private: | ||
RingBuffer *_rx_buffer; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not to have the RingBuffer object instead of a pointer? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had the same question. Of course we can change it, but we also need to change all the declarations inside pins_arduino.h. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless a good reason not to be a private member of the class. Yes please. |
||
}; | ||
|
||
extern Uart Serial; | ||
extern Uart Serial1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if we could create a XMC_UART object by passing valid UART pins like
UART(pin_tx, pin_rx, pin_cts, pin_rts)
.Not sure how affordable is it to implement based on the xmc_lib API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be possible. need to modify pins_arduino.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one probably needs more work than we want to take now. So we can create a ticket for this for the future.