Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Ignore .pre-commit-config.yaml
.pre-commit-config.yaml
.vscode/
.pre-commit-config.yaml
63 changes: 31 additions & 32 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
repos:

- repo: https://github.com/pre-commit/mirrors-clang-format
rev: 7d85583be209cb547946c82fbe51f4bc5dd1d017
hooks:
- id: clang-format
args: [--style=Google]
files: \.(cpp|hpp|c|h)$
stages: [commit]

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.5.1
hooks:
- id: prettier
files: \.(js|ts|jsx|tsx|css|less|html|json|markdown|md|yaml|yml)$

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.1
hooks:
- id: ruff
types_or: [ python, pyi ]
args: [ --fix ]
stages: [commit]
- id: ruff-format
stages: [commit]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
repos:
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: 7d85583be209cb547946c82fbe51f4bc5dd1d017
hooks:
- id: clang-format
args: [--style=Google]
files: \.(cpp|hpp|c|h)$
stages: [commit]

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.5.1
hooks:
- id: prettier
files: \.(js|ts|jsx|tsx|css|less|html|json|markdown|md|yaml|yml)$

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.1
hooks:
- id: ruff
types_or: [python, pyi]
args: [--fix]
stages: [commit]
- id: ruff-format
stages: [commit]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
41 changes: 41 additions & 0 deletions QSPI/Inc/QSPI_Command.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef QSPI_COMMAND_HPP
#define QSPI_COMMAND_HPP

#include <stdint.h>
#include <stm32h7xx_hal_qspi.h>

/**
* @brief Enum class representing the size of the QSPI address.
*/
enum class QSPI_AddressSize {
OneByte = QSPI_ADDRESS_8_BITS, ///< 8-bit address
TwoBytes = QSPI_ADDRESS_16_BITS, ///< 16-bit address
ThreeBytes = QSPI_ADDRESS_24_BITS, ///< 24-bit address
FourBytes = QSPI_ADDRESS_32_BITS ///< 32-bit address
};

/**
* @brief Struct representing a QSPI command.
*
* This struct encapsulates the details of a QSPI command, including the
* instruction, address, address size, transfer size, and data buffer. It also
* provides a method to convert the command to a HAL-compatible QSPI command
* structure.
*/
struct QSPI_Command {
uint8_t instruction; ///< The instruction byte for the QSPI command.
uint32_t address; ///< The address for the QSPI command.
QSPI_AddressSize address_size; ///< The size of the address.
size_t transfer_size; ///< The size of the data transfer.
uint8_t *data_buffer = nullptr; ///< Pointer to the data buffer.

/**
* @brief Converts the QSPI command to a HAL-compatible QSPI command
* structure.
*
* @return QSPI_CommandTypeDef The HAL-compatible QSPI command structure.
*/
QSPI_CommandTypeDef to_hal_cmd() const;
};

#endif // QSPI_COMMAND_HPP
62 changes: 62 additions & 0 deletions QSPI/Inc/QSPI_DeviceContext.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef QSPI_DEVICE_CTX_HPP
#define QSPI_DEVICE_CTX_HPP

#include <stdint.h>
#include <stm32h7xx_hal.h>

