mirror of
https://github.com/google/pebble.git
synced 2025-06-14 21:53:12 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
188
src/fw/drivers/spi.h
Normal file
188
src/fw/drivers/spi.h
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "board/board.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//
|
||||
//! High level slave port interface
|
||||
//! This part of the API can be used for fairly straightforward SPI interactions
|
||||
//! The assertion and deassertion of the SCS line is automatic
|
||||
//
|
||||
|
||||
//! Scatter Gather tx / rx information
|
||||
typedef struct SPIScatterGather {
|
||||
size_t sg_len; // number of bytes to tx and/or rx
|
||||
const void *sg_out; //! may be NULL (0 padding sent)
|
||||
void *sg_in; //! may be NULL (nothing saved)
|
||||
} SPIScatterGather;
|
||||
|
||||
typedef bool (*SPIDMACompleteHandler)(const SPISlavePort *slave, void *context);
|
||||
|
||||
//! Write byte to slave port and return the corresponding received byte
|
||||
uint8_t spi_slave_read_write(const SPISlavePort *slave, uint8_t out);
|
||||
|
||||
//! Write single data byte to the given slave port
|
||||
void spi_slave_write(const SPISlavePort *slave, uint8_t out);
|
||||
|
||||
//! Read a burst of bytes from given slave port (asserts SCS)
|
||||
//! 0 bytes are sent to the slave port to prompt the incoming bytes
|
||||
void spi_slave_burst_read(const SPISlavePort *slave, void *in, size_t len);
|
||||
|
||||
//! Write a burst of bytes to the given slave port (asserts SCS)
|
||||
//! No data is received or waited for
|
||||
void spi_slave_burst_write(const SPISlavePort *slave, const void *out, size_t len);
|
||||
|
||||
//! Transmit and Receive data bytes to and from the SPI Slave Port
|
||||
//! If out is NULL then 0s are transmitted, if in is NULL incoming data is not saved
|
||||
void spi_slave_burst_read_write(const SPISlavePort *slave, const void *out, void *in, size_t len);
|
||||
|
||||
//! Transmit and Receive data bytes to and from the SPI Slave Port (scatter gather)
|
||||
void spi_slave_burst_read_write_scatter(const SPISlavePort *slave,
|
||||
const SPIScatterGather *sc_info,
|
||||
size_t num_sg);
|
||||
|
||||
//! Set (or change) the clock frequency for the given SPI Slave Port (Hz)
|
||||
void spi_slave_set_frequency(const SPISlavePort *slave, uint32_t frequency_hz);
|
||||
|
||||
//! Wait until the SPI Slave is idle
|
||||
void spi_slave_wait_until_idle_blocking(const SPISlavePort *slave);
|
||||
|
||||
//! Gets the peripheral data register address for setting up DMA
|
||||
uint32_t spi_get_dma_base_address(const SPISlavePort *slave);
|
||||
|
||||
//
|
||||
//! Low level slave port interface
|
||||
//! This part of the API can be used for slightly more complex SPI operations
|
||||
//! (such as piecemeal reads or writes). Assertion and deassertion of SCS
|
||||
//! is up to the caller. Asserts in the code will help to ensure that the
|
||||
//! API is used correctly.
|
||||
//
|
||||
|
||||
//! The general use case for the _ll_ functions:
|
||||
//!
|
||||
//! acquire the Slave Port (start peripheral clock and enable SPI)
|
||||
//! spi_ll_slave_acquire(SLAVE);
|
||||
//! spi_ll_slave_scs_assert(SLAVE);
|
||||
//! perform (multiple) reads and writes as required
|
||||
//! spi_ll_XXXX(SLAVE, ...);
|
||||
//! spi_ll_XXXX(SLAVE, ...);
|
||||
//! spi_ll_XXXX(SLAVE, ...);
|
||||
//! release the Slave Port (stop peripheral clock and disable SPI)
|
||||
//! spi_ll_slave_scs_deassert(SLAVE);
|
||||
//! spi_ll_slave_release(SLAVE);
|
||||
//!
|
||||
//! Using the _ll_ routines it is also possible to perform slightly
|
||||
//! odd SPI transactions such as transmitting while SCS is not asserted
|
||||
//! or starting/stopping the clock while the SCS is asserted.
|
||||
//! These routines can also be used to adjust for timing requirements
|
||||
//! that some devices have.
|
||||
|
||||
//! Acquire the SPI device for use by spi_ll_XXXX functions
|
||||
//! All spi_ll_XXXX have asserts to check for acquisition
|
||||
//! Note: does not guarantee exclusivity for right now
|
||||
//! but could easily do one day if we ever share a SPI
|
||||
//! bus between multiple Slave Ports
|
||||
void spi_ll_slave_acquire(const SPISlavePort *slave);
|
||||
|
||||
//! Release the SPI Slave Port
|
||||
void spi_ll_slave_release(const SPISlavePort *slave);
|
||||
|
||||
//! Assert the SCS for the given SPI Slave Port
|
||||
void spi_ll_slave_scs_assert(const SPISlavePort *slave);
|
||||
|
||||
//! Deassert the SCS for the given SPI slave port
|
||||
void spi_ll_slave_scs_deassert(const SPISlavePort *slave);
|
||||
|
||||
//! Write byte to slave port and return the corresponding received byte
|
||||
//! It is up to the caller to ensure SCS is asserted correctly
|
||||
uint8_t spi_ll_slave_read_write(const SPISlavePort *slave, uint8_t out);
|
||||
|
||||
//! Write single data byte to the given slave port
|
||||
//! It is up to the caller to ensure SCS is asserted correctly
|
||||
void spi_ll_slave_write(const SPISlavePort *slave, uint8_t out);
|
||||
|
||||
//! Read a burst of bytes from given slave port
|
||||
//! 0 bytes are sent to the slave port to prompt the incoming bytes
|
||||
//! It is up to the caller to ensure SCS is asserted correctly
|
||||
void spi_ll_slave_burst_read(const SPISlavePort *slave, void *in, size_t len);
|
||||
|
||||
//! Write a burst of bytes to the given slave port
|
||||
//! No data is received or waited for
|
||||
//! It is up to the caller to ensure SCS is asserted correctly
|
||||
void spi_ll_slave_burst_write(const SPISlavePort *slave, const void *out, size_t len);
|
||||
|
||||
//! Transmit and Receive data bytes to and from the SPI Slave Port
|
||||
//! If out is NULL then 0s are transmitted, if in is NULL incoming data is not saved
|
||||
//! It is up to the caller to ensure SCS is asserted correctly
|
||||
void spi_ll_slave_burst_read_write(const SPISlavePort *slave,
|
||||
const void *out,
|
||||
void *in,
|
||||
size_t len);
|
||||
|
||||
//! Transmit and Receive data bytes to and from the SPI Slave Port (scatter gather)
|
||||
//! It is up to the caller to ensure SCS is asserted correctly
|
||||
void spi_ll_slave_burst_read_write_scatter(const SPISlavePort *slave,
|
||||
const SPIScatterGather *sc_info,
|
||||
size_t num_sg);
|
||||
|
||||
//! Reads data from the given slave port via DMA
|
||||
void spi_ll_slave_read_dma_start(const SPISlavePort *slave, void *in, size_t len,
|
||||
SPIDMACompleteHandler handler, void *context);
|
||||
|
||||
//! Stops the read DMA on the given slave port
|
||||
void spi_ll_slave_read_dma_stop(const SPISlavePort *slave);
|
||||
|
||||
//! Write data to the given slave port via DMA
|
||||
void spi_ll_slave_write_dma_start(const SPISlavePort *slave, const void *out, size_t len,
|
||||
SPIDMACompleteHandler handler, void *context);
|
||||
|
||||
//! Stops the write DMA on the given slave port
|
||||
void spi_ll_slave_write_dma_stop(const SPISlavePort *slave);
|
||||
|
||||
//! Sends and receives data via DMA on the given slave port. If out is NULL, 0s are transmitted. If
|
||||
//! in is NULL, incoming data is not saved.
|
||||
void spi_ll_slave_read_write_dma_start(const SPISlavePort *slave, const void *out, void *in,
|
||||
size_t len, SPIDMACompleteHandler handler, void *context);
|
||||
|
||||
//! Stops the read + write DMA on the given slave port
|
||||
void spi_ll_slave_read_write_dma_stop(const SPISlavePort *slave);
|
||||
|
||||
//! Checks whether a DMA operation is in progress on the given slave port
|
||||
bool spi_ll_slave_dma_in_progress(const SPISlavePort *slave);
|
||||
|
||||
//! The state of the SPI clock lines between transactions is unspecified. Some devices
|
||||
//! expect the clock to be in a certain state. This routine will drive the line low when
|
||||
//! enable is true and reconfigure it as a SPI CLK line when false
|
||||
void spi_ll_slave_drive_clock(const SPISlavePort *slave, bool enable);
|
||||
|
||||
//! Clears any errors which may be set
|
||||
void spi_ll_slave_clear_errors(const SPISlavePort *slave);
|
||||
|
||||
//! Initialize a single SPI device instance. Must be called before first use
|
||||
void spi_slave_port_init(SPISlavePort *device);
|
||||
|
||||
//! Deinitializes the SPI device
|
||||
void spi_slave_port_deinit(const SPISlavePort *slave);
|
||||
|
||||
// REVISIT:
|
||||
// This prototype is used by the roll-your-own SPI drivers.
|
||||
// It (and the definition) can go away once the new driver
|
||||
// API is adopted universally.
|
||||
uint16_t spi_find_prescaler(uint32_t bus_frequency, SpiPeriphClock periph_clock);
|
Loading…
Add table
Add a link
Reference in a new issue