1 /**
2  * \file
3  *
4  * \brief SAM Serial Peripheral Interface Driver
5  *
6  * Copyright (c) 2013-2016 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 #include "spi_interrupt.h"
47 
48 /**
49  * \internal
50  *
51  * Dummy byte to send when reading in master mode.
52  */
53 uint16_t dummy_write;
54 
55 /**
56  * \internal
57  * Starts transceive of buffers with a given length
58  *
59  * \param[in]  module   Pointer to SPI software instance struct
60  * \param[in]  rx_data  Pointer to data to be received
61  * \param[in]  tx_data  Pointer to data to be transmitted
62  * \param[in]  length   Length of data buffer
63  *
64  */
_spi_transceive_buffer(struct spi_module * const module,uint8_t * tx_data,uint8_t * rx_data,uint16_t length)65 static void _spi_transceive_buffer(
66 		struct spi_module *const module,
67 		uint8_t *tx_data,
68 		uint8_t *rx_data,
69 		uint16_t length)
70 {
71 	Assert(module);
72 	Assert(tx_data);
73 
74 	/* Write parameters to the device instance */
75 	module->remaining_tx_buffer_length = length;
76 	module->remaining_rx_buffer_length = length;
77 	module->rx_buffer_ptr = rx_data;
78 	module->tx_buffer_ptr = tx_data;
79 	module->status = STATUS_BUSY;
80 
81 	module->dir = SPI_DIRECTION_BOTH;
82 
83 	/* Get a pointer to the hardware module instance */
84 	SercomSpi *const hw = &(module->hw->SPI);
85 
86 	/* Enable the Data Register Empty and RX Complete Interrupt */
87 	hw->INTENSET.reg = (SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY |
88 			SPI_INTERRUPT_FLAG_RX_COMPLETE);
89 
90 #  if CONF_SPI_SLAVE_ENABLE == true
91 	if (module->mode == SPI_MODE_SLAVE) {
92 		/* Clear TXC flag if set */
93 		hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE;
94 		/* Enable transmit complete interrupt for slave */
95 		hw->INTENSET.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE;
96 	}
97 #  endif
98 }
99 
100 /**
101  * \internal
102  * Starts write of a buffer with a given length
103  *
104  * \param[in]  module   Pointer to SPI software instance struct
105  * \param[in]  tx_data  Pointer to data to be transmitted
106  * \param[in]  length   Length of data buffer
107  *
108  */
_spi_write_buffer(struct spi_module * const module,uint8_t * tx_data,uint16_t length)109 static void _spi_write_buffer(
110 		struct spi_module *const module,
111 		uint8_t *tx_data,
112 		uint16_t length)
113 {
114 	Assert(module);
115 	Assert(tx_data);
116 
117 	/* Write parameters to the device instance */
118 	module->remaining_tx_buffer_length = length;
119 	module->remaining_dummy_buffer_length = length;
120 	module->tx_buffer_ptr = tx_data;
121 	module->status = STATUS_BUSY;
122 
123 	module->dir = SPI_DIRECTION_WRITE;
124 
125 	/* Get a pointer to the hardware module instance */
126 	SercomSpi *const hw = &(module->hw->SPI);
127 
128 #  if CONF_SPI_SLAVE_ENABLE == true
129 	if (module->mode == SPI_MODE_SLAVE) {
130 		/* Clear TXC flag if set */
131 		hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE;
132 		/* Enable transmit complete interrupt for slave */
133 		hw->INTENSET.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE;
134 	}
135 #  endif
136 
137 	if (module->receiver_enabled) {
138 		/* Enable the Data Register Empty and RX Complete interrupt */
139 		hw->INTENSET.reg = (SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY |
140 				SPI_INTERRUPT_FLAG_RX_COMPLETE);
141 	} else {
142 		/* Enable the Data Register Empty interrupt */
143 		hw->INTENSET.reg = SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY;
144 	}
145 }
146 
147 /**
148  * \internal
149  * Setup SPI to read a buffer with a given length
150  *
151  * \param[in]  module   Pointer to SPI software instance struct
152  * \param[in]  rx_data  Pointer to data to be received
153  * \param[in]  length   Length of data buffer
154  *
155  */
_spi_read_buffer(struct spi_module * const module,uint8_t * rx_data,uint16_t length)156 static void _spi_read_buffer(
157 		struct spi_module *const module,
158 		uint8_t *rx_data,
159 		uint16_t length)
160 {
161 	Assert(module);
162 	Assert(rx_data);
163 
164 	uint8_t tmp_intenset = 0;
165 
166 	/* Set length for the buffer and the pointer, and let
167 	 * the interrupt handler do the rest */
168 	module->remaining_rx_buffer_length = length;
169 	module->remaining_dummy_buffer_length = length;
170 	module->rx_buffer_ptr = rx_data;
171 	module->status = STATUS_BUSY;
172 
173 	module->dir = SPI_DIRECTION_READ;
174 
175 	/* Get a pointer to the hardware module instance */
176 	SercomSpi *const hw = &(module->hw->SPI);
177 
178 	/* Enable the RX Complete Interrupt */
179 	tmp_intenset = SPI_INTERRUPT_FLAG_RX_COMPLETE;
180 
181 #  if CONF_SPI_MASTER_ENABLE == true
182 	if (module->mode == SPI_MODE_MASTER && module->dir == SPI_DIRECTION_READ) {
183 		/* Enable Data Register Empty interrupt for master */
184 		tmp_intenset |= SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY;
185 	}
186 #  endif
187 #  if CONF_SPI_SLAVE_ENABLE == true
188 	if (module->mode == SPI_MODE_SLAVE) {
189 		/* Clear TXC flag if set */
190 		hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE;
191 		/* Enable transmit complete interrupt for slave */
192 		tmp_intenset |= SPI_INTERRUPT_FLAG_TX_COMPLETE;
193 
194 		/* Workaround for SSL flag enable */
195 #ifdef FEATURE_SPI_SLAVE_SELECT_LOW_DETECT
196 		/* Clear SSL flag if set */
197 		hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_SLAVE_SELECT_LOW;
198 		/* Enable Slave Select Low Interrupt for slave */
199 		tmp_intenset |= SPI_INTERRUPT_FLAG_SLAVE_SELECT_LOW;
200 #endif
201 	}
202 #  endif
203 
204 	/* Enable all interrupts simultaneously */
205 	hw->INTENSET.reg = tmp_intenset;
206 }
207 
208 /**
209  * \brief Registers a SPI callback function
210  *
211  * Registers a callback function which is implemented by the user.
212  *
213  * \note The callback must be enabled by \ref spi_enable_callback, in order
214  *       for the interrupt handler to call it when the conditions for the
215  *       callback type are met.
216  *
217  * \param[in]  module         Pointer to USART software instance struct
218  * \param[in]  callback_func  Pointer to callback function
219  * \param[in]  callback_type  Callback type given by an enum
220  *
221  */
spi_register_callback(struct spi_module * const module,spi_callback_t callback_func,enum spi_callback callback_type)222 void spi_register_callback(
223 		struct spi_module *const module,
224 		spi_callback_t callback_func,
225 		enum spi_callback callback_type)
226 {
227 	/* Sanity check arguments */
228 	Assert(module);
229 	Assert(callback_func);
230 
231 	/* Register callback function */
232 	module->callback[callback_type] = callback_func;
233 
234 	/* Set the bit corresponding to the callback_type */
235 	module->registered_callback |= (1 << callback_type);
236 }
237 
238 /**
239  * \brief Unregisters a SPI callback function
240  *
241  * Unregisters a callback function which is implemented by the user.
242  *
243  * \param[in] module         Pointer to SPI software instance struct
244  * \param[in] callback_type  Callback type given by an enum
245  *
246  */
spi_unregister_callback(struct spi_module * const module,enum spi_callback callback_type)247 void spi_unregister_callback(
248 		struct spi_module *const module,
249 		enum spi_callback callback_type)
250 {
251 	/* Sanity check arguments */
252 	Assert(module);
253 
254 	/* Unregister callback function */
255 	module->callback[callback_type] = NULL;
256 
257 	/* Clear the bit corresponding to the callback_type */
258 	module->registered_callback &= ~(1 << callback_type);
259 }
260 
261 /**
262  * \brief Asynchronous buffer write
263  *
264  * Sets up the driver to write to the SPI from a given buffer. If registered
265  * and enabled, a callback function will be called when the write is finished.
266  *
267  * \param[in]  module   Pointer to SPI software instance struct
268  * \param[out] tx_data  Pointer to data buffer to receive
269  * \param[in]  length   Data buffer length
270  *
271  * \returns Status of the write request operation.
272  * \retval STATUS_OK               If the operation completed successfully
273  * \retval STATUS_ERR_BUSY         If the SPI was already busy with a write
274  *                                 operation
275  * \retval STATUS_ERR_INVALID_ARG  If requested write length was zero
276  */
spi_write_buffer_job(struct spi_module * const module,uint8_t * tx_data,uint16_t length)277 enum status_code spi_write_buffer_job(
278 		struct spi_module *const module,
279 		uint8_t *tx_data,
280 		uint16_t length)
281 {
282 	Assert(module);
283 	Assert(tx_data);
284 
285 	if (length == 0) {
286 		return STATUS_ERR_INVALID_ARG;
287 	}
288 
289 	/* Check if the SPI is busy transmitting or slave waiting for TXC*/
290 	if (module->status == STATUS_BUSY) {
291 		return STATUS_BUSY;
292 	}
293 
294 	/* Issue internal write */
295 	_spi_write_buffer(module, tx_data, length);
296 
297 	return STATUS_OK;
298 }
299 
300 /**
301  * \brief Asynchronous buffer read
302  *
303  * Sets up the driver to read from the SPI to a given buffer. If registered
304  * and enabled, a callback function will be called when the read is finished.
305  *
306  * \note If address matching is enabled for the slave, the first character
307  *       received and placed in the RX buffer will be the address.
308  *
309  * \param[in]  module   Pointer to SPI software instance struct
310  * \param[out] rx_data  Pointer to data buffer to receive
311  * \param[in]  length   Data buffer length
312  * \param[in]  dummy    Dummy character to send when reading in master mode
313  *
314  * \returns Status of the operation.
315  * \retval  STATUS_OK               If the operation completed successfully
316  * \retval  STATUS_ERR_BUSY         If the SPI was already busy with a read
317  *                                  operation
318  * \retval  STATUS_ERR_DENIED       If the receiver is not enabled
319  * \retval  STATUS_ERR_INVALID_ARG  If requested read length was zero
320  */
spi_read_buffer_job(struct spi_module * const module,uint8_t * rx_data,uint16_t length,uint16_t dummy)321 enum status_code spi_read_buffer_job(
322 		struct spi_module *const module,
323 		uint8_t *rx_data,
324 		uint16_t length,
325 		uint16_t dummy)
326 {
327 	/* Sanity check arguments */
328 	Assert(module);
329 	Assert(rx_data);
330 
331 	if (length == 0) {
332 		return STATUS_ERR_INVALID_ARG;
333 	}
334 
335 	if (!(module->receiver_enabled)) {
336 		return STATUS_ERR_DENIED;
337 	}
338 
339 	/* Check if the SPI is busy transmitting or slave waiting for TXC*/
340 	if (module->status == STATUS_BUSY) {
341 		return STATUS_BUSY;
342 	}
343 
344 	dummy_write = dummy;
345 	/* Issue internal read */
346 	_spi_read_buffer(module, rx_data, length);
347 	return STATUS_OK;
348 }
349 
350 /**
351  * \brief Asynchronous buffer write and read
352  *
353  * Sets up the driver to write and read to and from given buffers. If registered
354  * and enabled, a callback function will be called when the transfer is finished.
355  *
356  * \note If address matching is enabled for the slave, the first character
357  *       received and placed in the RX buffer will be the address.
358  *
359  * \param[in]  module   Pointer to SPI software instance struct
360  * \param[in] tx_data   Pointer to data buffer to send
361  * \param[out] rx_data  Pointer to data buffer to receive
362  * \param[in]  length   Data buffer length
363  *
364  * \returns Status of the operation.
365  * \retval  STATUS_OK               If the operation completed successfully
366  * \retval  STATUS_ERR_BUSY         If the SPI was already busy with a read
367  *                                  operation
368  * \retval  STATUS_ERR_DENIED       If the receiver is not enabled
369  * \retval  STATUS_ERR_INVALID_ARG  If requested read length was zero
370  */
spi_transceive_buffer_job(struct spi_module * const module,uint8_t * tx_data,uint8_t * rx_data,uint16_t length)371 enum status_code spi_transceive_buffer_job(
372 		struct spi_module *const module,
373 		uint8_t *tx_data,
374 		uint8_t *rx_data,
375 		uint16_t length)
376 {
377 	/* Sanity check arguments */
378 	Assert(module);
379 	Assert(rx_data);
380 
381 	if (length == 0) {
382 		return STATUS_ERR_INVALID_ARG;
383 	}
384 
385 	if (!(module->receiver_enabled)) {
386 		return STATUS_ERR_DENIED;
387 	}
388 
389 	/* Check if the SPI is busy transmitting or slave waiting for TXC*/
390 	if (module->status == STATUS_BUSY) {
391 		return STATUS_BUSY;
392 	}
393 
394 	/* Issue internal transceive */
395 	_spi_transceive_buffer(module, tx_data, rx_data, length);
396 
397 	return STATUS_OK;
398 }
399 /**
400  * \brief Aborts an ongoing job
401  *
402  * This function will abort the specified job type.
403  *
404  * \param[in]  module    Pointer to SPI software instance struct
405  */
spi_abort_job(struct spi_module * const module)406 void spi_abort_job(
407 		struct spi_module *const module)
408 {
409 	/* Pointer to the hardware module instance */
410 	SercomSpi *const spi_hw
411 		= &(module->hw->SPI);
412 
413 	/* Abort ongoing job */
414 
415 	/* Disable interrupts */
416 	spi_hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_RX_COMPLETE |
417 			SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY |
418 			SPI_INTERRUPT_FLAG_TX_COMPLETE;
419 
420 	module->status = STATUS_ABORTED;
421 	module->remaining_rx_buffer_length = 0;
422 	module->remaining_dummy_buffer_length = 0;
423 	module->remaining_tx_buffer_length = 0;
424 
425 	module->dir = SPI_DIRECTION_IDLE;
426 }
427 
428 #  if CONF_SPI_SLAVE_ENABLE == true || CONF_SPI_MASTER_ENABLE == true
429 /**
430  * \internal
431  * Writes a character from the TX buffer to the Data register.
432  *
433  * \param[in,out]  module  Pointer to SPI software instance struct
434  */
_spi_write(struct spi_module * const module)435 static void _spi_write(
436 		struct spi_module *const module)
437 {
438 	/* Pointer to the hardware module instance */
439 	SercomSpi *const spi_hw = &(module->hw->SPI);
440 
441 	/* Write value will be at least 8-bits long */
442 	uint16_t data_to_send = *(module->tx_buffer_ptr);
443 	/* Increment 8-bit pointer */
444 	(module->tx_buffer_ptr)++;
445 
446 	if (module->character_size == SPI_CHARACTER_SIZE_9BIT) {
447 		data_to_send |= ((*(module->tx_buffer_ptr)) << 8);
448 		/* Increment 8-bit pointer */
449 		(module->tx_buffer_ptr)++;
450 	}
451 
452 	/* Write the data to send*/
453 	spi_hw->DATA.reg = data_to_send & SERCOM_SPI_DATA_MASK;
454 
455 	/* Decrement remaining buffer length */
456 	(module->remaining_tx_buffer_length)--;
457 }
458 #  endif
459 
460 #  if CONF_SPI_MASTER_ENABLE == true
461 /**
462  * \internal
463  * Writes a dummy character to the Data register.
464  *
465  * \param[in,out]  module  Pointer to SPI software instance struct
466  */
_spi_write_dummy(struct spi_module * const module)467 static void _spi_write_dummy(
468 		struct spi_module *const module)
469 {
470 	/* Pointer to the hardware module instance */
471 	SercomSpi *const spi_hw = &(module->hw->SPI);
472 
473 	/* Write dummy byte */
474 	spi_hw->DATA.reg = dummy_write;
475 
476 	/* Decrement remaining dummy buffer length */
477 	module->remaining_dummy_buffer_length--;
478 }
479 #  endif
480 
481 /**
482  * \internal
483  * Writes a dummy character from the to the Data register.
484  *
485  * \param[in,out]  module  Pointer to SPI software instance struct
486  */
_spi_read_dummy(struct spi_module * const module)487 static void _spi_read_dummy(
488 		struct spi_module *const module)
489 {
490 	/* Pointer to the hardware module instance */
491 	SercomSpi *const spi_hw = &(module->hw->SPI);
492 	uint16_t flush = 0;
493 
494 	/* Read dummy byte */
495 	flush = spi_hw->DATA.reg;
496 	UNUSED(flush);
497 
498 	/* Decrement remaining dummy buffer length */
499 	module->remaining_dummy_buffer_length--;
500 }
501 
502 /**
503  * \internal
504  * Reads a character from the Data register to the RX buffer.
505  *
506  * \param[in,out]  module  Pointer to SPI software instance struct
507  */
_spi_read(struct spi_module * const module)508 static void _spi_read(
509 		struct spi_module *const module)
510 {
511 	/* Pointer to the hardware module instance */
512 	SercomSpi *const spi_hw = &(module->hw->SPI);
513 
514 	uint16_t received_data = (spi_hw->DATA.reg & SERCOM_SPI_DATA_MASK);
515 
516 	/* Read value will be at least 8-bits long */
517 	*(module->rx_buffer_ptr) = received_data;
518 	/* Increment 8-bit pointer */
519 	module->rx_buffer_ptr += 1;
520 
521 	if(module->character_size == SPI_CHARACTER_SIZE_9BIT) {
522 		/* 9-bit data, write next received byte to the buffer */
523 		*(module->rx_buffer_ptr) = (received_data >> 8);
524 		/* Increment 8-bit pointer */
525 		module->rx_buffer_ptr += 1;
526 	}
527 
528 	/* Decrement length of the remaining buffer */
529 	module->remaining_rx_buffer_length--;
530 }
531 
532 /**
533  * \internal
534  *
535  * Handles interrupts as they occur, and it will run callback functions
536  * which are registered and enabled.
537  *
538  * \note This function will be called by the Sercom_Handler, and should
539  *       not be called directly from any application code.
540  *
541  * \param[in]  instance  ID of the SERCOM instance calling the interrupt
542  *                       handler.
543  */
_spi_interrupt_handler(uint8_t instance)544 void _spi_interrupt_handler(
545 		uint8_t instance)
546 {
547 	/* Get device instance from the look-up table */
548 	struct spi_module *module
549 		= (struct spi_module *)_sercom_instances[instance];
550 
551 	/* Pointer to the hardware module instance */
552 	SercomSpi *const spi_hw = &(module->hw->SPI);
553 
554 	/* Combine callback registered and enabled masks. */
555 	uint8_t callback_mask =
556 			module->enabled_callback & module->registered_callback;
557 
558 	/* Read and mask interrupt flag register */
559 	uint16_t interrupt_status = spi_hw->INTFLAG.reg;
560 	interrupt_status &= spi_hw->INTENSET.reg;
561 
562 	/* Data register empty interrupt */
563 	if (interrupt_status & SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY) {
564 #  if CONF_SPI_MASTER_ENABLE == true
565 		if ((module->mode == SPI_MODE_MASTER) &&
566 			(module->dir == SPI_DIRECTION_READ)) {
567 			/* Send dummy byte when reading in master mode */
568 			_spi_write_dummy(module);
569 			if (module->remaining_dummy_buffer_length == 0) {
570 				/* Disable the Data Register Empty Interrupt */
571 				spi_hw->INTENCLR.reg
572 						= SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY;
573 			}
574 		}
575 #  endif
576 
577 		if (0
578 #  if CONF_SPI_MASTER_ENABLE == true
579 		|| ((module->mode == SPI_MODE_MASTER) &&
580 			(module->dir != SPI_DIRECTION_READ))
581 #  endif
582 #  if CONF_SPI_SLAVE_ENABLE == true
583 		|| ((module->mode == SPI_MODE_SLAVE) &&
584 			(module->dir != SPI_DIRECTION_READ))
585 #  endif
586 		) {
587 			/* Write next byte from buffer */
588 			_spi_write(module);
589 			if (module->remaining_tx_buffer_length == 0) {
590 				/* Disable the Data Register Empty Interrupt */
591 				spi_hw->INTENCLR.reg
592 						= SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY;
593 
594 				if (module->dir == SPI_DIRECTION_WRITE &&
595 						!(module->receiver_enabled)) {
596 					/* Enable the Data Register transmit complete Interrupt */
597 					spi_hw->INTENSET.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE;
598 				}
599 			}
600 		}
601 	}
602 
603 	/* Receive complete interrupt*/
604 	if (interrupt_status & SPI_INTERRUPT_FLAG_RX_COMPLETE) {
605 		/* Check for overflow */
606 		if (spi_hw->STATUS.reg & SERCOM_SPI_STATUS_BUFOVF) {
607 			if (module->dir != SPI_DIRECTION_WRITE) {
608 				/* Store the error code */
609 				module->status = STATUS_ERR_OVERFLOW;
610 
611 				/* End transaction */
612 				module->dir = SPI_DIRECTION_IDLE;
613 
614 				spi_hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_RX_COMPLETE |
615 						SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY;
616 				/* Run callback if registered and enabled */
617 				if (callback_mask & (1 << SPI_CALLBACK_ERROR)) {
618 					(module->callback[SPI_CALLBACK_ERROR])(module);
619 				}
620 			}
621 			/* Flush */
622 			uint16_t flush = spi_hw->DATA.reg;
623 			UNUSED(flush);
624 			/* Clear overflow flag */
625 			spi_hw->STATUS.reg = SERCOM_SPI_STATUS_BUFOVF;
626 		} else {
627 			if (module->dir == SPI_DIRECTION_WRITE) {
628 				/* Flush receive buffer when writing */
629 				_spi_read_dummy(module);
630 				if (module->remaining_dummy_buffer_length == 0) {
631 					spi_hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_RX_COMPLETE;
632 					module->status = STATUS_OK;
633 					module->dir = SPI_DIRECTION_IDLE;
634 					/* Run callback if registered and enabled */
635 					if (callback_mask &
636 							(1 << SPI_CALLBACK_BUFFER_TRANSMITTED)){
637 						(module->callback[SPI_CALLBACK_BUFFER_TRANSMITTED])(module);
638 					}
639 				}
640 			} else {
641 				/* Read data register */
642 				_spi_read(module);
643 
644 				/* Check if the last character have been received */
645 				if (module->remaining_rx_buffer_length == 0) {
646 					module->status = STATUS_OK;
647 					/* Disable RX Complete Interrupt and set status */
648 					spi_hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_RX_COMPLETE;
649 					if(module->dir == SPI_DIRECTION_BOTH) {
650 						if (callback_mask & (1 << SPI_CALLBACK_BUFFER_TRANSCEIVED)) {
651 							(module->callback[SPI_CALLBACK_BUFFER_TRANSCEIVED])(module);
652 						}
653 					} else if (module->dir == SPI_DIRECTION_READ) {
654 						if (callback_mask & (1 << SPI_CALLBACK_BUFFER_RECEIVED)) {
655 							(module->callback[SPI_CALLBACK_BUFFER_RECEIVED])(module);
656 						}
657 					}
658 				}
659 			}
660 		}
661 	}
662 
663 	/* Transmit complete */
664 	if (interrupt_status & SPI_INTERRUPT_FLAG_TX_COMPLETE) {
665 #  if CONF_SPI_SLAVE_ENABLE == true
666 		if (module->mode == SPI_MODE_SLAVE) {
667 			/* Transaction ended by master */
668 
669 			/* Disable interrupts */
670 			spi_hw->INTENCLR.reg =
671 					SPI_INTERRUPT_FLAG_TX_COMPLETE |
672 					SPI_INTERRUPT_FLAG_RX_COMPLETE |
673 					SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY;
674 			/* Clear interrupt flag */
675 			spi_hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE;
676 
677 
678 			/* Reset all status information */
679 			module->dir = SPI_DIRECTION_IDLE;
680 			module->remaining_tx_buffer_length = 0;
681 			module->remaining_rx_buffer_length = 0;
682 			module->status = STATUS_OK;
683 
684 			if (callback_mask &
685 					(1 << SPI_CALLBACK_SLAVE_TRANSMISSION_COMPLETE)) {
686 			(module->callback[SPI_CALLBACK_SLAVE_TRANSMISSION_COMPLETE])
687 					(module);
688 			}
689 
690 		}
691 #  endif
692 #  if CONF_SPI_MASTER_ENABLE == true
693 		if ((module->mode == SPI_MODE_MASTER) &&
694 			(module->dir == SPI_DIRECTION_WRITE) && !(module->receiver_enabled)) {
695 		  	/* Clear interrupt flag */
696 		 	spi_hw->INTENCLR.reg
697 					= SPI_INTERRUPT_FLAG_TX_COMPLETE;
698 			/* Buffer sent with receiver disabled */
699 			module->dir = SPI_DIRECTION_IDLE;
700 			module->status = STATUS_OK;
701 			/* Run callback if registered and enabled */
702 			if (callback_mask & (1 << SPI_CALLBACK_BUFFER_TRANSMITTED)){
703 				(module->callback[SPI_CALLBACK_BUFFER_TRANSMITTED])
704 						(module);
705 			}
706 		}
707 #endif
708 	}
709 
710 #  ifdef FEATURE_SPI_SLAVE_SELECT_LOW_DETECT
711 #  if CONF_SPI_SLAVE_ENABLE == true
712 		/* When a high to low transition is detected on the _SS pin in slave mode */
713 		if (interrupt_status & SPI_INTERRUPT_FLAG_SLAVE_SELECT_LOW) {
714 			if (module->mode == SPI_MODE_SLAVE) {
715 				/* Disable interrupts */
716 				spi_hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_SLAVE_SELECT_LOW;
717 				/* Clear interrupt flag */
718 				spi_hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_SLAVE_SELECT_LOW;
719 
720 				if (callback_mask & (1 << SPI_CALLBACK_SLAVE_SELECT_LOW)) {
721 					(module->callback[SPI_CALLBACK_SLAVE_SELECT_LOW])(module);
722 				}
723 			}
724 		}
725 #  endif
726 #  endif
727 
728 #  ifdef FEATURE_SPI_ERROR_INTERRUPT
729 	/* When combined error happen */
730 	if (interrupt_status & SPI_INTERRUPT_FLAG_COMBINED_ERROR) {
731 		/* Disable interrupts */
732 		spi_hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_COMBINED_ERROR;
733 		/* Clear interrupt flag */
734 		spi_hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_COMBINED_ERROR;
735 
736 		if (callback_mask & (1 << SPI_CALLBACK_COMBINED_ERROR)) {
737 			(module->callback[SPI_CALLBACK_COMBINED_ERROR])(module);
738 		}
739 	}
740 #  endif
741 }
742