/** @ingroup spi_function @brief Setup and initialize new SPI instance. Setup and create SPI instance according to parameters. @note This must be called exactly once per new SPI instance. @note Slave mode is not implemented!!! @return handle to the SPI instance created. Should be used as parameter to the send() functions. @param mode SPI_MODE_MASTER: Master mode\n SPI_MODE_SLAVE: Slave Mode. @param clock_divider defines the SPI clock divider. Use SPI_CLOCK_DIVIDER_xx as parameter. @param spi_mode defines the SPI mode to use [0..3]. These are the standard modes specified by Motorola\n |spi_mode | CPOL | CPHA |Clock Behavior| |:---: |:----:|:----:|:----------| | 0 | 0 | 0 |Low when idle, samples on leading edge| | 1 | 0 | 1 |Low when idle, samples on trailing edge| | 2 | 1 | 0 |High when idle, samples on leading edge| | 3 | 1 | 1 |High when idle, samples on trailing edge| @param data_order SPI_DATA_ORDER_LSB: LSB transmitted first.\n SPI_DATA_ORDER_MSB: MSB transmitted first. @param *cs_port port register for the CS pin - Ex. PORTB. @param *cs_pin that is connected to the slaves CS - Ex. PB6. @param cs_active_level 0: CS active when low.\n 1: CS active when high. @param *rx_buf 0: No receive buffer used, means no data vil be received from slave.\n pointer to the receive buffer structure to store received data in. @param *tx_buf 0: No trasmit buffer used, means that only one byte can be transmitted at the time.\n pointer to the transmit buffer structure to store transmit data in. 0: no tx buffer wanted. @param *call_back pointer to a call back function that will be called when the driver receives a byte from the SPI bus. The function should have the following signature:\n @code void handler_name(spi_p spi_instance, uint8_t rx_byte) @endcode 0: no call back function will be called. @note If SPI_USE_BUFFER in spi_iha_config.h is 0 then the pointers rx_buf and tx_buf are ignored. */ spi_p spi_new_instance(uint8_t mode, int8_t clock_divider, uint8_t spi_mode, uint8_t data_order, volatile uint8_t *cs_port, uint8_t cs_pin, uint8_t cs_active_level, buffer_struct_t *rx_buf, buffer_struct_t *tx_buf, void(*call_back )(spi_p spi, uint8_t last_rx_byte)) { if (!_initialised) { _spi_init(); _initialised = 1; } spi_p _spi = malloc(sizeof *_spi); _spi->_cs_port = cs_port; _spi->_cs_pin = cs_pin; // Set CS pin to output *(cs_port-1) |= _BV(cs_pin); _spi->_cs_active_level = cs_active_level; _spi->_SPCR = mode | _prescaler_mask[clock_divider] |(spi_mode<<2) | data_order; if (clock_divider > 3) { _spi->_SPSR = _BV(SPI2X); } #if SPI_USE_BUFFER == 1 _spi->_tx_buf = tx_buf; _spi->_rx_buf = rx_buf; #endif _spi->_call_back = call_back; // Critical section { // disable interrupt uint8_t c_sreg = SREG; cli(); spi_p current_instance = _this; _this = _spi; _set_cs(CS_INACTIVE); _this = current_instance; // restore interrupt state SREG = c_sreg; } return _spi; }