This file defines a useful set of functions for the SPI interface on AVR32 devices.
Definition in file spi.c.
#include "spi.h"
Go to the source code of this file.
Data Structures | |
union | u_avr32_spi_cr_t |
union | u_avr32_spi_csr_t |
union | u_avr32_spi_idr_t |
union | u_avr32_spi_ier_t |
union | u_avr32_spi_mr_t |
union | u_avr32_spi_tdr_t |
Functions | |
static int | getBaudDiv (const spi_options_t *options, unsigned int pba_hz) |
Calculates the baudrate divider. | |
void | spi_disable (volatile avr32_spi_t *spi) |
Disables the SPI. | |
void | spi_enable (volatile avr32_spi_t *spi) |
Enables the SPI. | |
unsigned char | spi_getStatus (volatile avr32_spi_t *spi) |
Gets status information from the SPI. | |
spi_status_t | spi_initMaster (volatile avr32_spi_t *spi, const spi_options_t *options) |
Initializes the SPI in master mode. | |
spi_status_t | spi_initSlave (volatile avr32_spi_t *spi, unsigned char bits, unsigned char spi_mode) |
Initializes the SPI in slave mode. | |
spi_status_t | spi_initTest (volatile avr32_spi_t *spi) |
Sets up the SPI in a test mode where the transmitter is connected to the receiver (local loopback). | |
int | spi_is_enabled (volatile avr32_spi_t *spi) |
Tests if the SPI is enabled. | |
spi_status_t | spi_read (volatile avr32_spi_t *spi, unsigned short *data) |
Reads one data word in master mode or in slave mode. | |
unsigned char | spi_readRegisterFullCheck (volatile avr32_spi_t *spi) |
Checks if there is data in the receive register. | |
void | spi_reset (volatile avr32_spi_t *spi) |
Resets the SPI controller. | |
spi_status_t | spi_selectChip (volatile avr32_spi_t *spi, unsigned char chip) |
Selects slave chip. | |
spi_status_t | spi_selectionMode (volatile avr32_spi_t *spi, unsigned char variable_ps, unsigned char pcs_decode, unsigned char delay) |
Sets up how and when the slave chips are selected (master mode only). | |
spi_status_t | spi_setupChipReg (volatile avr32_spi_t *spi, const spi_options_t *options, unsigned int pba_hz) |
Sets options for a specific slave chip. | |
spi_status_t | spi_unselectChip (volatile avr32_spi_t *spi, unsigned char chip) |
Unselects slave chip. | |
spi_status_t | spi_variableSlaveWrite (volatile avr32_spi_t *spi, unsigned short data, unsigned char pcs, unsigned char lastxfer) |
Selects a slave in master variable peripheral select mode and writes one data word to it. | |
spi_status_t | spi_write (volatile avr32_spi_t *spi, unsigned short data) |
Writes one data word in master fixed peripheral select mode or in slave mode. | |
unsigned char | spi_writeEndCheck (volatile avr32_spi_t *spi) |
Checks if all transmissions are complete. | |
unsigned char | spi_writeRegisterEmptyCheck (volatile avr32_spi_t *spi) |
Checks if there is no data in the transmit register. |
static int getBaudDiv | ( | const spi_options_t * | options, | |
unsigned int | pba_hz | |||
) | [static] |
Calculates the baudrate divider.
options | Pointer to a structure containing initialization options for an SPI channel. | |
pba_hz | SPI module input clock frequency (PBA clock, Hz). |
>=0 | Success. | |
<0 | Error. |
Definition at line 120 of file spi.c.
References spi_options_t::baudrate.
Referenced by spi_setupChipReg().
00121 { 00122 int baudDiv = (pba_hz + options->baudrate / 2) / options->baudrate; 00123 00124 if (baudDiv <= 0 || baudDiv > 255) { 00125 return -1; 00126 } 00127 00128 return baudDiv; 00129 }
void spi_disable | ( | volatile avr32_spi_t * | spi | ) |
void spi_enable | ( | volatile avr32_spi_t * | spi | ) |
Enables the SPI.
spi | Base address of the SPI instance. |
Definition at line 328 of file spi.c.
Referenced by at45dbx_resources_init(), init_spiMaster(), and init_spiSlave().
unsigned char spi_getStatus | ( | volatile avr32_spi_t * | spi | ) |
Gets status information from the SPI.
spi | Base address of the SPI instance. |
SPI_OK | Success. | |
SPI_ERROR_OVERRUN | Overrun error. | |
SPI_ERROR_MODE_FAULT | Mode fault (SPI addressed as slave while in master mode). | |
SPI_ERROR_OVERRUN_AND_MODE_FAULT | Overrun error and mode fault. |
Definition at line 420 of file spi.c.
References SPI_ERROR_MODE_FAULT, SPI_ERROR_OVERRUN, SPI_ERROR_OVERRUN_AND_MODE_FAULT, and SPI_OK.
00421 { 00422 spi_status_t ret = SPI_OK; 00423 unsigned long sr = spi->sr; 00424 00425 if (sr & AVR32_SPI_SR_OVRES_MASK) { 00426 ret = SPI_ERROR_OVERRUN; 00427 } 00428 00429 if (sr & AVR32_SPI_SR_MODF_MASK) { 00430 ret += SPI_ERROR_MODE_FAULT; 00431 } 00432 00433 if (ret == (SPI_ERROR_OVERRUN + SPI_ERROR_MODE_FAULT)) { 00434 return SPI_ERROR_OVERRUN_AND_MODE_FAULT; 00435 } 00436 else if (ret > 0) { 00437 return ret; 00438 } else { 00439 return SPI_OK; 00440 } 00441 }
spi_status_t spi_initMaster | ( | volatile avr32_spi_t * | spi, | |
const spi_options_t * | options | |||
) |
Initializes the SPI in master mode.
spi | Base address of the SPI instance. | |
options | Pointer to a structure containing initialization options. |
SPI_OK | Success. | |
SPI_ERROR_ARGUMENT | Invalid argument(s) passed. |
Definition at line 170 of file spi.c.
References spi_options_t::modfdis, u_avr32_spi_mr_t::MR, u_avr32_spi_mr_t::mr, SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by at45dbx_resources_init(), and init_spiMaster().
00171 { 00172 u_avr32_spi_mr_t u_avr32_spi_mr; 00173 00174 if (options->modfdis > 1) { 00175 return SPI_ERROR_ARGUMENT; 00176 } 00177 00178 // Reset. 00179 spi->cr = AVR32_SPI_CR_SWRST_MASK; 00180 00181 // Master Mode. 00182 u_avr32_spi_mr.mr = spi->mr; 00183 u_avr32_spi_mr.MR.mstr = 1; 00184 u_avr32_spi_mr.MR.modfdis = options->modfdis; 00185 u_avr32_spi_mr.MR.llb = 0; 00186 u_avr32_spi_mr.MR.pcs = (1 << AVR32_SPI_MR_PCS_SIZE) - 1; 00187 spi->mr = u_avr32_spi_mr.mr; 00188 00189 return SPI_OK; 00190 }
spi_status_t spi_initSlave | ( | volatile avr32_spi_t * | spi, | |
unsigned char | bits, | |||
unsigned char | spi_mode | |||
) |
Initializes the SPI in slave mode.
spi | Base address of the SPI instance. | |
bits | Number of bits in each transmitted character (8 to 16). | |
spi_mode | Clock polarity and phase. |
SPI_OK | Success. | |
SPI_ERROR_ARGUMENT | Invalid argument(s) passed. |
Definition at line 138 of file spi.c.
References SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by init_spiSlave().
00141 { 00142 if (spi_mode > 3 || 00143 bits < 8 || bits > 16) { 00144 return SPI_ERROR_ARGUMENT; 00145 } 00146 00147 // Reset. 00148 spi->cr = AVR32_SPI_CR_SWRST_MASK; 00149 00150 // Will use CSR0 offsets; these are the same for CSR0 to CSR3. 00151 spi->csr0 = ((spi_mode >> 1) << AVR32_SPI_CSR0_CPOL_OFFSET) | 00152 (((spi_mode & 0x1) ^ 0x1) << AVR32_SPI_CSR0_NCPHA_OFFSET) | 00153 ((bits - 8) << AVR32_SPI_CSR0_BITS_OFFSET); 00154 00155 return SPI_OK; 00156 }
spi_status_t spi_initTest | ( | volatile avr32_spi_t * | spi | ) |
Sets up the SPI in a test mode where the transmitter is connected to the receiver (local loopback).
spi | Base address of the SPI instance. |
SPI_OK | Success. |
Definition at line 159 of file spi.c.
References SPI_OK.
00160 { 00161 // Reset. 00162 spi->cr = AVR32_SPI_CR_SWRST_MASK; 00163 spi->mr |= AVR32_SPI_MR_MSTR_MASK | // Master Mode. 00164 AVR32_SPI_MR_LLB_MASK; // Local Loopback. 00165 00166 return SPI_OK; 00167 }
int spi_is_enabled | ( | volatile avr32_spi_t * | spi | ) |
spi_status_t spi_read | ( | volatile avr32_spi_t * | spi, | |
unsigned short * | data | |||
) |
Reads one data word in master mode or in slave mode.
spi | Base address of the SPI instance. | |
data | Pointer to the location where to store the received data word. |
SPI_OK | Success. | |
SPI_ERROR_TIMEOUT | Time-out. |
Definition at line 403 of file spi.c.
References SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
Referenced by at45dbx_mem_check(), at45dbx_read_byte(), at45dbx_read_sector_2_ram(), at45dbx_wait_ready(), and spi_slaveReceiveAndCompare().
00404 { 00405 unsigned int timeout = SPI_TIMEOUT; 00406 00407 while ((spi->sr & (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) != 00408 (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) { 00409 if (!timeout--) { 00410 return SPI_ERROR_TIMEOUT; 00411 } 00412 } 00413 00414 *data = spi->rdr >> AVR32_SPI_RDR_RD_OFFSET; 00415 00416 return SPI_OK; 00417 }
unsigned char spi_readRegisterFullCheck | ( | volatile avr32_spi_t * | spi | ) |
void spi_reset | ( | volatile avr32_spi_t * | spi | ) |
spi_status_t spi_selectChip | ( | volatile avr32_spi_t * | spi, | |
unsigned char | chip | |||
) |
Selects slave chip.
spi | Base address of the SPI instance. | |
chip | Slave chip number (normal: 0 to 3, extarnally decoded signal: 0 to 14). |
SPI_OK | Success. | |
SPI_ERROR_ARGUMENT | Invalid argument(s) passed. |
Definition at line 215 of file spi.c.
References SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by at45dbx_chipselect_df(), and init_spiMaster().
00216 { 00217 #ifdef FREERTOS_USED 00218 while (pdFALSE == xSemaphoreTake(xSPIMutex, 20)); 00219 #endif 00220 00221 // Assert all lines; no peripheral is selected. 00222 spi->mr |= AVR32_SPI_MR_PCS_MASK; 00223 00224 if (spi->mr & AVR32_SPI_MR_PCSDEC_MASK) { 00225 // The signal is decoded; allow up to 15 chips. 00226 if (chip > 14) { 00227 return SPI_ERROR_ARGUMENT; 00228 } 00229 00230 spi->mr &= ~AVR32_SPI_MR_PCS_MASK | (chip << AVR32_SPI_MR_PCS_OFFSET); 00231 } else { 00232 if (chip > 3) { 00233 return SPI_ERROR_ARGUMENT; 00234 } 00235 00236 spi->mr &= ~(1 << (AVR32_SPI_MR_PCS_OFFSET + chip)); 00237 } 00238 00239 return SPI_OK; 00240 }
spi_status_t spi_selectionMode | ( | volatile avr32_spi_t * | spi, | |
unsigned char | variable_ps, | |||
unsigned char | pcs_decode, | |||
unsigned char | delay | |||
) |
Sets up how and when the slave chips are selected (master mode only).
spi | Base address of the SPI instance. | |
variable_ps | Target slave is selected in transfer register for every character to transmit. | |
pcs_decode | The four chip select lines are decoded externally. Values 0 to 14 can be given to spi_selectChip. | |
delay | Delay in PBA periods between chip selects. |
SPI_OK | Success. | |
SPI_ERROR_ARGUMENT | Invalid argument(s) passed. |
Definition at line 193 of file spi.c.
References u_avr32_spi_mr_t::MR, u_avr32_spi_mr_t::mr, SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by at45dbx_resources_init(), and init_spiMaster().
00197 { 00198 u_avr32_spi_mr_t u_avr32_spi_mr; 00199 00200 if (variable_ps > 1 || 00201 pcs_decode > 1) { 00202 return SPI_ERROR_ARGUMENT; 00203 } 00204 00205 u_avr32_spi_mr.mr = spi->mr; 00206 u_avr32_spi_mr.MR.ps = variable_ps; 00207 u_avr32_spi_mr.MR.pcsdec = pcs_decode; 00208 u_avr32_spi_mr.MR.dlybcs = delay; 00209 spi->mr = u_avr32_spi_mr.mr; 00210 00211 return SPI_OK; 00212 }
spi_status_t spi_setupChipReg | ( | volatile avr32_spi_t * | spi, | |
const spi_options_t * | options, | |||
unsigned int | pba_hz | |||
) |
Sets options for a specific slave chip.
The baudrate field has to be written before transfer in master mode. Four similar registers exist, one for each slave. When using encoded slave addressing, reg=0 sets options for slaves 0 to 3, reg=1 for slaves 4 to 7 and so on.
spi | Base address of the SPI instance. | |
options | Pointer to a structure containing initialization options for an SPI channel. | |
pba_hz | SPI module input clock frequency (PBA clock, Hz). |
SPI_OK | Success. | |
SPI_ERROR_ARGUMENT | Invalid argument(s) passed. |
Definition at line 267 of file spi.c.
References spi_options_t::bits, u_avr32_spi_csr_t::CSR, u_avr32_spi_csr_t::csr, getBaudDiv(), spi_options_t::reg, spi_options_t::spck_delay, SPI_ERROR_ARGUMENT, spi_options_t::spi_mode, SPI_OK, spi_options_t::stay_act, and spi_options_t::trans_delay.
Referenced by at45dbx_init(), init_spiMaster(), and init_spiSlave().
00270 { 00271 u_avr32_spi_csr_t u_avr32_spi_csr; 00272 00273 if (options->spi_mode > 3 || 00274 options->stay_act > 1 || 00275 options->bits < 8 || options->bits > 16) { 00276 return SPI_ERROR_ARGUMENT; 00277 } 00278 00279 int baudDiv = getBaudDiv(options, pba_hz); 00280 00281 if (baudDiv < 0) { 00282 return SPI_ERROR_ARGUMENT; 00283 } 00284 00285 // Will use CSR0 offsets; these are the same for CSR0 to CSR3. 00286 u_avr32_spi_csr.csr = 0; 00287 u_avr32_spi_csr.CSR.cpol = options->spi_mode >> 1; 00288 u_avr32_spi_csr.CSR.ncpha = (options->spi_mode & 0x1) ^ 0x1; 00289 u_avr32_spi_csr.CSR.csaat = options->stay_act; 00290 u_avr32_spi_csr.CSR.bits = options->bits - 8; 00291 u_avr32_spi_csr.CSR.scbr = baudDiv; 00292 u_avr32_spi_csr.CSR.dlybs = options->spck_delay; 00293 u_avr32_spi_csr.CSR.dlybct = options->trans_delay; 00294 00295 switch(options->reg) { 00296 case 0: 00297 spi->csr0 = u_avr32_spi_csr.csr; 00298 break; 00299 case 1: 00300 spi->csr1 = u_avr32_spi_csr.csr; 00301 break; 00302 case 2: 00303 spi->csr2 = u_avr32_spi_csr.csr; 00304 break; 00305 case 3: 00306 spi->csr3 = u_avr32_spi_csr.csr; 00307 break; 00308 default: 00309 return SPI_ERROR_ARGUMENT; 00310 } 00311 00312 #ifdef FREERTOS_USED 00313 if (!xSPIMutex) 00314 { 00315 // Create the SPI mutex. 00316 vSemaphoreCreateBinary(xSPIMutex); 00317 if (!xSPIMutex) 00318 { 00319 while(1); 00320 } 00321 } 00322 #endif 00323 00324 return SPI_OK; 00325 }
spi_status_t spi_unselectChip | ( | volatile avr32_spi_t * | spi, | |
unsigned char | chip | |||
) |
Unselects slave chip.
spi | Base address of the SPI instance. | |
chip | Slave chip number (normal: 0 to 3, extarnally decoded signal: 0 to 14). |
SPI_OK | Success. | |
SPI_ERROR_TIMEOUT | Time-out. |
Definition at line 243 of file spi.c.
References SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
Referenced by at45dbx_chipselect_df().
00244 { 00245 unsigned int timeout = SPI_TIMEOUT; 00246 00247 while (!(spi->sr & AVR32_SPI_SR_TXEMPTY_MASK)) { 00248 if (!timeout--) { 00249 return SPI_ERROR_TIMEOUT; 00250 } 00251 } 00252 00253 // Assert all lines; no peripheral is selected. 00254 spi->mr |= AVR32_SPI_MR_PCS_MASK; 00255 00256 // Last transfer, so deassert the current NPCS if CSAAT is set. 00257 spi->cr = AVR32_SPI_CR_LASTXFER_MASK; 00258 00259 #ifdef FREERTOS_USED 00260 xSemaphoreGive(xSPIMutex); 00261 #endif 00262 00263 return SPI_OK; 00264 }
spi_status_t spi_variableSlaveWrite | ( | volatile avr32_spi_t * | spi, | |
unsigned short | data, | |||
unsigned char | pcs, | |||
unsigned char | lastxfer | |||
) |
Selects a slave in master variable peripheral select mode and writes one data word to it.
spi | Base address of the SPI instance. | |
data | The data word to write. | |
pcs | Slave selector (bit 0 -> nCS line 0, bit 1 -> nCS line 1, etc.). | |
lastxfer | Boolean indicating whether this is the last data word transfer. |
SPI_OK | Success. | |
SPI_ERROR_TIMEOUT | Time-out. | |
SPI_ERROR_ARGUMENT | Invalid argument(s) passed. |
Once the data has been written to the transmit buffer, the end of transmission is not waited for. Invoke spi_writeEndCheck if needed.
Definition at line 368 of file spi.c.
References SPI_ERROR_ARGUMENT, SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
00370 { 00371 unsigned int timeout = SPI_TIMEOUT; 00372 00373 if (pcs > 14 || lastxfer > 1) { 00374 return SPI_ERROR_ARGUMENT; 00375 } 00376 00377 while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) { 00378 if (!timeout--) { 00379 return SPI_ERROR_TIMEOUT; 00380 } 00381 } 00382 00383 spi->tdr = (data << AVR32_SPI_TDR_TD_OFFSET) | 00384 (pcs << AVR32_SPI_TDR_PCS_OFFSET) | 00385 (lastxfer << AVR32_SPI_TDR_LASTXFER_OFFSET); 00386 00387 return SPI_OK; 00388 }
spi_status_t spi_write | ( | volatile avr32_spi_t * | spi, | |
unsigned short | data | |||
) |
Writes one data word in master fixed peripheral select mode or in slave mode.
spi | Base address of the SPI instance. | |
data | The data word to write. |
SPI_OK | Success. | |
SPI_ERROR_TIMEOUT | Time-out. |
Once the data has been written to the transmit buffer, the end of transmission is not waited for. Invoke spi_writeEndCheck if needed.
Definition at line 352 of file spi.c.
References SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
Referenced by at45dbx_mem_check(), at45dbx_read_open(), at45dbx_wait_ready(), at45dbx_write_byte(), at45dbx_write_close(), at45dbx_write_open(), at45dbx_write_sector_from_ram(), and spi_masterSend().
00353 { 00354 unsigned int timeout = SPI_TIMEOUT; 00355 00356 while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) { 00357 if (!timeout--) { 00358 return SPI_ERROR_TIMEOUT; 00359 } 00360 } 00361 00362 spi->tdr = data << AVR32_SPI_TDR_TD_OFFSET; 00363 00364 return SPI_OK; 00365 }
unsigned char spi_writeEndCheck | ( | volatile avr32_spi_t * | spi | ) |
unsigned char spi_writeRegisterEmptyCheck | ( | volatile avr32_spi_t * | spi | ) |