mirror of
https://github.com/eclipse/upm.git
synced 2025-03-18 22:47:28 +03:00
526 lines
20 KiB
C
526 lines
20 KiB
C
![]() |
/*
|
||
|
* Author: Jon Trulson <jtrulson@ics.com>
|
||
|
* Copyright (c) 2016 Intel Corporation.
|
||
|
*
|
||
|
* 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 <stdint.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <upm.h>
|
||
|
|
||
|
#include <mraa/i2c.h>
|
||
|
#include <mraa/spi.h>
|
||
|
#include <mraa/gpio.h>
|
||
|
|
||
|
#include <mcp2515_regs.h>
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* @file mcp2515
|
||
|
* @library mcp2515
|
||
|
* @brief C API for the MCP2515 CAN bus controller
|
||
|
*
|
||
|
* @include mcp2515.c
|
||
|
* @include mcp2515_regs.c
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Device context
|
||
|
*/
|
||
|
typedef struct _mcp2515_context {
|
||
|
mraa_spi_context spi;
|
||
|
|
||
|
// CS pin, if we are using one
|
||
|
mraa_gpio_context gpio;
|
||
|
|
||
|
// interrupt, if enabled
|
||
|
mraa_gpio_context intr;
|
||
|
} *mcp2515_context;
|
||
|
|
||
|
/**
|
||
|
* MCP2515 initializer
|
||
|
*
|
||
|
* @param bus spi bus to use
|
||
|
* @param cs_pin The GPIO pin to use for Chip Select (CS). Pass
|
||
|
* pass -1 if your CS is handled automatically by your SPI
|
||
|
* implementation (Edison).
|
||
|
* @return an initialized device context on success, NULL on error.
|
||
|
*/
|
||
|
mcp2515_context mcp2515_init(int bus, int cs_pin);
|
||
|
|
||
|
/**
|
||
|
* MCP2515 close
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
*/
|
||
|
void mcp2515_close(mcp2515_context dev);
|
||
|
|
||
|
/**
|
||
|
* Reset the device.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_reset(const mcp2515_context dev);
|
||
|
|
||
|
/**
|
||
|
* Set the operating mode of the device. After initialization
|
||
|
* (mcp2515_init()), the device mode will be set to NORMAL. Note
|
||
|
* that some operations require the device to be placed into CONFIG
|
||
|
* mode. This function will wait until the selected mode has been
|
||
|
* entered.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param opmode One of the MCP2515_OPMODE_T values.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_set_opmode(const mcp2515_context dev,
|
||
|
MCP2515_OPMODE_T opmode);
|
||
|
|
||
|
/**
|
||
|
* Set the baud rate of the CAN bus. All devices on a given CAN
|
||
|
* bus must be operating at the correct speed. The device must be
|
||
|
* switched into CONFIG mode bofore this function will have any
|
||
|
* effect. On initialization (mcp2515_init()), the default CAN
|
||
|
* bus speed will be set to 50Kbps.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param speed One of the MCP2515_SPEED_T values.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_set_speed(const mcp2515_context dev,
|
||
|
MCP2515_SPEED_T speed);
|
||
|
|
||
|
/**
|
||
|
* Load a transmit buffer with the id, payload, and other
|
||
|
* information. This function does not actually transmit the
|
||
|
* buffer. There are 3 TX buffers available. The buffer must be
|
||
|
* free (ie: not awaiting transmit) before it can be loaded. Once
|
||
|
* a TX buffer has been successfully loaded, it can be transmitted
|
||
|
* with the mcp2515_transmit_buffer() function.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param bufnum The buffer to load. One of the
|
||
|
* MCP2515_TX_BUFFER_T values.
|
||
|
* @param id The integer representation of the CAN bus ID.
|
||
|
* @param ext True if the ID is an extended identifier, false otherwise.
|
||
|
* @param rtr True if this is a Remote Transfer Request, false otherwise.
|
||
|
* @param payload A pointer to an array of bytes that make up the
|
||
|
* payload to send.
|
||
|
* @param len The length of the payload. The length is limited to
|
||
|
* 8.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_load_tx_buffer(const mcp2515_context dev,
|
||
|
MCP2515_TX_BUFFER_T bufnum,
|
||
|
int id, bool ext, bool rtr,
|
||
|
uint8_t *payload, int len);
|
||
|
|
||
|
/**
|
||
|
* Transmit a buffer already loaded by mcp2515_load_tx_buffer().
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param bufnum The buffer to transmit. One of the
|
||
|
* MCP2515_TX_BUFFER_T values.
|
||
|
* @param wait True if the function should wait until transmission
|
||
|
* is complete before returning, false otherwise.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_transmit_buffer(const mcp2515_context dev,
|
||
|
MCP2515_TX_BUFFER_T bufnum,
|
||
|
bool wait);
|
||
|
|
||
|
/**
|
||
|
* Determine whether a TX buffer is available for use or not. A TX
|
||
|
* buffer is unavailable if a transmit request is pending on it,
|
||
|
* but transmission has not yet completed.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param bufnum The buffer to check. One of the
|
||
|
* MCP2515_TX_BUFFER_T values.
|
||
|
* @return True if the buffer is availabe, false otherwise.
|
||
|
*/
|
||
|
bool mcp2515_tx_buffer_is_free(const mcp2515_context dev,
|
||
|
MCP2515_TX_BUFFER_T bufnum);
|
||
|
|
||
|
/**
|
||
|
* Find a free TX buffer and return it.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @return One of the MCP2515_TX_BUFFER_T values. If no buffers
|
||
|
* are available, MCP2515_TX_NO_BUFFERS will be returned.
|
||
|
*/
|
||
|
MCP2515_TX_BUFFER_T mcp2515_find_free_tx_buffer(const mcp2515_context dev);
|
||
|
|
||
|
/**
|
||
|
* Set the transmit priority of a TX buffer. Higher priority
|
||
|
* buffers are always transmitted before lower priority buffers.
|
||
|
* This function can be called on a buffer at any time prior to
|
||
|
* actual transmission.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param bufnum The buffer to set priority for. One of the
|
||
|
* MCP2515_TX_BUFFER_T values.
|
||
|
* @param priority The priority to set for the buffer. One of the
|
||
|
* MCP2515_TXP_T values.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_set_tx_buffer_priority(const mcp2515_context dev,
|
||
|
MCP2515_TX_BUFFER_T bufnum,
|
||
|
MCP2515_TXP_T priority);
|
||
|
|
||
|
/**
|
||
|
* Abort a transmission that has been queued, but not yet
|
||
|
* completed. This will also free up the TX buffer for future
|
||
|
* use. Note, if you abort a transmission, but transmission has
|
||
|
* already started, this call will have no effect, and the buffer
|
||
|
* will complete transmission.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param bufnum The buffer to abort. One of the
|
||
|
* MCP2515_TX_BUFFER_T values.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_abort_tx(const mcp2515_context dev,
|
||
|
MCP2515_TX_BUFFER_T bufnum);
|
||
|
|
||
|
/**
|
||
|
* Set the mode for an RX buffer. The mode specifies, at a high
|
||
|
* level, what packets should be captured from the bus and placed
|
||
|
* into an RX buffer. See the datasheet for details, but the
|
||
|
* default, MCP2515_RXMODE_ANY_FILTER, should be sufficient in
|
||
|
* most cases. It is also possible to use this to restrict the
|
||
|
* types of CAN ids accepted (extended only, standard only) as
|
||
|
* well as a debug ANY_NOFILTER mode.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param bufnum The buffer to set the mode for. One of the
|
||
|
* MCP2515_RX_BUFFER_T values.
|
||
|
* @param rxm The mode to set. One of the MCP2515_RXMODE_T values.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_set_rx_buffer_mode(const mcp2515_context dev,
|
||
|
MCP2515_RX_BUFFER_T bufnum,
|
||
|
MCP2515_RXMODE_T rxm);
|
||
|
|
||
|
/**
|
||
|
* Return a bitmask indicating which of the 2 RX buffers have
|
||
|
* packets waiting in them. This can be 0 (no packets), 1(RXB0),
|
||
|
* 2(RXB1), or 3 (RXB0 and RXB1). This information is retrieved
|
||
|
* using the MCP2515_CMD_RX_STATUS command.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @return A bitmask indicating which RX buffers (if any) have
|
||
|
* packets in them. One of the MCP2515_RXMSG_T values.
|
||
|
*/
|
||
|
MCP2515_RXMSG_T mcp2515_rx_status_msgs(const mcp2515_context dev);
|
||
|
|
||
|
/**
|
||
|
* Return the message type present in one of the RX buffers. RXB0
|
||
|
* has the highest priority, so if both RX buffers are full, this
|
||
|
* function will only return data for the packet in RXB0. This
|
||
|
* information is retrieved using the MCP2515_CMD_RX_STATUS
|
||
|
* command.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @return One of the MCP2515_MSGTYPE_T values.
|
||
|
*/
|
||
|
MCP2515_MSGTYPE_T mcp2515_rx_status_msg_type(const mcp2515_context dev);
|
||
|
|
||
|
/**
|
||
|
* Return the filter that matched an RX buffer. RXB0 has the
|
||
|
* highest priority, so if both RX buffers are full, this function
|
||
|
* will only return data for the packet in RXB0. This information
|
||
|
* is retrieved using the MCP2515_CMD_RX_STATUS command.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @return One of the MCP2515_FILTERMATCH_T values.
|
||
|
*/
|
||
|
MCP2515_FILTERMATCH_T mcp2515_rx_status_filtermatch(const mcp2515_context dev);
|
||
|
|
||
|
/**
|
||
|
* This function retrieves a message from the specified RX buffer.
|
||
|
* The message (MCP2515_MSG_T) contains all of the data in the
|
||
|
* packet, including id, rtr, ext, payload and payload length. In
|
||
|
* addition, after retrieving the message, the RX buffer is freed
|
||
|
* to receive further data from the CAN bus.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param bufnum The buffer to retrieve. One of the
|
||
|
* MCP2515_RX_BUFFER_T values.
|
||
|
* @param msg A pointer to a MCP2515_MSG_T, which will be filled
|
||
|
* with the decoded contents of the RX buffer.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_get_rx_msg(const mcp2515_context dev,
|
||
|
MCP2515_RX_BUFFER_T bufnum,
|
||
|
MCP2515_MSG_T *msg);
|
||
|
|
||
|
/**
|
||
|
* This is a utility function that accepts a MCP2515_MSG_T and
|
||
|
* prints out it's decoded contents. This is of primary
|
||
|
* importance for debugging, and to simplify the examples
|
||
|
* somewhat.
|
||
|
*
|
||
|
* The output will look similar to:
|
||
|
*
|
||
|
* id 00000000 ext 0 rtr 0 filt 0 len 8
|
||
|
* payload: 0xc8 0x01 0x02 0x03 0x04 0x05 0x06 0x07
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param msg A pointer to a MCP2515_MSG_T containing the data to
|
||
|
* be printed out.
|
||
|
*/
|
||
|
void mcp2515_print_msg(const mcp2515_context dev, MCP2515_MSG_T *msg);
|
||
|
|
||
|
/**
|
||
|
* Installs an interrupt service routine (ISR) to be called when
|
||
|
* an interrupt occurs.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param pin GPIO pin to use as the interrupt pin.
|
||
|
* @param fptr Pointer to a function to be called on interrupt.
|
||
|
* @param arg Pointer to an object to be supplied as an
|
||
|
* argument to the ISR.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_install_isr(const mcp2515_context dev, int pin,
|
||
|
void (*isr)(void *), void *arg);
|
||
|
|
||
|
/**
|
||
|
* Uninstalls the previously installed ISR
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
*/
|
||
|
void mcp2515_uninstall_isr(const mcp2515_context dev);
|
||
|
|
||
|
/**
|
||
|
* Set the interrupt enables register.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param enables A bitmask of interrupts to enable from
|
||
|
* MCP2515_CANINT_BITS_T.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_set_intr_enables(const mcp2515_context dev,
|
||
|
uint8_t enables);
|
||
|
|
||
|
/**
|
||
|
* Retrieve the interrupt flags register.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param flags A pointer to a bitmask that will be filled with
|
||
|
* values from MCP2515_CANINT_BITS_T, indicating which interrupt
|
||
|
* flags are set.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_get_intr_flags(const mcp2515_context dev,
|
||
|
uint8_t *flags);
|
||
|
|
||
|
/**
|
||
|
* This function allows you to set specific interrupt flags. If
|
||
|
* the corresponding interrupt enable is set, an interrupt will be
|
||
|
* generated.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param flags A bitmask of interrupt flags to set, from
|
||
|
* MCP2515_CANINT_BITS_T values.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_set_intr_flags(const mcp2515_context dev,
|
||
|
uint8_t flags);
|
||
|
|
||
|
/**
|
||
|
* This function allows you to clear specific interrupt flags.
|
||
|
* See the datasheet. Some flags cannot be cleared until the
|
||
|
* underlying cause has been corrected.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param flags A bitmask of interrupt flags to clear, from
|
||
|
* MCP2515_CANINT_BITS_T values.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_clear_intr_flags(const mcp2515_context dev,
|
||
|
uint8_t flags);
|
||
|
|
||
|
/**
|
||
|
* Retrieve the error flags register
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param flags A pointer to a uint8_t that will hold the flags
|
||
|
* with values from MCP2515_EFLG_BITS_T.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_get_error_flags(const mcp2515_context dev,
|
||
|
uint8_t *flags);
|
||
|
|
||
|
/**
|
||
|
* Clear error flags. Note, some flags cannot be cleared
|
||
|
* until the underlying issues is resolved.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param flags A bitmask of values from MCP2515_EFLG_BITS_T
|
||
|
* specifying the flags to clear.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_clear_error_flags(const mcp2515_context dev,
|
||
|
uint8_t flags);
|
||
|
|
||
|
/**
|
||
|
* This function allows you to set one of the 6 RX filters
|
||
|
* available. Filters 0 and 1 are for RXB0 only, while filters
|
||
|
* 2-5 are for RXB1. See the datasheet for details on how these
|
||
|
* filters (along with the masks) are used to select candidate CAN
|
||
|
* bus data for retrieval from the CAN bus.
|
||
|
*
|
||
|
* These can only be set when the device is in CONFIG mode.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param filter One of the 6 MCP2515_RX_FILTER_T values.
|
||
|
* @param ext True if the id is extended, false for standard.
|
||
|
* @param id Integer representation of a CAN bus ID.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_set_filter(const mcp2515_context dev,
|
||
|
MCP2515_RX_FILTER_T filter, bool ext,
|
||
|
int id);
|
||
|
|
||
|
/**
|
||
|
* This function allows you to set one of the 2 RX masks. Mask 0
|
||
|
* is for RXB0, mask 1 is for RXB1. The masks specify which bits
|
||
|
* in the filters are used for matching CAN bus data. See the
|
||
|
* datasheet for details on how these masks (along with the
|
||
|
* filters) are used to select candidate CAN bus data for retrieval
|
||
|
* from the CAN bus.
|
||
|
*
|
||
|
* These can only be set when the device is in CONFIG mode.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param mask One of the 2 MCP2515_RX_MASK_T values.
|
||
|
* @param ext True if the id is extended, false for standard.
|
||
|
* @param id Integer representation of a CAN bus ID.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_set_mask(const mcp2515_context dev,
|
||
|
MCP2515_RX_MASK_T mask, bool ext, int id);
|
||
|
|
||
|
/**
|
||
|
* Perform a bus read. This function is exposed here for those
|
||
|
* users wishing to perform their own low level accesses. This is
|
||
|
* a low level function, and should not be used unless you know
|
||
|
* what you are doing.
|
||
|
*
|
||
|
* @param dev Device context.
|
||
|
* @param cmd The command to send.
|
||
|
* @param args An array of arguments, or NULL.
|
||
|
* @param arglen The number of args, or 0.
|
||
|
* @param data A pointer to a buffer in which data will be read into.
|
||
|
* @param len The number of bytes to read.
|
||
|
* @return UPM result.
|
||
|
*/
|
||
|
upm_result_t mcp2515_bus_read(const mcp2515_context dev, uint8_t cmd,
|
||
|
uint8_t *args, unsigned int arglen,
|
||
|
uint8_t *data, uint8_t len);
|
||
|
|
||
|
/**
|
||
|
* Perform a bus write. This function is exposed here for those
|
||
|
* users wishing to perform their own low level accesses. This is
|
||
|
* a low level function, and should not be used unless you know
|
||
|
* what you are doing.
|
||
|
*
|
||
|
* @param dev Device context
|
||
|
* @param cmd The command to send.
|
||
|
* @param data A pointer to a buffer containing data to write.
|
||
|
* @param len The number of bytes to write.
|
||
|
* @return UPM Status
|
||
|
*/
|
||
|
upm_result_t mcp2515_bus_write(const mcp2515_context dev, uint8_t cmd,
|
||
|
uint8_t *data, uint8_t len);
|
||
|
|
||
|
/**
|
||
|
* Write to a specific register. This function is exposed here
|
||
|
* for those users wishing to perform their own low level
|
||
|
* accesses. This is a low level function, and should not be used
|
||
|
* unless you know what you are doing.
|
||
|
*
|
||
|
* @param dev Device context
|
||
|
* @param reg The register to write to.
|
||
|
* @param value The byte to write.
|
||
|
* @return UPM Status
|
||
|
*/
|
||
|
upm_result_t mcp2515_write_reg(const mcp2515_context dev, uint8_t reg,
|
||
|
uint8_t value);
|
||
|
|
||
|
/**
|
||
|
* Write to multiple consecutive registers. This function is
|
||
|
* exposed here for those users wishing to perform their own low
|
||
|
* level accesses. This is a low level function, and should not
|
||
|
* be used unless you know what you are doing.
|
||
|
*
|
||
|
* @param dev Device context
|
||
|
* @param reg The register to start writing to.
|
||
|
* @param buffer A pointer to an array of bytes to write.
|
||
|
* @param len The number of bytes to write.
|
||
|
* @return UPM Status
|
||
|
*/
|
||
|
upm_result_t mcp2515_write_regs(const mcp2515_context dev, uint8_t reg,
|
||
|
uint8_t *buffer, int len);
|
||
|
|
||
|
/**
|
||
|
* Read a register. This function is exposed here for those users
|
||
|
* wishing to perform their own low level accesses. This is a low
|
||
|
* level function, and should not be used unless you know what you
|
||
|
* are doing.
|
||
|
*
|
||
|
* @param dev Device context
|
||
|
* @param reg The register to read.
|
||
|
* @param buffer A pointer to a a byte where the value will be placed.
|
||
|
* @return UPM Status
|
||
|
*/
|
||
|
upm_result_t mcp2515_read_reg(const mcp2515_context dev, uint8_t reg,
|
||
|
uint8_t *value);
|
||
|
|
||
|
/**
|
||
|
* Perform a bit modify operation on a register. Only certain
|
||
|
* registers support this method of access - check the datasheet.
|
||
|
* This function is exposed here for those users wishing to
|
||
|
* perform their own low level accesses. This is a low level
|
||
|
* function, and should not be used unless you know what you are
|
||
|
* doing.
|
||
|
*
|
||
|
* @param dev Device context
|
||
|
* @param addr The address of the register to access.
|
||
|
* @param mask A bitmask used to mask off value bits.
|
||
|
* @param value The value to write (bits masked by mask).
|
||
|
* @return UPM Status
|
||
|
*/
|
||
|
upm_result_t mcp2515_bit_modify(const mcp2515_context dev, uint8_t addr,
|
||
|
uint8_t mask, uint8_t value);
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|