/**
* @brief Struct representing the context of a QSPI device.
*
* This struct encapsulates the context required for QSPI communication,
* including the chip select (CS) port and pin, and the maximum timeout for
* operations.
*/
struct QSPI_DeviceContext {
private:
GPIO_TypeDef &cs_port; ///< Reference to the GPIO port for chip select.
uint16_t cs_pin; ///< Pin number for chip select.
uint32_t max_timeout; ///< Maximum timeout for QSPI operations.

public:
/**
* @brief Constructor for QSPI_DeviceContext.
*
* @param cs_port Reference to the GPIO port for chip select.
* @param cs_pin Pin number for chip select.
* @param max_timeout Maximum timeout for QSPI operations (default is
* HAL_MAX_DELAY).
*/
QSPI_DeviceContext(GPIO_TypeDef &cs_port, uint16_t cs_pin,
uint32_t max_timeout = HAL_MAX_DELAY)
: cs_port(cs_port), cs_pin(cs_pin), max_timeout(max_timeout) {}

/**
* @brief Get the chip select port as a pointer.
*
* @return GPIO_TypeDef* Pointer to the GPIO port for chip select.
*/
GPIO_TypeDef *get_cs_port_as_ptr() const { return &this->cs_port; }

/**
* @brief Get the chip select port as a reference.
*
* @return GPIO_TypeDef& Reference to the GPIO port for chip select.
*/
GPIO_TypeDef &get_cs_port_as_ref() const { return this->cs_port; }

/**
* @brief Get the chip select pin number.
*
* @return uint16_t Pin number for chip select.
*/
uint16_t get_cs_pin() const { return this->cs_pin; }

/**
* @brief Get the maximum timeout for QSPI operations.
*
* @return uint32_t Maximum timeout for QSPI operations.
*/
uint32_t get_max_timeout() const { return this->max_timeout; }
};

#endif // QSPI_DEVICE_CTX_HPP
50 changes: 50 additions & 0 deletions QSPI/Inc/QSPI_Driver.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#ifndef QSPI_DRIVER_HPP
#define QSPI_DRIVER_HPP

#include <stm32h7xx_hal_qspi.h>

#include "QSPI_Command.hpp"
#include "QSPI_DeviceContext.hpp"
#include "QSPI_Result.hpp"

/**
* @brief Class representing a QSPI driver.
*
* This class provides methods to perform read and write operations using QSPI.
* It encapsulates a QSPI handle and provides methods to interact with QSPI
* devices.
*/
class QSPI_Driver {
private:
QSPI_HandleTypeDef &qspi_handle; ///< Reference to the QSPI handle.

public:
/**
* @brief Constructor for QSPI_Driver.
*
* @param hqspi Reference to the QSPI handle.
*/
QSPI_Driver(QSPI_HandleTypeDef &hqspi) : qspi_handle(hqspi) {}

/**
* @brief Write data to a QSPI device.
*
* @param ctx The context of the QSPI device.
* @param cmd The QSPI command to be executed.
* @return QSPI_Result The result of the write operation.
*/
QSPI_Result write(const QSPI_DeviceContext &ctx,
const QSPI_Command &cmd) const;

/**
* @brief Read data from a QSPI device.
*
* @param ctx The context of the QSPI device.
* @param cmd The QSPI command to be executed.
* @return QSPI_Result The result of the read operation.
*/
QSPI_Result read(const QSPI_DeviceContext &ctx,
const QSPI_Command &cmd) const;
};

#endif // QSPI_DRIVER_HPP
23 changes: 23 additions & 0 deletions QSPI/Inc/QSPI_Result.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef QSPI_RESULT_HPP
#define QSPI_RESULT_HPP

#include <stm32h7xx_hal.h>

/**
* The `Ok` variant is the only truthy variant
*/
enum class QSPI_Result { Ok = 1, Err = -1, Busy = -2, Timeout = -3 };

inline bool operator!(QSPI_Result error) { return error != QSPI_Result::Ok; }

inline bool operator==(QSPI_Result error, bool value) {
return (error == QSPI_Result::Ok) == value;
}

inline bool operator!=(QSPI_Result error, bool value) {
return !(error == value);
}

QSPI_Result from_hal_status(HAL_StatusTypeDef status);

#endif // QSPI_RESULT_HPP
28 changes: 28 additions & 0 deletions QSPI/Src/QSPI_Command.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "../Inc/QSPI_Command.hpp"

