diff options
Diffstat (limited to 'cm3cpp/spi.hpp')
-rw-r--r-- | cm3cpp/spi.hpp | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/cm3cpp/spi.hpp b/cm3cpp/spi.hpp new file mode 100644 index 0000000..cbb4f13 --- /dev/null +++ b/cm3cpp/spi.hpp @@ -0,0 +1,258 @@ +/* + * This file is part of the libopencm3_cpp_extensions project. + * hosted at http://github.com/thirdpin/libopencm3_cpp_extensions + * + * Copyright (C) 2016 Third Pin LLC + * Written by Anastasiia Lazareva <a.lazareva@thirdpin.ru> + * Written by Maxim Ambrosevich + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* +SPI C++ Wrapper of libopencm3 library for STM32F2, STM32F4 +*/ + +#ifndef SPI_EXT_H +#define SPI_EXT_H + +#include <libopencm3/stm32/spi.h> + +#include "gpio.hpp" +#include "irq/irq.hpp" + +namespace cm3cpp { + +namespace spi { + +constexpr bool OK = true; +constexpr bool ERROR = false; + +enum Flag : uint32_t +{ + RECEIVE_BUFFER_NOT_EMPTY = 0x0001, + TRANSMIT_BUFFER_EMPTY = 0x0002, + CHANEL_SIDE = 0x0004, + UNDERRUN_FLAG = 0x0008, + CRC_ERROR = 0x0010, + MODE_FAULT = 0x0020, + OVERRUN_FLAG = 0x0040, + BUSY_FLAG = 0x0080, + TI_FRAME_FORMAT_ERROR = 0x0100, +}; + +enum BaudRate : uint8_t +{ + BAUDRATE_FPCLK_DIV_2 = 0x00, + BAUDRATE_FPCLK_DIV_4 = 0x01, + BAUDRATE_FPCLK_DIV_8 = 0x02, + BAUDRATE_FPCLK_DIV_16 = 0x03, + BAUDRATE_FPCLK_DIV_32 = 0x04, + BAUDRATE_FPCLK_DIV_64 = 0x05, + BAUDRATE_FPCLK_DIV_128 = 0x06, + BAUDRATE_FPCLK_DIV_256 = 0x07, +}; + +enum NextTx +{ + NEXT_TX_FROM_BUFFER, + NEXT_TX_FROM_CRC +}; + +enum DataFrameFormat +{ + DFF_8BIT, + DFF_16BIT +}; + +enum State +{ + DISABLE, + ENABLE +}; + +enum NssState +{ + LOW, + HIGH +}; + +enum Polarity +{ + POLARITY_LOW, + POLARITY_HIGH +}; + +enum Phase +{ + PHASE_LOW, + PHASE_HIGH +}; + +enum BitPos +{ + MSB_FIRST, + LSB_FIRST +}; + +enum StdMode +{ + MODE_0 = 0, + MODE_1, + MODE_2, + MODE_3 +}; + +class Spi : public IInterruptable +{ + public: + using Gpio = gpio::Gpio; + + struct Config + { + uint8_t spi_number; + Gpio::Pinout mosi_pin; + Gpio::Pinout miso_pin; + Gpio::Pinout scl_pin; + }; + + Spi(); + Spi(Config spi_conf); + + void call(); + + bool get_flag_status(Flag flag) const; + + void reset() { spi_reset(_spi); } + + void enable() { spi_enable(_spi); } + + void disable() { spi_disable(_spi); } + + void clean_disable() { spi_clean_disable(_spi); } + + void write(uint16_t data) + { + while (!get_flag_status(Flag::TRANSMIT_BUFFER_EMPTY)) + ; + SPI_DR(_spi) = data; + } + + void write_end() + { + while (!get_flag_status(Flag::RECEIVE_BUFFER_NOT_EMPTY)) + ; + (void)SPI_DR(_spi); + } + + uint16_t read(uint16_t data) + { + while (!get_flag_status(Flag::TRANSMIT_BUFFER_EMPTY)) + ; + SPI_DR(_spi) = data; + while (!get_flag_status(Flag::RECEIVE_BUFFER_NOT_EMPTY)) + ; + return SPI_DR(_spi); + } + + void set_master_mode() { spi_set_master_mode(_spi); } + + void set_slave_mode() { spi_set_slave_mode(_spi); } + + void full_duplex_mode() { spi_set_full_duplex_mode(_spi); } + + void set_bidirectional_mode() { spi_set_bidirectional_mode(_spi); } + + void set_bidirectional_transmit_only_mode() + { + spi_set_bidirectional_transmit_only_mode(_spi); + } + + void set_bidirectional_receive_only_mode() + { + spi_set_bidirectional_receive_only_mode(_spi); + } + + void set_unidirectional_mode() { spi_set_unidirectional_mode(_spi); } + + void set_receive_only_mode() { spi_set_receive_only_mode(_spi); } + + void enable_crc() { spi_enable_crc(_spi); } + + void disable_crc() { spi_disable_crc(_spi); } + + void set_next_tx_from(NextTx next); + void set_data_drame_format(DataFrameFormat dff); + void set_software_slave_management(State state); + void set_nss(NssState nss); + void set_bit_position(BitPos pos); + + void set_baudrate_prescaler(BaudRate baudrate) + { + spi_set_baudrate_prescaler(_spi, (uint8_t)baudrate); + } + + void set_clock_polarity(Polarity polarity); + void set_clock_phase(Phase phase); + + void enable_nvic(); + + void enable_tx_buffer_empty_interrupt() + { + spi_enable_tx_buffer_empty_interrupt(_spi); + } + + void disable_tx_buffer_empty_interrupt() + { + spi_disable_tx_buffer_empty_interrupt(_spi); + } + + void enable_rx_buffer_not_empty_interrupt() + { + spi_enable_rx_buffer_not_empty_interrupt(_spi); + } + + void disable_rx_buffer_not_empty_interrupt() + { + spi_disable_rx_buffer_not_empty_interrupt(_spi); + } + + void enable_error_interrupt() { spi_enable_error_interrupt(_spi); } + + void disable_error_interrupt() { spi_disable_error_interrupt(_spi); } + + void enable_ss_output() { spi_enable_ss_output(_spi); } + + void disable_ss_output() { spi_disable_ss_output(_spi); } + + void enable_tx_dma() { spi_enable_tx_dma(_spi); } + + void disable_tx_dma() { spi_disable_tx_dma(_spi); } + + void enable_rx_dma() { spi_enable_rx_dma(_spi); } + + void disable_rx_dma() { spi_disable_rx_dma(_spi); } + + void set_standard_mode(StdMode mode) { spi_set_standard_mode(_spi, mode); } + + private: + uint32_t _spi; + Interrupt _irq; +}; + +} // namespace spi + +} // namespace cm3cpp + +#endif |