spi_master.c
Go to the documentation of this file.
1 
33 /*
34  * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
35  */
36 
37 #include "spi_master.h"
38 #if SAMG55
39 #include "flexcom.h"
40 #include "conf_board.h"
41 #endif
42 
46 #define MAX_NUM_WITH_DECODER 0x10
47 
51 #define MAX_NUM_WITHOUT_DECODER 0x04
52 
56 #define NONE_CHIP_SELECT_ID 0x0f
57 
61 #define DEFAULT_CHIP_ID 0
62 
68 void spi_master_init(Spi *p_spi)
69 {
70 #if SAMG55
71  flexcom_enable(BOARD_FLEXCOM_SPI);
72  flexcom_set_opmode(BOARD_FLEXCOM_SPI, FLEXCOM_SPI);
73 #else
74  spi_enable_clock(p_spi);
75 #endif
76  spi_reset(p_spi);
77  spi_set_master_mode(p_spi);
79  spi_disable_loopback(p_spi);
84 }
85 
100 void spi_master_setup_device(Spi *p_spi, struct spi_device *device,
101  spi_flags_t flags, uint32_t baud_rate, board_spi_select_id_t sel_id)
102 {
103 #if (SAM4L)
104  int16_t baud_div = spi_calc_baudrate_div(baud_rate, sysclk_get_pba_hz());
105 #else
106  int16_t baud_div = spi_calc_baudrate_div(baud_rate, sysclk_get_peripheral_hz());
107 #endif
108  /* avoid Cppcheck Warning */
109  UNUSED(sel_id);
110  if (-1 == baud_div) {
111  Assert(0 == "Failed to find baudrate divider");
112  }
115  spi_set_bits_per_transfer(p_spi, device->id,
117  spi_set_baudrate_div(p_spi, device->id, baud_div);
119  spi_set_clock_polarity(p_spi, device->id, flags >> 1);
120  spi_set_clock_phase(p_spi, device->id, ((flags & 0x1) ^ 0x1));
121 }
122 
132 void spi_select_device(Spi *p_spi, struct spi_device *device)
133 {
135  if (device->id < MAX_NUM_WITH_DECODER) {
137  }
138  } else {
139  if (device->id < MAX_NUM_WITHOUT_DECODER) {
140  spi_set_peripheral_chip_select_value(p_spi, (~(1 << device->id)));
141  }
142  }
143 }
144 
155 void spi_deselect_device(Spi *p_spi, struct spi_device *device)
156 {
157  /* avoid Cppcheck Warning */
158  UNUSED(device);
159  while (!spi_is_tx_empty(p_spi)) {
160  }
161 
162  // Assert all lines; no peripheral is selected.
164 
165  // Last transfer, so de-assert the current NPCS if CSAAT is set.
166  spi_set_lastxfer(p_spi);
167 
168 }
169 
181 status_code_t spi_write_packet(Spi *p_spi, const uint8_t *data,
182  size_t len)
183 {
184  uint32_t timeout = SPI_TIMEOUT;
185  uint32_t i = 0;
186  uint8_t val;
187 
188  while (len) {
189  timeout = SPI_TIMEOUT;
190  while (!spi_is_tx_ready(p_spi)) {
191  if (!timeout--) {
192  return ERR_TIMEOUT;
193  }
194  }
195  val = data[i];
196  spi_write_single(p_spi, val);
197  i++;
198  len--;
199  }
200 
201  return STATUS_OK;
202 }
203 
215 status_code_t spi_read_packet(Spi *p_spi, uint8_t *data, size_t len)
216 {
217  uint32_t timeout = SPI_TIMEOUT;
218  uint8_t val;
219  uint32_t i = 0;
220 
221  while (len) {
222  timeout = SPI_TIMEOUT;
223  while (!spi_is_tx_ready(p_spi)) {
224  if (!timeout--) {
225  return ERR_TIMEOUT;
226  }
227  }
229 
230  timeout = SPI_TIMEOUT;
231  while (!spi_is_rx_ready(p_spi)) {
232  if (!timeout--) {
233  return ERR_TIMEOUT;
234  }
235  }
236  spi_read_single(p_spi, &val);
237 
238  data[i] = val;
239  i++;
240  len--;
241  }
242 
243  return STATUS_OK;
244 }
245 
256 status_code_t spi_transceive_packet(Spi *p_spi, uint8_t *tx_data, uint8_t *rx_data, size_t len)
257 {
258  uint32_t timeout = SPI_TIMEOUT;
259  uint8_t val;
260  uint32_t i = 0;
261 
262  while (len) {
263  timeout = SPI_TIMEOUT;
264  while (!spi_is_tx_ready(p_spi)) {
265  if (!timeout--) {
266  return ERR_TIMEOUT;
267  }
268  }
269  spi_write_single(p_spi, tx_data[i]);
270 
271  timeout = SPI_TIMEOUT;
272  while (!spi_is_rx_ready(p_spi)) {
273  if (!timeout--) {
274  return ERR_TIMEOUT;
275  }
276  }
277  spi_read_single(p_spi, &val);
278 
279  rx_data[i] = val;
280  i++;
281  len--;
282  }
283 
284  return STATUS_OK;
285 }
static void spi_set_master_mode(Spi *p_spi)
Set SPI to Master mode.
void spi_set_clock_phase(Spi *p_spi, uint32_t ul_pcs_ch, uint32_t ul_phase)
Set Data Capture Phase.
Definition: spi.c:307
void spi_configure_cs_behavior(Spi *p_spi, uint32_t ul_pcs_ch, uint32_t ul_cs_behavior)
Configure CS behavior for SPI transfer (spi_cs_behavior_t).
Definition: spi.c:323
#define UNUSED(v)
Marking v as a unused parameter or value.
Definition: compiler.h:86
static void spi_read_single(Spi *p_spi, uint8_t *data)
Receive one byte from an SPI device.
void spi_select_device(Spi *p_spi, struct spi_device *device)
Select the given device on the SPI bus.
Definition: spi_master.c:132
Success.
Definition: status_codes.h:66
void spi_master_init(Spi *p_spi)
Initialize the SPI in master mode.
Definition: spi_master.c:68
void spi_deselect_device(Spi *p_spi, struct spi_device *device)
Deselect the given device on the SPI bus.
Definition: spi_master.c:155
int16_t spi_set_baudrate_div(Spi *p_spi, uint32_t ul_pcs_ch, uint8_t uc_baudrate_divider)
Set Serial Clock Baud Rate divider value (SCBR).
Definition: spi.c:385
#define CONFIG_SPI_MASTER_BITS_PER_TRANSFER
Default Configuration of SPI Master Bits per Transfer Definition.
board_spi_select_id_t id
Board specific select id.
Operation timed out.
Definition: status_codes.h:72
Spi hardware registers.
#define CONFIG_SPI_MASTER_DELAY_BS
Default Configuration of SPI Master Delay BS.
void spi_set_bits_per_transfer(Spi *p_spi, uint32_t ul_pcs_ch, uint32_t ul_bits)
Set number of bits per transfer.
Definition: spi.c:345
static uint32_t spi_get_peripheral_select_decode_setting(Spi *p_spi)
Get Peripheral Select Decode mode.
void spi_set_clock_polarity(Spi *p_spi, uint32_t ul_pcs_ch, uint32_t ul_polarity)
Set clock default state.
Definition: spi.c:290
#define CONFIG_SPI_MASTER_DELAY_BCT
Default Configuration of SPI Master Delay BCT.
static void spi_reset(Spi *p_spi)
Reset SPI and set it to Slave mode.
static uint32_t spi_is_tx_ready(Spi *p_spi)
Check if all transmissions are ready.
status_code_t spi_transceive_packet(Spi *p_spi, uint8_t *tx_data, uint8_t *rx_data, size_t len)
Send and receive a sequence of bytes from an SPI device.
Definition: spi_master.c:256
static void spi_disable_loopback(Spi *p_spi)
Disable loopback mode.
static uint32_t sysclk_get_peripheral_hz(void)
Retrieves the current rate in Hz of the peripheral clocks.
void spi_enable_clock(Spi *p_spi)
Enable SPI clock.
Definition: spi.c:60
#define CONFIG_SPI_MASTER_DELAY_BCS
Default Configuration of SPI Master Delay BCS.
Board configuration.
status_code_t spi_write_packet(Spi *p_spi, const uint8_t *data, size_t len)
Send a sequence of bytes to an SPI device.
Definition: spi_master.c:181
static void spi_disable_peripheral_select_decode(Spi *p_spi)
Disable Peripheral Select Decode.
static void spi_disable_mode_fault_detect(Spi *p_spi)
Disable Mode Fault Detection.
void spi_set_peripheral_chip_select_value(Spi *p_spi, uint32_t ul_value)
Set Peripheral Chip Select (PCS) value.
Definition: spi.c:193
USBInterfaceDescriptor data
#define CONFIG_SPI_MASTER_DUMMY
Default Configuration of SPI Master Dummy Field.
static void spi_write_single(Spi *p_spi, uint8_t data)
Write one byte to an SPI device.
#define DEFAULT_CHIP_ID
The default chip select id.
Definition: spi_master.c:61
int16_t spi_calc_baudrate_div(const uint32_t baudrate, uint32_t mck)
Calculate the baudrate divider.
Definition: spi.c:362
enum status_code status_code_t
Definition: status_codes.h:97
static uint32_t spi_is_rx_ready(Spi *p_spi)
Check if all receptions are ready.
static uint32_t spi_is_tx_empty(Spi *p_spi)
Check if all transmissions are complete.
static void spi_set_fixed_peripheral_select(Spi *p_spi)
Set Fixed Peripheral Select. Peripheral Chip Select is controlled by SPI_MR.
void spi_set_transfer_delay(Spi *p_spi, uint32_t ul_pcs_ch, uint8_t uc_dlybs, uint8_t uc_dlybct)
Configure timing for SPI transfer.
Definition: spi.c:405
uint8_t spi_flags_t
SPI Flags Definition.
#define NONE_CHIP_SELECT_ID
Max number when the chip selects are directly connected to peripheral device.
Definition: spi_master.c:56
void spi_set_delay_between_chip_select(Spi *p_spi, uint32_t ul_delay)
Set delay between chip selects (in number of MCK clocks). If DLYBCS <= 6, 6 MCK clocks will be insert...
Definition: spi.c:206
Polled SPI device definition.
#define SPI_TIMEOUT
uint32_t board_spi_select_id_t
Board SPI Select Id Definition.
#define Assert(expr)
This macro is used to test fatal errors.
Definition: compiler.h:196
SPI master common service for SAM.
#define MAX_NUM_WITH_DECODER
Max number when the chip selects are connected to a 4- to 16-bit decoder.
Definition: spi_master.c:46
void spi_master_setup_device(Spi *p_spi, struct spi_device *device, spi_flags_t flags, uint32_t baud_rate, board_spi_select_id_t sel_id)
Set up an SPI device.
Definition: spi_master.c:100
#define MAX_NUM_WITHOUT_DECODER
Max number when the chip selects are directly connected to peripheral device.
Definition: spi_master.c:51
static void spi_set_lastxfer(Spi *p_spi)
Issue a LASTXFER command. The next transfer is the last transfer and after that CS is de-asserted...
status_code_t spi_read_packet(Spi *p_spi, uint8_t *data, size_t len)
Receive a sequence of bytes from an SPI device.
Definition: spi_master.c:215


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:05