// If anything causes problems, it probably has to do with this function
// This requires testing along with the rest of the QSPI driver but this is the
// most likely source of issues
QSPI_CommandTypeDef QSPI_Command::to_hal_cmd() const {
QSPI_CommandTypeDef hal_cmd;

hal_cmd.Address = this->address;
hal_cmd.AddressSize = static_cast<uint32_t>(this->address_size);
hal_cmd.AddressMode = QSPI_ADDRESS_NONE;

hal_cmd.Instruction = this->instruction;
hal_cmd.InstructionMode = QSPI_INSTRUCTION_NONE;

hal_cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_1_LINE;
hal_cmd.AlternateBytes = 0;
hal_cmd.AlternateBytesSize = 0;

hal_cmd.DataMode = QSPI_DATA_1_LINE;
hal_cmd.DummyCycles = 0;
hal_cmd.NbData = this->transfer_size;
hal_cmd.DdrMode = QSPI_DDR_MODE_DISABLE;
hal_cmd.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
hal_cmd.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

return hal_cmd;
}
72 changes: 72 additions & 0 deletions QSPI/Src/QSPI_Driver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* @author Connell Reffo
*/

#include "../Inc/QSPI_Driver.hpp"

#include <stm32h743xx.h>
#include <stm32h7xx_hal.h>
#include <stm32h7xx_hal_qspi.h>

#include "../Inc/QSPI_DeviceContext.hpp"
#include "../Inc/QSPI_Result.hpp"

QSPI_Result QSPI_Driver::write(const QSPI_DeviceContext &ctx,
const QSPI_Command &cmd) const {
// Pull chip select to low
// Standard communiaction protocol before sending command
HAL_GPIO_WritePin(ctx.get_cs_port_as_ptr(), ctx.get_cs_pin(), GPIO_PIN_RESET);

// Setup command
QSPI_CommandTypeDef hal_cmd = cmd.to_hal_cmd();

const QSPI_Result write_cmd_result = from_hal_status(
HAL_QSPI_Command(&this->qspi_handle, &hal_cmd, ctx.get_max_timeout()));

if (!write_cmd_result) {
return write_cmd_result;
}

// Transmit command
const QSPI_Result transmit_cmd_result = from_hal_status(HAL_QSPI_Transmit(
&this->qspi_handle, cmd.data_buffer, ctx.get_max_timeout()));

if (!transmit_cmd_result) {
return transmit_cmd_result;
}

// Pull CS back to high
// This signifies the end of the command
HAL_GPIO_WritePin(ctx.get_cs_port_as_ptr(), ctx.get_cs_pin(), GPIO_PIN_SET);

return QSPI_Result::Ok;
}

QSPI_Result QSPI_Driver::read(const QSPI_DeviceContext &ctx,
const QSPI_Command &cmd) const {
// Pull CS low
HAL_GPIO_WritePin(ctx.get_cs_port_as_ptr(), ctx.get_cs_pin(), GPIO_PIN_RESET);

// Setup command
QSPI_CommandTypeDef hal_cmd = cmd.to_hal_cmd();

const QSPI_Result read_cmd_result = from_hal_status(
HAL_QSPI_Command(&this->qspi_handle, &hal_cmd, ctx.get_max_timeout()));

if (!read_cmd_result) {
return read_cmd_result;
}

// Receive data
const QSPI_Result receive_cmd_result = from_hal_status(HAL_QSPI_Receive(
&this->qspi_handle, cmd.data_buffer, ctx.get_max_timeout()));

if (!receive_cmd_result) {
return receive_cmd_result;
}

// Pull CS back high
HAL_GPIO_WritePin(ctx.get_cs_port_as_ptr(), ctx.get_cs_pin(), GPIO_PIN_SET);

return QSPI_Result::Ok;
}
9 changes: 9 additions & 0 deletions QSPI/Src/QSPI_Result.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "../Inc/QSPI_Result.hpp"

QSPI_Result from_hal_status(HAL_StatusTypeDef status) {
if (status == HAL_OK) {
return QSPI_Result::Ok;
}

return static_cast<QSPI_Result>(static_cast<signed char>(status) * -1);
}
Loading