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
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #include <cfg/arch/avr.h>
00075
00076
00077
00078
00079
00080 #include <dev/spidigio.h>
00081
00082
00083
00084
00085 #ifndef SPIDIGIO_SOUT_BIT
00086 #define SPIDIGIO_SOUT_BIT 5
00087 #define SPIDIGIO_SOUT_AVRPORT AVRPORTD
00088 #define SPIDIGIO_SIN_BIT 6
00089 #define SPIDIGIO_SIN_AVRPORT AVRPORTD
00090 #define SPIDIGIO_SCLK_BIT 7
00091 #define SPIDIGIO_SCLK_AVRPORT AVRPORTD
00092 #define SPIDIGIO_LDI_BIT 7
00093 #define SPIDIGIO_LDI_AVRPORT AVRPORTB
00094 #define SPIDIGIO_LDO_BIT 5
00095 #define SPIDIGIO_LDO_AVRPORT AVRPORTB
00096 #endif
00097
00098 #if (SPIDIGIO_SOUT_AVRPORT == AVRPORTB)
00099 #define SPIDIGIO_SOUT_PORT PORTB
00100 #define SPIDIGIO_SOUT_DDR DDRB
00101
00102 #elif (SPIDIGIO_SOUT_AVRPORT == AVRPORTD)
00103 #define SPIDIGIO_SOUT_PORT PORTD
00104 #define SPIDIGIO_SOUT_DDR DDRD
00105
00106 #elif (SPIDIGIO_SOUT_AVRPORT == AVRPORTE)
00107 #define SPIDIGIO_SOUT_PORT PORTE
00108 #define SPIDIGIO_SOUT_DDR DDRE
00109
00110 #elif (SPIDIGIO_SOUT_AVRPORT == AVRPORTF)
00111 #define SPIDIGIO_SOUT_PORT PORTF
00112 #define SPIDIGIO_SOUT_DDR DDRF
00113
00114 #endif
00115
00116 #if (SPIDIGIO_SIN_AVRPORT == AVRPORTB)
00117 #define SPIDIGIO_SIN_PORT PORTB
00118 #define SPIDIGIO_SIN_PIN PINB
00119 #define SPIDIGIO_SIN_DDR DDRB
00120
00121 #elif (SPIDIGIO_SIN_AVRPORT == AVRPORTD)
00122 #define SPIDIGIO_SIN_PORT PORTD
00123 #define SPIDIGIO_SIN_PIN PIND
00124 #define SPIDIGIO_SIN_DDR DDRD
00125
00126 #elif (SPIDIGIO_SIN_AVRPORT == AVRPORTE)
00127 #define SPIDIGIO_SIN_PORT PORTE
00128 #define SPIDIGIO_SIN_PIN PINE
00129 #define SPIDIGIO_SIN_DDR DDRE
00130
00131 #elif (SPIDIGIO_SIN_AVRPORT == AVRPORTF)
00132 #define SPIDIGIO_SIN_PORT PORTF
00133 #define SPIDIGIO_SIN_PIN PINF
00134 #define SPIDIGIO_SIN_DDR DDRF
00135 #endif
00136
00137 #if (SPIDIGIO_SCLK_AVRPORT == AVRPORTB)
00138 #define SPIDIGIO_SCLK_PORT PORTB
00139 #define SPIDIGIO_SCLK_DDR DDRB
00140
00141 #elif (SPIDIGIO_SCLK_AVRPORT == AVRPORTD)
00142 #define SPIDIGIO_SCLK_PORT PORTD
00143 #define SPIDIGIO_SCLK_DDR DDRD
00144
00145 #elif (SPIDIGIO_SCLK_AVRPORT == AVRPORTE)
00146 #define SPIDIGIO_SCLK_PORT PORTE
00147 #define SPIDIGIO_SCLK_DDR DDRE
00148
00149 #elif (SPIDIGIO_SCLK_AVRPORT == AVRPORTF)
00150 #define SPIDIGIO_SCLK_PORT PORTF
00151 #define SPIDIGIO_SCLK_DDR DDRF
00152
00153 #endif
00154
00155 #if (SPIDIGIO_LDO_AVRPORT == AVRPORTB)
00156 #define SPIDIGIO_LDO_PORT PORTB
00157 #define SPIDIGIO_LDO_DDR DDRB
00158
00159 #elif (SPIDIGIO_LDO_AVRPORT == AVRPORTD)
00160 #define SPIDIGIO_LDO_PORT PORTD
00161 #define SPIDIGIO_LDO_DDR DDRD
00162
00163 #elif (SPIDIGIO_LDO_AVRPORT == AVRPORTE)
00164 #define SPIDIGIO_LDO_PORT PORTE
00165 #define SPIDIGIO_LDO_DDR DDRE
00166
00167 #elif (SPIDIGIO_LDO_AVRPORT == AVRPORTF)
00168 #define SPIDIGIO_LDO_PORT PORTF
00169 #define SPIDIGIO_LDO_DDR DDRF
00170
00171 #endif
00172
00173 #if (SPIDIGIO_LDI_AVRPORT == AVRPORTB)
00174 #define SPIDIGIO_LDI_PORT PORTB
00175 #define SPIDIGIO_LDI_DDR DDRB
00176
00177 #elif (SPIDIGIO_LDI_AVRPORT == AVRPORTD)
00178 #define SPIDIGIO_LDI_PORT PORTD
00179 #define SPIDIGIO_LDI_DDR DDRD
00180
00181 #elif (SPIDIGIO_LDI_AVRPORT == AVRPORTE)
00182 #define SPIDIGIO_LDI_PORT PORTE
00183 #define SPIDIGIO_LDI_DDR DDRE
00184
00185 #elif (SPIDIGIO_LDI_AVRPORT == AVRPORTF)
00186 #define SPIDIGIO_LDI_PORT PORTF
00187 #define SPIDIGIO_LDI_DDR DDRF
00188
00189 #endif
00190
00195
00196 static ureg_t us_loops = 1;
00197
00213 static INLINE void delay_us(ureg_t us)
00214 {
00215 ureg_t _cnt = us * us_loops;
00216
00217 while (_cnt--) {
00218
00219
00220
00221
00222
00223 _NOP();
00224 }
00225 }
00226
00238 static INLINE void ShiftDigital(void)
00239 {
00240
00241 cbi(SPIDIGIO_SCLK_PORT, SPIDIGIO_SCLK_BIT);
00242
00243 delay_us(4);
00244
00245
00246 sbi(SPIDIGIO_SCLK_PORT, SPIDIGIO_SCLK_BIT);
00247
00248 delay_us(4);
00249 }
00250
00269 u_long SpiDigitalGet(ureg_t num)
00270 {
00271 u_long bits = 0;
00272
00273 cbi(SPIDIGIO_SOUT_PORT, SPIDIGIO_SOUT_BIT);
00274
00275
00276
00277
00278
00279
00280 sbi(SPIDIGIO_LDI_PORT, SPIDIGIO_LDI_BIT);
00281 delay_us(4);
00282 cbi(SPIDIGIO_LDI_PORT, SPIDIGIO_LDI_BIT);
00283 delay_us(4);
00284
00285
00286 while (num--) {
00287
00288 bits <<= 1;
00289
00290
00291
00292
00293
00294
00295
00296 if (bit_is_set(SPIDIGIO_SIN_PIN, SPIDIGIO_SIN_BIT)) {
00297 bits |= 1;
00298 }
00299
00300
00301
00302
00303
00304 ShiftDigital();
00305 }
00306 return bits;
00307 }
00308
00323 void SpiDigitalSet(ureg_t num, u_long bits)
00324 {
00325 u_long mask;
00326
00327
00328 if (num) {
00329
00330
00331
00332
00333
00334
00335
00336 mask = 1UL << (num - 1);
00337
00338
00339 while (num--) {
00340
00341
00342
00343
00344
00345
00346
00347 if (bits & mask) {
00348
00349 sbi(SPIDIGIO_SOUT_PORT, SPIDIGIO_SOUT_BIT);
00350 }
00351 else {
00352
00353 cbi(SPIDIGIO_SOUT_PORT, SPIDIGIO_SOUT_BIT);
00354 }
00355
00356
00357 delay_us(4);
00358
00359
00360 ShiftDigital();
00361
00362
00363 mask >>= 1;
00364 }
00365
00366
00367
00368
00369
00370 cbi(SPIDIGIO_LDO_PORT, SPIDIGIO_LDO_BIT);
00371 delay_us(4);
00372 sbi(SPIDIGIO_LDO_PORT, SPIDIGIO_LDO_BIT);
00373 }
00374 }
00375
00401 static ureg_t CountDigitalShifts(ureg_t num, ureg_t bit, ureg_t smode)
00402 {
00403 ureg_t i;
00404 ureg_t rc = 0;
00405
00406
00407
00408
00409
00410 if (smode) {
00411 sbi(SPIDIGIO_LDI_PORT, SPIDIGIO_LDI_BIT);
00412 delay_us(4);
00413 cbi(SPIDIGIO_LDI_PORT, SPIDIGIO_LDI_BIT);
00414 }
00415
00416
00417
00418
00419 if (bit) {
00420 sbi(SPIDIGIO_SOUT_PORT, SPIDIGIO_SOUT_BIT);
00421 } else {
00422 cbi(SPIDIGIO_SOUT_PORT, SPIDIGIO_SOUT_BIT);
00423 }
00424 delay_us(4);
00425
00426
00427
00428
00429
00430 for (i = 0; i < num; i++) {
00431 if (bit_is_set(SPIDIGIO_SIN_PIN, SPIDIGIO_SIN_BIT)) {
00432 if (bit) {
00433 if (smode) {
00434 rc = i + 1;
00435 } else if (rc == 0) {
00436 rc = i + 1;
00437 }
00438 }
00439 } else {
00440 if (bit == 0) {
00441 if (smode) {
00442 rc = i + 1;
00443 } else if (rc == 0) {
00444 rc = i + 1;
00445 }
00446 }
00447 }
00448 ShiftDigital();
00449 }
00450 return rc;
00451 }
00452
00468 void SpiDigitalInit(ureg_t * inputs, ureg_t * outputs)
00469 {
00470 ureg_t total = 0;
00471 ureg_t i;
00472 ureg_t cnt;
00473
00474
00475
00476
00477 if ((us_loops = (NutGetCpuClock() + 500000UL) / 4000000UL) < 1) {
00478 us_loops = 1;
00479 }
00480
00481
00482
00483
00484 sbi(SPIDIGIO_SOUT_DDR, SPIDIGIO_SOUT_BIT);
00485
00486
00487
00488
00489 sbi(SPIDIGIO_SIN_PORT, SPIDIGIO_SIN_BIT);
00490 cbi(SPIDIGIO_SIN_DDR, SPIDIGIO_SIN_BIT);
00491
00492
00493
00494
00495
00496 sbi(SPIDIGIO_SCLK_PORT, SPIDIGIO_SCLK_BIT);
00497 sbi(SPIDIGIO_SCLK_DDR, SPIDIGIO_SCLK_BIT);
00498
00499
00500
00501
00502
00503 sbi(SPIDIGIO_LDO_PORT, SPIDIGIO_LDO_BIT);
00504 sbi(SPIDIGIO_LDO_DDR, SPIDIGIO_LDO_BIT);
00505
00506
00507
00508
00509
00510 cbi(SPIDIGIO_LDI_PORT, SPIDIGIO_LDI_BIT);
00511 sbi(SPIDIGIO_LDI_DDR, SPIDIGIO_LDI_BIT);
00512
00513
00514
00515
00516
00517
00518 CountDigitalShifts(32, 0, 0);
00519 total = CountDigitalShifts(32, 1, 0) - 1;
00520
00521
00522
00523
00524
00525
00526 *inputs = 0;
00527 for (i = 0; i < 5; i++) {
00528 if ((cnt = CountDigitalShifts(total, 0, 1)) > *inputs) {
00529 *inputs = cnt;
00530 }
00531 if ((cnt = CountDigitalShifts(total, 1, 1)) > *inputs) {
00532 *inputs = cnt;
00533 }
00534 }
00535 *outputs = total - *inputs;
00536 }
00537
00538