If you look into SPI you will see that SPI only transfers 8 bits at a time and the arriving bits are assembled.
An Uno is an 8 bit machine.
Here is a ESP32 API function to write 8 bits with DMA and background data transfer enabled.
int fWriteSPIdata8bits( spi_device_handle_t &h, int _address, int _sendData )
{
uint8_t address = _address;
uint8_t sendData = _sendData;
esp_err_t intError;
spi_transaction_t trans_desc;
trans_desc = { };
trans_desc.addr = 0;
trans_desc.cmd = 0;
trans_desc.flags = 0;
trans_desc.length = (8 * 2); // total data bits
trans_desc.tx_buffer = txData;
trans_desc.rxlength = 0 ; // Number of bits NOT number of bytes
trans_desc.rx_buffer = NULL;
txData[0] = address & 0x7F;
txData[1] = sendData;
intError = spi_device_transmit( h, &trans_desc);
return intError;
} // void fWriteSPIdata8bits( spi_device_handle_t &h, uint8_t address, uint8_t sendData )
And here is a ESP32 SPI API function to read 16 bits with DMA and background data transfer enabled.
void fReadSPIdata16bits( spi_device_handle_t &h, int _address )
{
uint8_t address = _address;
esp_err_t intError;
spi_transaction_t trans_desc;
trans_desc = { };
trans_desc.addr = 0;
trans_desc.cmd = 0;
trans_desc.flags = 0;
trans_desc.length = (8 * 3); // total data bits
trans_desc.tx_buffer = txData;
trans_desc.rxlength = 8 * 2 ; // Number of bits NOT number of bytes
trans_desc.rx_buffer = rxData;
txData[0] = address | 0x80;
intError = spi_device_transmit( h, &trans_desc);
low = rxData[0]; high = rxData[1];
} // void fSendSPI( uint8_t count, uint8_t address, uint8_t DataToSend)
You can see an 8 bit transaction needs two buckets of 8 bit data one bucket for the device register to be read and one bucket for the 8 bit reply. You can see the 16 bit reply needs 3 8 bit buckets, 1 bucket to hold the address register and 2 buckets to hold the reply.
Your 8 bit and 16 bit and so forth and so on bit buckets should be taken care of through the library used or, if you do it yourself, the programmer.
And thrown in for extra measure. This is wrote for a NLX90393 a 20 bit device and the code SPI API code to send 20 bits with DMA and background data transfer enabled.
int fWriteSPIdata32bits( spi_device_handle_t &h, int _sendData0, int _sendData1, int _sendData2, int _sendData3 )
{
// uint8_t address = _address;
// uint8_t sendData = _sendData;
esp_err_t intError;
spi_transaction_t trans_desc;
trans_desc = { };
trans_desc.addr = 0;
trans_desc.cmd = 0;
trans_desc.flags = 0;
trans_desc.length = (8 * 4); // total data bits
trans_desc.tx_buffer = txData;
trans_desc.rxlength = 0 ; // Number of bits NOT number of bytes
trans_desc.rx_buffer = NULL;
txData[0] = (uint8_t)_sendData0; // command bits
txData[1] = (uint8_t)_sendData1; // lower bits
txData[2] = (uint8_t)_sendData2; // higher bits
txData[3] = (uint8_t)_sendData3; // address
intError = spi_device_transmit( h, &trans_desc);
return intError;
} // void fWriteSPIdata8bits( spi_device_handle_t &h, uint8_t address, uint8_t sendData )
And you can load up a device library and look at the code to see how the code author does the thing.