174 lines
5.1 KiB
C++
174 lines
5.1 KiB
C++
|
|
/*
|
|||
|
|
* SpiBus.h
|
|||
|
|
*
|
|||
|
|
* Created on: 6 <EFBFBD><EFBFBD><EFBFBD>. 2019 <EFBFBD>.
|
|||
|
|
* Author: krugliy
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#ifndef SOURCE_DRIVER_SPIBUS_H_
|
|||
|
|
#define SOURCE_DRIVER_SPIBUS_H_
|
|||
|
|
|
|||
|
|
|
|||
|
|
#include <cstddef>
|
|||
|
|
|
|||
|
|
#include "../common/Link.hpp"
|
|||
|
|
|
|||
|
|
#include "DiscreteOutput_OnePin.hh"
|
|||
|
|
|
|||
|
|
#include "../peripheral/ISerialPort.hh"
|
|||
|
|
#include "../peripheral/ISerialPortConfigurator.hh"
|
|||
|
|
|
|||
|
|
|
|||
|
|
namespace driver {
|
|||
|
|
//serial port buffered driver
|
|||
|
|
class ISerialPortBuff {
|
|||
|
|
public:
|
|||
|
|
virtual bool buff_transmite( const void * bit_stream, int bit_count ) = 0;
|
|||
|
|
virtual bool receive( void * data ) = 0;
|
|||
|
|
|
|||
|
|
virtual ~ISerialPortBuff() = default;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
class SpiBusAbonentConfig {
|
|||
|
|
public:
|
|||
|
|
struct Setting {
|
|||
|
|
unsigned short clk_scheme;
|
|||
|
|
unsigned short cs_polarity;
|
|||
|
|
unsigned short transfer_delay;
|
|||
|
|
unsigned long baud_rate;
|
|||
|
|
bool rx_inv; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
bool tx_inv; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
bool loop_back_enable;
|
|||
|
|
|
|||
|
|
bool isValid() {
|
|||
|
|
return true; //todo: baud_rate <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool operator==( const Setting & other ) {
|
|||
|
|
|
|||
|
|
return ( clk_scheme == other.clk_scheme )
|
|||
|
|
&& ( baud_rate == other.baud_rate )
|
|||
|
|
&& ( loop_back_enable == other.loop_back_enable );
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool operator!=( const Setting & other ) { return not (*this == other ); }
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
bool configure( Setting & set ) {
|
|||
|
|
|
|||
|
|
if( not set.isValid() ) return false;
|
|||
|
|
|
|||
|
|
abonent_setting = set;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const Setting & getAbonentSetting() const { return abonent_setting; }
|
|||
|
|
|
|||
|
|
bool getCsActiveLevel() const { return abonent_setting.cs_polarity ==
|
|||
|
|
1; }
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
Setting abonent_setting;
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
|
|||
|
|
class SpiBus {
|
|||
|
|
public:
|
|||
|
|
class SpiAbonent;
|
|||
|
|
|
|||
|
|
static const unsigned short max_links = 32; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> max_spi_bus_abonents
|
|||
|
|
|
|||
|
|
static const unsigned short fifo_buff_size = 16; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> 16-<2D><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
static const unsigned short fifo_buff_word_bit_len = 16;
|
|||
|
|
static const unsigned short max_delay_cycle_count = 255;
|
|||
|
|
|
|||
|
|
peripheral::ISerialPort * createAbonent( peripheral::IGpio & chip_select,
|
|||
|
|
const SpiBusAbonentConfig & abon_config,
|
|||
|
|
std::pmr::memory_resource* allocator );
|
|||
|
|
|
|||
|
|
SpiBus( peripheral::ISerialPort & _serial_port,
|
|||
|
|
peripheral::ISerialPortConfigurator & _serial_configurator,
|
|||
|
|
std::size_t _max_spi_abonents );
|
|||
|
|
|
|||
|
|
virtual ~SpiBus() = default;
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
const std::size_t max_spi_bus_abonents;
|
|||
|
|
short num_spi_abonent;
|
|||
|
|
|
|||
|
|
class SpiBusMaster {
|
|||
|
|
private:
|
|||
|
|
peripheral::ISerialPort & serial_port;
|
|||
|
|
peripheral::ISerialPortConfigurator & serial_configurator;
|
|||
|
|
|
|||
|
|
SpiAbonent * active_abonent;
|
|||
|
|
SpiBusAbonentConfig::Setting active_abon_setting;
|
|||
|
|
Link<SpiAbonent, max_links> collision;
|
|||
|
|
|
|||
|
|
public:
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
//<2F> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0, <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0 <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
peripheral::ISerialPort * transfer_request( SpiAbonent * spi_abonent );
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
bool is_response_ready( SpiAbonent * spi_abonent );
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
void cancel_request( SpiAbonent * spi_abonent );
|
|||
|
|
|
|||
|
|
SpiBusMaster( peripheral::ISerialPort & _serial_port, peripheral::ISerialPortConfigurator & _serial_configurator );
|
|||
|
|
|
|||
|
|
} spiBusMaster;
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
class SpiBus::SpiAbonent : public peripheral::ISerialPort {
|
|||
|
|
private:
|
|||
|
|
SpiBus::SpiBusMaster & serial_bus;
|
|||
|
|
|
|||
|
|
const SpiBusAbonentConfig abon_config;
|
|||
|
|
driver::detail::DiscreteOutput_OnePin chip_select;
|
|||
|
|
|
|||
|
|
unsigned char rx_buff[fifo_buff_size]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
bool data_ready = false; //<2F><><EFBFBD><EFBFBD><EFBFBD> rx_buff - <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
short num_words;
|
|||
|
|
|
|||
|
|
public:
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
|
|||
|
|
const SpiBusAbonentConfig::Setting & getSetting() const { return abon_config.getAbonentSetting(); }
|
|||
|
|
|
|||
|
|
// bool transmite_handler( peripheral::ISerialPort & serial_port ); //<2F><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// //<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
|
|||
|
|
// //<2F><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> fifo <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
//
|
|||
|
|
//
|
|||
|
|
void transmite_complete_handler( peripheral::ISerialPort & serial_port );
|
|||
|
|
// bool transmite_complete_handler( CircularBuffer<spi_rx_buff_size, uint16_t> & master_rx_buff )
|
|||
|
|
|
|||
|
|
bool transmite( const void * bit_stream, int bit_count ) override;
|
|||
|
|
|
|||
|
|
bool receive( void * data ) override;
|
|||
|
|
|
|||
|
|
bool isDataReady();
|
|||
|
|
|
|||
|
|
SpiAbonent( SpiBusMaster & _bus_master, peripheral::IGpio & _chip_select,
|
|||
|
|
const SpiBusAbonentConfig & _abon_config );
|
|||
|
|
|
|||
|
|
virtual ~SpiAbonent();
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
|
|||
|
|
} /* namespace driver */
|
|||
|
|
|
|||
|
|
#endif /* SOURCE_DRIVER_SPIBUS_H_ */
|