-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Description
General idea
A module which executes transaction and reports back once transaction is completed. Transaction consists of fixed number of operations. Manager instance has a pointer to a function which is capable of performing base operations. Transaction contains operations and data specific to that transaction.
Use cases
SPI & I2C
Transaction is a set of single direction transfers like TX+RX to read the data from a sensor. Transaction contains destination details like CS pin (SPI) or device address (I2C). Using transaction can simplify Initialization of an external device since whole configuration transfers can be combined into single transaction. Fixed transactions can be stored in ROM.
Additional considerations:
- delay between operations within a transaction shall be supported since it is often required (e.g. trigger sensor measurement, wait, read result)
- pausing between operations shall be supported. Pausing is more generic than delay thus delay may be realized with pausing feature. Pausing is required if certain condition must be met before transaction can be continued (e.g. trigger operation, wait for RDY pin, read result)
- SPI: controlling multiple pins to be able to control command/data pin or control multiple devices within single transaction
- I2C: is there a case to support multiple devices in single transaction? If so then transaction data shall contain pool of address and each message should identify which address to use.
Others
Others has been mentioned, like CAN, ADC, GPIO (e.g. bitbanging as a transaction?)
#22371 (comment)
Transactions theoretical examples:
i2c sensor initialization transaction example, where multiple transfers (mainly TXTX) are combined. Sensor driver is notified when transaction is completed or error occurs.
const struct i2c_msg msgs[] = {
I2C_MSG_TXRX(®_addr0, 1, &dev_id, 1, 0), /* read device id into dev_id variable */
I2C_MSG_TXTX(®_addr1, 1, ®_val1, 1, 0), /* write one byte to the register */
I2C_MSG_TXTX(®_addr2, 1, &buf, 4, 0), /* write 4 bytes to registers */
I2C_MSG_TXTX(®_addr3, 1, ®_val3, 1, 0) /* write one byte to the register */
};
const struct i2c_transaction transaction[] = {
.msgs = msgs,
.num_msgs = ARRAY_SIZE(msgs),
.addr = 0x44
}
trigger i2c sensor measurement and read it after certain delay. Delay is achieved by setting flag to pause transaction after first message. Transaction is resumed by the user.
const struct i2c_msg msgs[] = {
I2C_MSG_TXTX(®_addr0, 1, ®_enable, 1, I2C_MSG_FLAGS_PAUSE), /* enable and pause */
I2C_MSG_TXRX(®_addr1, 1, &value, 1, 0), /* read data */
}
const struct i2c_transaction transaction[] = {
.msgs = msgs,
.num_msgs = ARRAY_SIZE(msgs),
.addr = 0x44,
.paused_callback = pause_callback
}
void pause_callback(...)
{
k_timer_start(...)
//or busy wait if short enough - we may be in interrupt context
transaction_mngr_resume(...)
}
In similar way transactions can be defined for SPI. Flags for messages may include information about chip select actions (multiple pins can be supported).
To be considered is whether multiple configurations (addresses in i2c case) would be supported to allow interacting with multiple devices in one transaction.
Benefits
- APIs of operations used in transactions can be simplied since they need to be capable of performing only the simplest, low level operations. E.g. i2c, spi API can be limited to
async_transfer,configure. - Combination of transaction manager with queued operation manager (RFC: Queued operations manager #22494) allows for accessing single resource to perform chain of operations on that resource.
API draft
Transaction contains pointer to configuration, messages and optionally "paused" callback
struct transaction {
void *config;
void *msgs;
u16_t msg_size;
u16_t num_msgs;
transaction_paused_fn paused_fn;
}
Transaction manager shall contain operation function pointer, flags, state
Transaction is performed using call like:
int transaction_perform(struct transaction_mngr *mngr, struct transaction *ops,
transaction_cb callback, void *user_date)
Combining with queue operation manager #22494
Asynchronous operations for I2C and SPI can be achieved by combining transaction manager with queued operation manager where user schedules transactions to be executed by queued operations manager.
Other use cases
TBD. Dear reader, transaction manager is proposed because of SPI, I2C case. If you know other use case which fits into that and have additional requirements please add them.
Last but not least - naming
working name is transaction manager, are there any other candidates? sequence manager? sequencer? burst manager?
Metadata
Metadata
Assignees
Labels
Type
Projects
Status