Go to the documentation of this file.00001
00048 #include <cfg/spi.h>
00049
00050 #include <arch/avr32.h>
00051 #include <arch/avr32/gpio.h>
00052
00053 #include <dev/spibus_avr32.h>
00054 #include <dev/irqreg.h>
00055 #include <dev/gpio.h>
00056 #include <sys/event.h>
00057 #include <sys/nutdebug.h>
00058
00059 #include <stdlib.h>
00060 #include <errno.h>
00061
00062 #include <avr32/io.h>
00063
00064 #ifndef AVR32_SPI0_ADDRESS
00065 #define AVR32_SPI0_ADDRESS AVR32_SPI_ADDRESS
00066 #endif
00067
00068 #ifndef AVR32_SPI0
00069 #define AVR32_SPI0 AVR32_SPI
00070 #endif
00071
00072 #if defined(AVR32_SPI0_SCK_0_0_PIN)
00073 #define AVR32_SPI0_SCK_PIN AVR32_SPI0_SCK_0_0_PIN
00074 #define AVR32_SPI0_SCK_FUNCTION AVR32_SPI0_SCK_0_0_FUNCTION
00075 #define AVR32_SPI0_MISO_PIN AVR32_SPI0_MISO_0_0_PIN
00076 #define AVR32_SPI0_MISO_FUNCTION AVR32_SPI0_MISO_0_0_FUNCTION
00077 #define AVR32_SPI0_MOSI_PIN AVR32_SPI0_MOSI_0_0_PIN
00078 #define AVR32_SPI0_MOSI_FUNCTION AVR32_SPI0_MOSI_0_0_FUNCTION
00079 #define AVR32_SPI0_NPCS_PIN AVR32_SPI0_NPCS_0_0_PIN
00080 #define AVR32_SPI0_NPCS_FUNCTION AVR32_SPI0_NPCS_0_0_FUNCTION
00081 #elif defined(AVR32_SPI0_SCK_0_PIN)
00082 #define AVR32_SPI0_SCK_PIN AVR32_SPI0_SCK_0_PIN
00083 #define AVR32_SPI0_SCK_FUNCTION AVR32_SPI0_SCK_0_FUNCTION
00084 #define AVR32_SPI0_MISO_PIN AVR32_SPI0_MISO_0_PIN
00085 #define AVR32_SPI0_MISO_FUNCTION AVR32_SPI0_MISO_0_FUNCTION
00086 #define AVR32_SPI0_MOSI_PIN AVR32_SPI0_MOSI_0_PIN
00087 #define AVR32_SPI0_MOSI_FUNCTION AVR32_SPI0_MOSI_0_FUNCTION
00088 #define AVR32_SPI0_NPCS_PIN AVR32_SPI0_NPCS_0_PIN
00089 #define AVR32_SPI0_NPCS_FUNCTION AVR32_SPI0_NPCS_0_FUNCTION
00090 #elif defined(AVR32_SPI_SCK_0_0_PIN)
00091 #define AVR32_SPI0_SCK_PIN AVR32_SPI_SCK_0_0_PIN
00092 #define AVR32_SPI0_SCK_FUNCTION AVR32_SPI_SCK_0_0_FUNCTION
00093 #define AVR32_SPI0_MISO_PIN AVR32_SPI_MISO_0_0_PIN
00094 #define AVR32_SPI0_MISO_FUNCTION AVR32_SPI_MISO_0_0_FUNCTION
00095 #define AVR32_SPI0_MOSI_PIN AVR32_SPI_MOSI_0_0_PIN
00096 #define AVR32_SPI0_MOSI_FUNCTION AVR32_SPI_MOSI_0_0_FUNCTION
00097 #define AVR32_SPI0_NPCS_PIN AVR32_SPI_NPCS_0_0_PIN
00098 #define AVR32_SPI0_NPCS_FUNCTION AVR32_SPI_NPCS_0_0_FUNCTION
00099 #endif
00100
00101 #if defined(SPI0_CS0_PIO_BIT)
00102 #if defined(SPI0_CS0_PIO_ID)
00103 #undef GPIO_ID
00104 #define GPIO_ID SPI0_CS0_PIO_ID
00105 #include <cfg/arch/porttran.h>
00106 static INLINE void SPI0_CS0_LO(void)
00107 {
00108 GPIO_SET_LO(SPI0_CS0_PIO_BIT);
00109 }
00110
00111 static INLINE void SPI0_CS0_HI(void)
00112 {
00113 GPIO_SET_HI(SPI0_CS0_PIO_BIT);
00114 }
00115
00116 static INLINE void SPI0_CS0_SO(void)
00117 {
00118 GPIO_ENABLE(SPI0_CS0_PIO_BIT);
00119 GPIO_OUTPUT(SPI0_CS0_PIO_BIT);
00120 }
00121 #else
00122 #define SPI0_CS0_LO()
00123 #define SPI0_CS0_HI()
00124 #define SPI0_CS0_SO()
00125 #endif
00126 #endif
00127
00128 #if defined(SPI0_CS1_PIO_BIT)
00129 #if defined(SPI0_CS1_PIO_ID)
00130 #undef GPIO_ID
00131 #define GPIO_ID SPI0_CS1_PIO_ID
00132 #include <cfg/arch/porttran.h>
00133 static INLINE void SPI0_CS1_LO(void)
00134 {
00135 GPIO_SET_LO(SPI0_CS1_PIO_BIT);
00136 }
00137
00138 static INLINE void SPI0_CS1_HI(void)
00139 {
00140 GPIO_SET_HI(SPI0_CS1_PIO_BIT);
00141 }
00142
00143 static INLINE void SPI0_CS1_SO(void)
00144 {
00145 GPIO_ENABLE(SPI0_CS1_PIO_BIT);
00146 GPIO_OUTPUT(SPI0_CS1_PIO_BIT);
00147 }
00148 #else
00149 #define SPI0_CS1_LO()
00150 #define SPI0_CS1_HI()
00151 #define SPI0_CS1_SO()
00152 #endif
00153 #endif
00154
00155 #if defined(SPI0_CS2_PIO_BIT)
00156 #if defined(SPI0_CS2_PIO_ID)
00157 #undef GPIO_ID
00158 #define GPIO_ID SPI0_CS2_PIO_ID
00159 #include <cfg/arch/porttran.h>
00160 static INLINE void SPI0_CS2_LO(void)
00161 {
00162 GPIO_SET_LO(SPI0_CS2_PIO_BIT);
00163 }
00164
00165 static INLINE void SPI0_CS2_HI(void)
00166 {
00167 GPIO_SET_HI(SPI0_CS2_PIO_BIT);
00168 }
00169
00170 static INLINE void SPI0_CS2_SO(void)
00171 {
00172 GPIO_ENABLE(SPI0_CS2_PIO_BIT);
00173 GPIO_OUTPUT(SPI0_CS2_PIO_BIT);
00174 }
00175 #else
00176 #define SPI0_CS2_LO()
00177 #define SPI0_CS2_HI()
00178 #define SPI0_CS2_SO()
00179 #endif
00180 #endif
00181
00182 #if defined(SPI0_CS3_PIO_BIT)
00183 #if defined(SPI0_CS3_PIO_ID)
00184 #undef GPIO_ID
00185 #define GPIO_ID SPI0_CS3_PIO_ID
00186 #include <cfg/arch/porttran.h>
00187 static INLINE void SPI0_CS3_LO(void)
00188 {
00189 GPIO_SET_LO(SPI0_CS3_PIO_BIT);
00190 }
00191
00192 static INLINE void SPI0_CS3_HI(void)
00193 {
00194 GPIO_SET_HI(SPI0_CS3_PIO_BIT);
00195 }
00196
00197 static INLINE void SPI0_CS3_SO(void)
00198 {
00199 GPIO_ENABLE(SPI0_CS3_PIO_BIT);
00200 GPIO_OUTPUT(SPI0_CS3_PIO_BIT);
00201 }
00202 #else
00203 #define SPI0_CS3_LO()
00204 #define SPI0_CS3_HI()
00205 #define SPI0_CS3_SO()
00206 #endif
00207 #endif
00208
00212 int Avr32Spi0ChipSelect(uint_fast8_t cs, uint_fast8_t hi)
00213 {
00214 int rc = 0;
00215
00216 switch (cs) {
00217 #if defined(SPI0_CS0_PIO_BIT)
00218 case 0:
00219 if (hi) {
00220 SPI0_CS0_HI();
00221 } else {
00222 SPI0_CS0_LO();
00223 }
00224 SPI0_CS0_SO();
00225 break;
00226 #endif
00227 #if defined(SPI0_CS1_PIO_BIT)
00228 case 1:
00229 if (hi) {
00230 SPI0_CS1_HI();
00231 } else {
00232 SPI0_CS1_LO();
00233 }
00234 SPI0_CS1_SO();
00235 break;
00236 #endif
00237 #if defined(SPI0_CS2_PIO_BIT)
00238 case 2:
00239 if (hi) {
00240 SPI0_CS2_HI();
00241 } else {
00242 SPI0_CS2_LO();
00243 }
00244 SPI0_CS2_SO();
00245 break;
00246 #endif
00247 #if defined(SPI0_CS3_PIO_BIT)
00248 case 3:
00249 if (hi) {
00250 SPI0_CS3_HI();
00251 } else {
00252 SPI0_CS3_LO();
00253 }
00254 SPI0_CS3_SO();
00255 break;
00256 #endif
00257 default:
00258 errno = EIO;
00259 rc = -1;
00260 break;
00261 }
00262 return rc;
00263 }
00264
00276 int Avr32SpiBus0Select(NUTSPINODE * node, uint32_t tmo)
00277 {
00278 int rc;
00279
00280
00281 NUTASSERT(node != NULL);
00282 NUTASSERT(node->node_bus != NULL);
00283 NUTASSERT(node->node_stat != NULL);
00284
00285
00286 rc = NutEventWait(&node->node_bus->bus_mutex, tmo);
00287 if (rc) {
00288 errno = EIO;
00289 } else {
00290 AVR32SPIREG *spireg = node->node_stat;
00291
00292
00293 gpio_enable_module_pin(AVR32_SPI0_SCK_PIN, AVR32_SPI0_SCK_FUNCTION);
00294 gpio_enable_module_pin(AVR32_SPI0_MISO_PIN, AVR32_SPI0_MISO_FUNCTION);
00295 gpio_enable_module_pin(AVR32_SPI0_MOSI_PIN, AVR32_SPI0_MOSI_FUNCTION);
00296 gpio_enable_module_pin(AVR32_SPI0_NPCS_PIN, AVR32_SPI0_NPCS_FUNCTION);
00297
00298
00299 if (node->node_mode & SPI_MODE_UPDATE) {
00300 Avr32SpiSetup(node);
00301 }
00302
00303
00304 outr(AVR32_SPI0_ADDRESS + AVR32_SPI_MR, spireg->mr);
00305
00306 outr(AVR32_SPI0_ADDRESS + AVR32_SPI_CSR0, spireg->csr);
00307
00308
00309 AVR32_SPI0.cr |= AVR32_SPI_CR_SPIEN_MASK;
00310
00311
00312 rc = Avr32Spi0ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) != 0);
00313 if (rc) {
00314
00315 NutEventPost(&node->node_bus->bus_mutex);
00316 }
00317 }
00318 return rc;
00319 }
00320
00329 int Avr32SpiBus0Deselect(NUTSPINODE * node)
00330 {
00331
00332 NUTASSERT(node != NULL);
00333 NUTASSERT(node->node_bus != NULL);
00334
00335 #ifdef SPIBUS0_DOUBLE_BUFFER
00336 Avr32SpiBusWait(node, NUT_WAIT_INFINITE);
00337 #endif
00338
00339 Avr32Spi0ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) == 0);
00340
00341
00342 NutEventPost(&node->node_bus->bus_mutex);
00343
00344 return 0;
00345 }
00346
00347 #if !defined(SPIBUS0_POLLING_MODE) || !defined(SPIBUS0_DOUBLE_BUFFER)
00348
00349 static uint8_t *volatile spi0_txp;
00350 static uint8_t *volatile spi0_rxp;
00351 static volatile size_t spi0_xc;
00352
00353 void Avr32SpiBus0Interrupt(void *arg)
00354 {
00355 uint8_t b;
00356
00357
00358 b = (uint8_t) inr(AVR32_SPI0_ADDRESS + AVR32_SPI_RDR) >> AVR32_SPI_RDR_RD_OFFSET;
00359 if (spi0_xc) {
00360 if (spi0_rxp) {
00361 *spi0_rxp++ = b;
00362 }
00363 spi0_xc--;
00364 }
00365 if (spi0_xc) {
00366 if (spi0_txp) {
00367 b = *spi0_txp++;
00368 }
00369 outr(AVR32_SPI0_ADDRESS + AVR32_SPI_TDR, (b << AVR32_SPI_TDR_TD_OFFSET));
00370 } else {
00371 NutEventPostFromIrq((void **) arg);
00372 }
00373 }
00374
00389 int Avr32SpiBus0Transfer(NUTSPINODE * node, CONST void *txbuf, void *rxbuf, int xlen)
00390 {
00391 uint8_t b = 0xff;
00392 uintptr_t base;
00393
00394
00395 NUTASSERT(node != NULL);
00396 NUTASSERT(node->node_bus != NULL);
00397 NUTASSERT(node->node_bus->bus_base != 0);
00398 base = node->node_bus->bus_base;
00399
00400 if (xlen) {
00401 spi0_txp = (uint8_t *) txbuf;
00402 spi0_rxp = (uint8_t *) rxbuf;
00403 spi0_xc = (size_t) xlen;
00404 if (spi0_txp) {
00405 b = *spi0_txp++;
00406 }
00407
00408 outr(base + AVR32_SPI_IER, AVR32_SPI_IER_RDRF_MASK);
00409 outr(base + AVR32_SPI_TDR, (b << AVR32_SPI_TDR_TD_OFFSET));
00410
00411 NutEventWait(&node->node_bus->bus_ready, NUT_WAIT_INFINITE);
00412 outr(base + AVR32_SPI_IDR, (unsigned int) -1);
00413 }
00414 return 0;
00415 }
00416 #endif
00417
00421 NUTSPIBUS spiBus0Avr32 = {
00422 NULL,
00423 NULL,
00424 AVR32_SPI0_ADDRESS,
00425 &sig_SPI0,
00426 Avr32SpiBusNodeInit,
00427 Avr32SpiBus0Select,
00428 Avr32SpiBus0Deselect,
00429 #if defined(SPIBUS0_POLLING_MODE)
00430 Avr32SpiBusPollTransfer,
00431 #elif defined(SPIBUS0_DOUBLE_BUFFER)
00432 Avr32SpiBusDblBufTransfer,
00433 #else
00434 Avr32SpiBus0Transfer,
00435 #endif
00436 #ifdef SPIBUS0_DOUBLE_BUFFER
00437 Avr32SpiBusWait,
00438 #else
00439 NutSpiBusWait,
00440 #endif
00441 NutSpiBusSetMode,
00442 NutSpiBusSetRate,
00443 NutSpiBusSetBits
00444 };