Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00047 #include <cfg/spi.h>
00048 #include <cfg/arch/gpio.h>
00049
00050 #include <dev/spibus_at91.h>
00051 #include <dev/irqreg.h>
00052 #include <sys/event.h>
00053 #include <sys/nutdebug.h>
00054
00055 #include <stdlib.h>
00056 #include <errno.h>
00057
00058 #if defined(SPI1_PIO_BASE)
00059
00060 #if defined(SPI1_CS0_PIO_BIT)
00061 #if defined(SPI1_CS0_PIO_ID)
00062 #undef GPIO_ID
00063 #define GPIO_ID SPI1_CS0_PIO_ID
00064 #include <cfg/arch/porttran.h>
00065 static INLINE void SPI1_CS0_LO(void)
00066 {
00067 GPIO_SET_LO(SPI1_CS0_PIO_BIT);
00068 }
00069
00070 static INLINE void SPI1_CS0_HI(void)
00071 {
00072 GPIO_SET_HI(SPI1_CS0_PIO_BIT);
00073 }
00074
00075 static INLINE void SPI1_CS0_SO(void)
00076 {
00077 GPIO_ENABLE(SPI1_CS0_PIO_BIT);
00078 GPIO_OUTPUT(SPI1_CS0_PIO_BIT);
00079 }
00080 #else
00081 #define SPI1_CS0_LO()
00082 #define SPI1_CS0_HI()
00083 #define SPI1_CS0_SO()
00084 #endif
00085 #endif
00086
00087 #if defined(SPI1_CS1_PIO_BIT)
00088 #if defined(SPI1_CS1_PIO_ID)
00089 #undef GPIO_ID
00090 #define GPIO_ID SPI1_CS1_PIO_ID
00091 #include <cfg/arch/porttran.h>
00092 static INLINE void SPI1_CS1_LO(void)
00093 {
00094 GPIO_SET_LO(SPI1_CS1_PIO_BIT);
00095 }
00096
00097 static INLINE void SPI1_CS1_HI(void)
00098 {
00099 GPIO_SET_HI(SPI1_CS1_PIO_BIT);
00100 }
00101
00102 static INLINE void SPI1_CS1_SO(void)
00103 {
00104 GPIO_ENABLE(SPI1_CS1_PIO_BIT);
00105 GPIO_OUTPUT(SPI1_CS1_PIO_BIT);
00106 }
00107 #else
00108 #define SPI1_CS1_LO()
00109 #define SPI1_CS1_HI()
00110 #define SPI1_CS1_SO()
00111 #endif
00112 #endif
00113
00114 #if defined(SPI1_CS2_PIO_BIT)
00115 #if defined(SPI1_CS2_PIO_ID)
00116 #undef GPIO_ID
00117 #define GPIO_ID SPI1_CS2_PIO_ID
00118 #include <cfg/arch/porttran.h>
00119 static INLINE void SPI1_CS2_LO(void)
00120 {
00121 GPIO_SET_LO(SPI1_CS2_PIO_BIT);
00122 }
00123
00124 static INLINE void SPI1_CS2_HI(void)
00125 {
00126 GPIO_SET_HI(SPI1_CS2_PIO_BIT);
00127 }
00128
00129 static INLINE void SPI1_CS2_SO(void)
00130 {
00131 GPIO_ENABLE(SPI1_CS2_PIO_BIT);
00132 GPIO_OUTPUT(SPI1_CS2_PIO_BIT);
00133 }
00134 #else
00135 #define SPI1_CS2_LO()
00136 #define SPI1_CS2_HI()
00137 #define SPI1_CS2_SO()
00138 #endif
00139 #endif
00140
00141 #if defined(SPI1_CS3_PIO_BIT)
00142 #if defined(SPI1_CS3_PIO_ID)
00143 #undef GPIO_ID
00144 #define GPIO_ID SPI1_CS3_PIO_ID
00145 #include <cfg/arch/porttran.h>
00146 static INLINE void SPI1_CS3_LO(void)
00147 {
00148 GPIO_SET_LO(SPI1_CS3_PIO_BIT);
00149 }
00150
00151 static INLINE void SPI1_CS3_HI(void)
00152 {
00153 GPIO_SET_HI(SPI1_CS3_PIO_BIT);
00154 }
00155
00156 static INLINE void SPI1_CS3_SO(void)
00157 {
00158 GPIO_ENABLE(SPI1_CS3_PIO_BIT);
00159 GPIO_OUTPUT(SPI1_CS3_PIO_BIT);
00160 }
00161 #else
00162 #define SPI1_CS3_LO()
00163 #define SPI1_CS3_HI()
00164 #define SPI1_CS3_SO()
00165 #endif
00166 #endif
00167
00171 int At91Spi1ChipSelect(uint_fast8_t cs, uint_fast8_t hi)
00172 {
00173 int rc = 0;
00174
00175 switch (cs) {
00176 #if defined(SPI1_CS0_PIO_BIT)
00177 case 0:
00178 if (hi) {
00179 SPI1_CS0_HI();
00180 } else {
00181 SPI1_CS0_LO();
00182 }
00183 SPI1_CS0_SO();
00184 break;
00185 #endif
00186 #if defined(SPI1_CS1_PIO_BIT)
00187 case 1:
00188 if (hi) {
00189 SPI1_CS1_HI();
00190 } else {
00191 SPI1_CS1_LO();
00192 }
00193 SPI1_CS1_SO();
00194 break;
00195 #endif
00196 #if defined(SPI1_CS2_PIO_BIT)
00197 case 2:
00198 if (hi) {
00199 SPI1_CS2_HI();
00200 } else {
00201 SPI1_CS2_LO();
00202 }
00203 SPI1_CS2_SO();
00204 break;
00205 #endif
00206 #if defined(SPI1_CS3_PIO_BIT)
00207 case 3:
00208 if (hi) {
00209 SPI1_CS3_HI();
00210 } else {
00211 SPI1_CS3_LO();
00212 }
00213 SPI1_CS3_SO();
00214 break;
00215 #endif
00216 default:
00217 errno = EIO;
00218 rc = -1;
00219 break;
00220 }
00221 return rc;
00222 }
00223
00235 int At91SpiBus1Select(NUTSPINODE * node, uint32_t tmo)
00236 {
00237 int rc;
00238
00239
00240 NUTASSERT(node != NULL);
00241 NUTASSERT(node->node_bus != NULL);
00242 NUTASSERT(node->node_stat != NULL);
00243
00244
00245 rc = NutEventWait(&node->node_bus->bus_mutex, tmo);
00246 if (rc) {
00247 errno = EIO;
00248 } else {
00249 AT91SPIREG *spireg = node->node_stat;
00250
00251 outr(PMC_PCER, _BV(SPI1_ID));
00252
00253
00254 outr(SPI1_PIO_BASE + SPI1_PSR_OFF, SPI1_PINS);
00255 outr(SPI1_PIO_BASE + PIO_PDR_OFF, SPI1_PINS);
00256
00257
00258 if (node->node_mode & SPI_MODE_UPDATE) {
00259 At91SpiSetup(node);
00260 }
00261
00262
00263 outr(SPI1_CR, SPI_SPIEN);
00264
00265 outr(SPI1_MR, spireg->at91spi_mr);
00266 outr(SPI1_CSR0 + node->node_cs * 4, spireg->at91spi_csr);
00267
00268
00269 rc = At91Spi1ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) != 0);
00270 if (rc) {
00271
00272 NutEventPost(&node->node_bus->bus_mutex);
00273 }
00274 }
00275 return rc;
00276 }
00277
00286 int At91SpiBus1Deselect(NUTSPINODE * node)
00287 {
00288
00289 NUTASSERT(node != NULL);
00290 NUTASSERT(node->node_bus != NULL);
00291
00292 #ifdef SPIBUS1_DOUBLE_BUFFER
00293 At91SpiBusWait(node, NUT_WAIT_INFINITE);
00294 #endif
00295
00296 At91Spi1ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) == 0);
00297
00298
00299 NutEventPost(&node->node_bus->bus_mutex);
00300
00301 return 0;
00302 }
00303
00304 #if !defined(SPIBUS1_POLLING_MODE) || !defined(SPIBUS1_DOUBLE_BUFFER)
00305
00306 static uint8_t * volatile spi1_txp;
00307 static uint8_t * volatile spi1_rxp;
00308 static volatile size_t spi1_xc;
00309
00310 void At91SpiBus1Interrupt(void *arg)
00311 {
00312 uint8_t b;
00313
00314
00315 b = inb(SPI1_RDR);
00316 if (spi1_xc) {
00317 if (spi1_rxp) {
00318 *spi1_rxp++ = b;
00319 }
00320 spi1_xc--;
00321 }
00322 if (spi1_xc) {
00323 if (spi1_txp) {
00324 b = *spi1_txp++;
00325 }
00326 outb(SPI1_TDR, b);
00327 } else {
00328 NutEventPostFromIrq((void **)arg);
00329 }
00330 }
00331
00346 int At91SpiBus1Transfer(NUTSPINODE * node, CONST void *txbuf, void *rxbuf, int xlen)
00347 {
00348 uint8_t b = 0xff;
00349 uintptr_t base;
00350
00351
00352 NUTASSERT(node != NULL);
00353 NUTASSERT(node->node_bus != NULL);
00354 NUTASSERT(node->node_bus->bus_base != 0);
00355 base = node->node_bus->bus_base;
00356
00357 if (xlen) {
00358 spi1_txp = (uint8_t *) txbuf;
00359 spi1_rxp = (uint8_t *) rxbuf;
00360 spi1_xc = (size_t) xlen;
00361 if (spi1_txp) {
00362 b = *spi1_txp++;
00363 }
00364
00365 outr(base + SPI_IER_OFF, SPI_RDRF);
00366 outr(base + SPI_TDR_OFF, b);
00367
00368 NutEventWait(&node->node_bus->bus_ready, NUT_WAIT_INFINITE);
00369 outr(base + SPI_IDR_OFF, (unsigned int) - 1);
00370 }
00371 return 0;
00372 }
00373 #endif
00374
00378 NUTSPIBUS spiBus1At91 = {
00379 NULL,
00380 NULL,
00381 SPI1_BASE,
00382 &sig_SPI1,
00383 At91SpiBusNodeInit,
00384 At91SpiBus1Select,
00385 At91SpiBus1Deselect,
00386 #if defined(SPIBUS1_POLLING_MODE)
00387 At91SpiBusPollTransfer,
00388 #elif defined(SPIBUS1_DOUBLE_BUFFER)
00389 At91SpiBusDblBufTransfer,
00390 #else
00391 At91SpiBus1Transfer,
00392 #endif
00393 #ifdef SPIBUS1_DOUBLE_BUFFER
00394 At91SpiBusWait,
00395 #else
00396 NutSpiBusWait,
00397 #endif
00398 NutSpiBusSetMode,
00399 NutSpiBusSetRate,
00400 NutSpiBusSetBits
00401 };
00402
00403 #endif