Skip to content
Snippets Groups Projects
Select Git revision
6 results

CC3135.h

Blame
  • CC3135.h 4.80 KiB
    /* Copyright (c) 2022 Skyward Experimental Rocketry
     * Author: Davide Mor
     *
     * 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.
     */
    
    #pragma once
    
    #include <ActiveObject.h>
    #include <miosix.h>
    
    #include <functional>
    #include <memory>
    
    #include "CC3135Defs.h"
    #include "CC3135Iface.h"
    
    /*
    TODO(davide.mor): Write a small description of the CC3135
    
    TODO(davide.mor): Write about scatter/gather IO
    */
    
    namespace Boardcore
    {
    
    class CC3135 : ActiveObject
    {
    public:
        enum class Error
        {
            NO_ERROR,             //< No error occured.
            NWP_TIMEOUT,          //< The NWP did not respond.
            NWP_STATUS_NON_ZERO,  //< The NWD returned a non-zero status code.
        };
    
        explicit CC3135(std::unique_ptr<ICC3135Iface> &&iface);
    
        CC3135::Error init(bool wait_for_init);
    
        void handleIrq();
    
        CC3135::Error getVersion(CC3135Defs::DeviceVersion &version);
    
        CC3135::Error setMode(CC3135Defs::Mode mode);
    
    private:
        //! Simple buffer for scatter/gather IO
        struct Buffer
        {
            uint8_t *ptr;
            size_t len;
    
            template <typename T>
            static Buffer from(T *data)
            {
                return {reinterpret_cast<uint8_t *>(data), sizeof(T)};
            }
    
            static Buffer null() { return {nullptr, 0}; }
        };
    
        class ServiceThreadLock
        {
        public:
            ServiceThreadLock(CC3135 *parent) : parent(parent)
            {
                parent->installAsServiceThread();
            }
    
            ~ServiceThreadLock() { parent->restoreDefaultServiceThread(); }
    
        private:
            CC3135 *parent;
        };
    
        //! Function for servicing async messages.
        void run() override;
    
        void defaultPacketHandler(CC3135Defs::ResponseHeader header);
    
        CC3135::Error devigeGet(uint8_t set_id, uint8_t option, Buffer result);
    
        //! Read something from the device, to wake it up?
        CC3135::Error dummyDeviceRead();
    
        // Functions dedicated to interrupt servicing
    
        //! Wait for an incoming interrupt (only callable in service thread).
        void waitForIrq();
        //! Install this thread as the service thread.
        void installAsServiceThread();
        //! Restore default service thread.
        void restoreDefaultServiceThread();
    
        // Functions for high level IO
    
        //! Write a packet in output and wait for a packet in input
        CC3135::Error inoutPacketSync(CC3135Defs::OpCode tx_opcode,
                                      Buffer tx_command, Buffer tx_payload,
                                      CC3135Defs::OpCode rx_opcode,
                                      Buffer rx_command, Buffer rx_payload);
        //! Read packet in input, with proper synchronization.
        CC3135::Error readPacketSync(CC3135Defs::OpCode opcode, Buffer command,
                                     Buffer payload);
        //! Write a packet in output, with proper synchronization.
        CC3135::Error writePacketSync(CC3135Defs::OpCode opcode, Buffer command,
                                      Buffer payload);
    
        // Functions for low level IO
    
        //! Read a single packet.
        CC3135::Error readPacket(CC3135Defs::OpCode opcode, Buffer command,
                                 Buffer payload);
        //! Write a single packet.
        CC3135::Error writePacket(CC3135Defs::OpCode opcode, Buffer command,
                                  Buffer payload);
        //! Read a packet header.
        CC3135::Error readHeader(CC3135Defs::ResponseHeader *header);
        //! Write a packet header.
        CC3135::Error writeHeader(CC3135Defs::RequestHeader *header);
    
        //! Read dummy n bytes.
        void dummyRead(size_t n);
    
        //! Safely read a buffer, does bound checking
        void safeRead(size_t &len, Buffer buffer);
    
        miosix::Thread *irq_wait_thread = nullptr;  //< Thread waiting on IRQ
        size_t irq_count                = 0;        //< Number of interrupts
    
        miosix::FastMutex iface_mutex;
        std::unique_ptr<ICC3135Iface> iface;
    
        uint8_t tx_seq_num = 0;
    };
    
    }  // namespace Boardcore