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
00044 #include <cfg/spi.h>
00045 #include <cfg/arch/gpio.h>
00046
00047 #include <dev/gpio.h>
00048 #include <dev/spibus_gpio.h>
00049 #include <sys/event.h>
00050 #include <sys/timer.h>
00051 #include <sys/nutdebug.h>
00052
00053 #include <errno.h>
00054 #include <stdlib.h>
00055
00056
00057 #if defined(SBBI0_MISO_BIT) && !defined(SBBI0_MISO_PORT)
00058 #define SBBI0_MISO_PORT NUTGPIO_PORT
00059 #endif
00060 #if defined(SBBI0_MOSI_BIT) && !defined(SBBI0_MOSI_PORT)
00061 #define SBBI0_MOSI_PORT NUTGPIO_PORT
00062 #endif
00063 #if defined(SBBI0_SCK_BIT) && !defined(SBBI0_SCK_PORT)
00064 #define SBBI0_SCK_PORT NUTGPIO_PORT
00065 #endif
00066 #if defined(SBBI0_CS0_BIT) && !defined(SBBI0_CS0_PORT)
00067 #define SBBI0_CS0_PORT NUTGPIO_PORT
00068 #endif
00069 #if defined(SBBI0_CS1_BIT) && !defined(SBBI0_CS1_PORT)
00070 #define SBBI0_CS1_PORT NUTGPIO_PORT
00071 #endif
00072 #if defined(SBBI0_CS2_BIT) && !defined(SBBI0_CS2_PORT)
00073 #define SBBI0_CS2_PORT NUTGPIO_PORT
00074 #endif
00075 #if defined(SBBI0_CS3_BIT) && !defined(SBBI0_CS3_PORT)
00076 #define SBBI0_CS3_PORT NUTGPIO_PORT
00077 #endif
00078
00079 static GSPIREG gspi_reg0;
00080 #if defined(SBBI0_CS1_BIT)
00081 static GSPIREG gspi_reg1;
00082 #endif
00083 #if defined(SBBI0_CS2_BIT)
00084 static GSPIREG gspi_reg2;
00085 #endif
00086 #if defined(SBBI0_CS3_BIT)
00087 static GSPIREG gspi_reg3;
00088 #endif
00089
00093 static GSPIREG *GpioSpi0ChipSelect(uint_fast8_t cs, uint_fast8_t hi)
00094 {
00095 GSPIREG *rc;
00096
00097 switch (cs) {
00098 case 0:
00099
00100 #if defined(SBBI0_CS0_BIT)
00101 GpioPinSet(SBBI0_CS0_PORT, SBBI0_CS0_BIT, hi);
00102 GpioPinConfigSet(SBBI0_CS0_PORT, SBBI0_CS0_BIT, GPIO_CFG_OUTPUT);
00103 #endif
00104 rc = &gspi_reg0;
00105 break;
00106 #if defined(SBBI0_CS1_BIT)
00107 case 1:
00108 GpioPinSet(SBBI0_CS1_PORT, SBBI0_CS1_BIT, hi);
00109 GpioPinConfigSet(SBBI0_CS1_PORT, SBBI0_CS1_BIT, GPIO_CFG_OUTPUT);
00110 rc = &gspi_reg1;
00111 break;
00112 #endif
00113 #if defined(SBBI0_CS2_BIT)
00114 case 2:
00115 GpioPinSet(SBBI0_CS2_PORT, SBBI0_CS2_BIT, hi);
00116 GpioPinConfigSet(SBBI0_CS2_PORT, SBBI0_CS2_BIT, GPIO_CFG_OUTPUT);
00117 rc = &gspi_reg2;
00118 break;
00119 #endif
00120 #if defined(SBBI0_CS3_BIT)
00121 case 3:
00122 GpioPinSet(SBBI0_CS3_PORT, SBBI0_CS3_BIT, hi);
00123 GpioPinConfigSet(SBBI0_CS3_PORT, SBBI0_CS3_BIT, GPIO_CFG_OUTPUT);
00124 rc = &gspi_reg3;
00125 break;
00126 #endif
00127 default:
00128 errno = EIO;
00129 rc = NULL;
00130 break;
00131 }
00132 return rc;
00133 }
00134
00135
00136 static void SpiMode0Transfer(GSPIREG *gspi, CONST uint8_t *txbuf, uint8_t *rxbuf, int xlen)
00137 {
00138 #if defined(SBBI0_SCK_BIT)
00139 uint_fast8_t mask;
00140
00141 while (xlen--) {
00142 for (mask = 0x80; mask; mask >>= 1) {
00143 #if defined(SBBI0_MOSI_BIT)
00144 if (txbuf) {
00145 GpioPinSet(SBBI0_MOSI_PORT, SBBI0_MOSI_BIT, (*txbuf & mask) != 0);
00146 }
00147 #endif
00148 NutMicroDelay(gspi->gspi_dly_rate);
00149 GpioPinSetHigh(SBBI0_SCK_PORT, SBBI0_SCK_BIT);
00150 #if defined(SBBI0_MISO_BIT)
00151 if (rxbuf) {
00152 if (GpioPinGet(SBBI0_MISO_PORT, SBBI0_MISO_BIT)) {
00153 *rxbuf |= mask;
00154 }
00155 else {
00156 *rxbuf &= ~mask;
00157 }
00158 }
00159 #endif
00160 NutMicroDelay(gspi->gspi_dly_rate);
00161 GpioPinSetLow(SBBI0_SCK_PORT, SBBI0_SCK_BIT);
00162 }
00163 if (txbuf) {
00164 txbuf++;
00165 }
00166 if (rxbuf) {
00167 rxbuf++;
00168 }
00169 }
00170 #endif
00171 }
00172
00173
00174 static void SpiMode1Transfer(GSPIREG *gspi, CONST uint8_t *txbuf, uint8_t *rxbuf, int xlen)
00175 {
00176 #if defined(SBBI0_SCK_BIT)
00177 uint_fast8_t mask;
00178
00179 while (xlen--) {
00180 for (mask = 0x80; mask; mask >>= 1) {
00181 NutMicroDelay(gspi->gspi_dly_rate);
00182 GpioPinSetHigh(SBBI0_SCK_PORT, SBBI0_SCK_BIT);
00183 #if defined(SBBI0_MOSI_BIT)
00184 if (txbuf) {
00185 GpioPinSet(SBBI0_MOSI_PORT, SBBI0_MOSI_BIT, (*txbuf & mask) != 0);
00186 }
00187 #endif
00188 NutMicroDelay(gspi->gspi_dly_rate);
00189 GpioPinSetLow(SBBI0_SCK_PORT, SBBI0_SCK_BIT);
00190 #if defined(SBBI0_MISO_BIT)
00191 if (rxbuf) {
00192 if (GpioPinGet(SBBI0_MISO_PORT, SBBI0_MISO_BIT)) {
00193 *rxbuf |= mask;
00194 }
00195 else {
00196 *rxbuf &= ~mask;
00197 }
00198 }
00199 #endif
00200 }
00201 if (txbuf) {
00202 txbuf++;
00203 }
00204 if (rxbuf) {
00205 rxbuf++;
00206 }
00207 }
00208 #endif
00209 }
00210
00211
00212 static void SpiMode2Transfer(GSPIREG *gspi, CONST uint8_t *txbuf, uint8_t *rxbuf, int xlen)
00213 {
00214 #if defined(SBBI0_SCK_BIT)
00215 uint_fast8_t mask;
00216
00217 while (xlen--) {
00218 for (mask = 0x80; mask; mask >>= 1) {
00219 #if defined(SBBI0_MOSI_BIT)
00220 if (txbuf) {
00221 GpioPinSet(SBBI0_MOSI_PORT, SBBI0_MOSI_BIT, (*txbuf & mask) != 0);
00222 }
00223 #endif
00224 NutMicroDelay(gspi->gspi_dly_rate);
00225 GpioPinSetLow(SBBI0_SCK_PORT, SBBI0_SCK_BIT);
00226 #if defined(SBBI0_MISO_BIT)
00227 if (rxbuf) {
00228 if (GpioPinGet(SBBI0_MISO_PORT, SBBI0_MISO_BIT)) {
00229 *rxbuf |= mask;
00230 }
00231 else {
00232 *rxbuf &= ~mask;
00233 }
00234 }
00235 #endif
00236 NutMicroDelay(gspi->gspi_dly_rate);
00237 GpioPinSetHigh(SBBI0_SCK_PORT, SBBI0_SCK_BIT);
00238 }
00239 if (txbuf) {
00240 txbuf++;
00241 }
00242 if (rxbuf) {
00243 rxbuf++;
00244 }
00245 }
00246 #endif
00247 }
00248
00249
00250 static void SpiMode3Transfer(GSPIREG *gspi, CONST uint8_t *txbuf, uint8_t *rxbuf, int xlen)
00251 {
00252 #if defined(SBBI0_SCK_BIT)
00253 uint_fast8_t mask;
00254
00255 while (xlen--) {
00256 for (mask = 0x80; mask; mask >>= 1) {
00257 NutMicroDelay(gspi->gspi_dly_rate);
00258 GpioPinSetLow(SBBI0_SCK_PORT, SBBI0_SCK_BIT);
00259 #if defined(SBBI0_MOSI_BIT)
00260 if (txbuf) {
00261 GpioPinSet(SBBI0_MOSI_PORT, SBBI0_MOSI_BIT, (*txbuf & mask) != 0);
00262 }
00263 #endif
00264 NutMicroDelay(gspi->gspi_dly_rate);
00265 GpioPinSetHigh(SBBI0_SCK_PORT, SBBI0_SCK_BIT);
00266 #if defined(SBBI0_MISO_BIT)
00267 if (rxbuf) {
00268 if (GpioPinGet(SBBI0_MISO_PORT, SBBI0_MISO_BIT)) {
00269 *rxbuf |= mask;
00270 }
00271 else {
00272 *rxbuf &= ~mask;
00273 }
00274 }
00275 #endif
00276 }
00277 if (txbuf) {
00278 txbuf++;
00279 }
00280 if (rxbuf) {
00281 rxbuf++;
00282 }
00283 }
00284 #endif
00285 }
00286
00301 int GpioSpiBus0Transfer(NUTSPINODE * node, CONST void *txbuf, void *rxbuf, int xlen)
00302 {
00303 GSPIREG *gspi;
00304
00305
00306 NUTASSERT(node != NULL);
00307 NUTASSERT(node->node_stat != NULL);
00308 gspi = (GSPIREG *)node->node_stat;
00309
00310
00311
00312 switch (node->node_mode & SPI_MODE_3) {
00313 case SPI_MODE_0:
00314 SpiMode0Transfer(gspi, txbuf, rxbuf, xlen);
00315 break;
00316 case SPI_MODE_1:
00317 SpiMode1Transfer(gspi, txbuf, rxbuf, xlen);
00318 break;
00319 case SPI_MODE_2:
00320 SpiMode2Transfer(gspi, txbuf, rxbuf, xlen);
00321 break;
00322 case SPI_MODE_3:
00323 SpiMode3Transfer(gspi, txbuf, rxbuf, xlen);
00324 break;
00325 }
00326 return 0;
00327 }
00328
00339 int GpioSpiBus0NodeInit(NUTSPINODE * node)
00340 {
00341
00342 NUTASSERT(node != NULL);
00343
00344
00345 node->node_stat = GpioSpi0ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) == 0);
00346 if (node->node_stat == NULL) {
00347
00348 return -1;
00349 }
00350 return GpioSpiSetup(node);
00351 }
00352
00364 int GpioSpiBus0Select(NUTSPINODE * node, uint32_t tmo)
00365 {
00366 int rc;
00367
00368
00369 NUTASSERT(node != NULL);
00370 NUTASSERT(node->node_stat != NULL);
00371
00372
00373 rc = NutEventWait(&node->node_bus->bus_mutex, tmo);
00374 if (rc) {
00375 errno = EIO;
00376 } else {
00377
00378 if (node->node_mode & SPI_MODE_UPDATE) {
00379 GpioSpiSetup(node);
00380 }
00381
00382 #if defined(SBBI0_SCK_BIT)
00383 GpioPinSetLow(SBBI0_SCK_PORT, (node->node_mode & SPI_MODE_CPOL) != 0);
00384 GpioPinConfigSet(SBBI0_SCK_PORT, SBBI0_SCK_BIT, GPIO_CFG_OUTPUT);
00385 #endif
00386
00387 #if defined(SBBI0_MOSI_BIT)
00388 GpioPinConfigSet(SBBI0_MOSI_PORT, SBBI0_MOSI_BIT, GPIO_CFG_OUTPUT);
00389 #endif
00390 #if defined(SBBI0_MISO_BIT)
00391 GpioPinConfigSet(SBBI0_MISO_PORT, SBBI0_MISO_BIT, 0);
00392 #endif
00393
00394 if (GpioSpi0ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) != 0) == NULL) {
00395
00396 NutEventPost(&node->node_bus->bus_mutex);
00397 rc = -1;
00398 }
00399 }
00400 return rc;
00401 }
00402
00411 int GpioSpiBus0Deselect(NUTSPINODE * node)
00412 {
00413
00414 NUTASSERT(node != NULL);
00415 NUTASSERT(node->node_bus != NULL);
00416
00417
00418 GpioSpi0ChipSelect(node->node_cs, (node->node_mode & SPI_MODE_CSHIGH) == 0);
00419
00420
00421 NutEventPost(&node->node_bus->bus_mutex);
00422
00423 return 0;
00424 }
00425
00429 NUTSPIBUS spiBus0Gpio = {
00430 NULL,
00431 NULL,
00432 0,
00433 NULL,
00434 GpioSpiBus0NodeInit,
00435 GpioSpiBus0Select,
00436 GpioSpiBus0Deselect,
00437 GpioSpiBus0Transfer,
00438 NutSpiBusWait,
00439 NutSpiBusSetMode,
00440 NutSpiBusSetRate,
00441 NutSpiBusSetBits
00442 };