Skip to content

Commit

Permalink
Add Zephyr support
Browse files Browse the repository at this point in the history
  • Loading branch information
martinjaeger committed Mar 11, 2020
1 parent c99cfd9 commit 8c52b9d
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 0 deletions.
16 changes: 16 additions & 0 deletions cicada/platform/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_include_directories(../../..)

target_sources(app PRIVATE zephyrserial.cpp)
target_sources(app PRIVATE zephyrtick.cpp)
target_sources(app PRIVATE zephyrirq.cpp)

target_sources(app PRIVATE ../../bufferedserial.cpp)
target_sources(app PRIVATE ../../mqttcountdown.cpp)

target_sources(app PRIVATE ../../commdevices/ipcommdevice.cpp)
target_sources(app PRIVATE ../../commdevices/simcommdevice.cpp)
#target_sources(app PRIVATE ../../commdevices/sim7x00.cpp)
target_sources(app PRIVATE ../../commdevices/sim800.cpp)
target_sources(app PRIVATE ../../commdevices/blockingcommdev.cpp)
37 changes: 37 additions & 0 deletions cicada/platform/zephyr/zephyrirq.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2020 Martin Jäger / Libre Solar
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#include "cicada/irq.h"

#include <zephyr.h>

unsigned int irq_lock_key;

void eDisableInterrupts()
{
irq_lock_key = irq_lock();
}

void eEnableInterrupts()
{
irq_unlock(irq_lock_key);
}
123 changes: 123 additions & 0 deletions cicada/platform/zephyr/zephyrserial.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (C) 2020 Martin Jäger / Libre Solar
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#include "cicada/platform/zephyr/zephyrserial.h"

#include <zephyr.h>
#include <drivers/uart.h>

#include "cicada/irq.h"
#include <cstdint>

using namespace Cicada;

ZephyrSerial::ZephyrSerial(char* readBuffer, char* writeBuffer, Size readBufferSize,
Size writeBufferSize, const char *devName) :
BufferedSerial(readBuffer, writeBuffer, readBufferSize, writeBufferSize)
{
uart_dev = device_get_binding(devName);
}

bool ZephyrSerial::setSerialConfig(uint32_t baudRate, uint8_t dataBits)
{
struct uart_config uart_conf;

uart_config_get(uart_dev, &uart_conf);

if (baudRate < 50 || baudRate > 4500000) {
return false;
}

uart_conf.baudrate = baudRate;

switch (dataBits) {
case 8:
uart_conf.data_bits = UART_CFG_DATA_BITS_8;
break;
case 9:
uart_conf.data_bits = UART_CFG_DATA_BITS_9;
break;
default:
return false;
}

return uart_configure(uart_dev, &uart_conf) == 0;
}

bool ZephyrSerial::open()
{
return true;
}

void ZephyrSerial::close() {;}

bool ZephyrSerial::isOpen()
{
return true;
}

const char* ZephyrSerial::portName() const
{
return NULL;
}

bool ZephyrSerial::rawRead(uint8_t& data)
{
return uart_poll_in(uart_dev, &data) == 0;
}

bool ZephyrSerial::rawWrite(uint8_t data)
{
if (tx_complete) {
tx_complete = false;
uart_poll_out(uart_dev, data);
return true;
}
return false;
}

void ZephyrSerial::startTransmit()
{
uart_irq_callback_user_data_set(uart_dev, handleInterrupt, this);

/*
* This will enable the TC (transmission complete) interrupt, not TXE (transmit data register
* empty) interrupt.
* TXE would be more suitable, but is not supported by Zephyr driver at the moment.
*/
uart_irq_tx_enable(uart_dev);
}

void ZephyrSerial::handleInterrupt(void *user_data)
{
ZephyrSerial *instance = (ZephyrSerial *)user_data;

uart_irq_update(instance->uart_dev);
instance->tx_complete = uart_irq_tx_complete(instance->uart_dev);

instance->transferToAndFromBuffer();
}

bool ZephyrSerial::writeBufferProcessed() const
{
return _writeBuffer.bytesAvailable() == 0 && tx_complete;
}
96 changes: 96 additions & 0 deletions cicada/platform/zephyr/zephyrserial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright (C) 2020 Martin Jäger / Libre Solar
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#ifndef ZEPHYRSERIAL_H_
#define ZEPHYRSERIAL_H_

#include <zephyr.h>

#include "cicada/bufferedserial.h"

#define Size Cicada::Size

/*!
* UART driver for STM32 micro controllers, using HAL.
*
* *NOTE:* If you use more than one UART port in your program, you need to set
* the preprocessor define `E_MULTITON_MAX_INSTANCES` to the number of ports
* used. You can set this macro with the -D compiler argument, for example
* `-DE_MULTITON_MAX_INSTANCES=2`.
*
* In the UART's IRQ handler, get the instance with `ZephyrSerial::getInstance()`
* and call it's `handleInterrupt()` function. Example:
* ```
* void USART3_IRQHandler()
* {
* static ZephyrSerial* instance = ZephyrSerial::getInstance(USART3);
* instance->handleInterrupt();
* }
* ```
*/

class ZephyrSerial : public Cicada::BufferedSerial
{
public:

/*!
* Constructor with user supplied buffers for read/write buffers.
*
* \param readBuffer user supplied buffer for data arriving at the serial line
* \param writeBuffer user supplied buffer to store data before being sent on the serial line
* \param readBufferSize size of the read buffer
* \param writeBufferSize size of the write buffer
* \param devName Zephyr UART/USART device name
*/
ZephyrSerial(char* readBuffer, char* writeBuffer, Size readBufferSize, Size writeBufferSize,
const char *devName);

virtual bool open() override;
virtual bool isOpen() override;
virtual bool setSerialConfig(uint32_t baudRate, uint8_t dataBits) override;
virtual void close() override;
virtual const char* portName() const override;
virtual bool rawRead(uint8_t& data) override;
virtual bool rawWrite(uint8_t data) override;
virtual void startTransmit() override;
virtual bool writeBufferProcessed() const override;

static void handleInterrupt(void *instance);

bool tx_complete = false;

private:
// Private constructors to avoid copying
ZephyrSerial(const ZephyrSerial&);
ZephyrSerial& operator=(const ZephyrSerial&);

//void init(USART_TypeDef* uartInstance);

static ZephyrSerial* instance[E_MULTITON_MAX_INSTANCES];

struct device *uart_dev;

uint8_t _flags;
//IRQn_Type _uartInterruptInstance;
};

#endif
34 changes: 34 additions & 0 deletions cicada/platform/zephyr/zephyrtick.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2020 Martin Jäger / Libre Solar
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#include "cicada/tick.h"

#include <zephyr.h>

E_TICK_TYPE eTickFunction()
{
/*
* 32-bit timer should be fine, as in case of a rollover also the threshold should roll over
* (see implementation in mqttcountdown.cpp)
*/
return k_uptime_get_32();
}

0 comments on commit 8c52b9d

Please sign in to comment.