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
00045 #include <cfg/os.h>
00046
00047 #include <sys/nutdebug.h>
00048 #include <sys/timer.h>
00049
00050 #include <string.h>
00051 #include <stdio.h>
00052
00053
00054
00055 #define SEG_NOOP 0x00
00056 #define SEG_DIG0 0x01
00057 #define SEG_DIG1 0x02
00058 #define SEG_DIG2 0x03
00059 #define SEG_DIG3 0x04
00060 #define SEG_DIG4 0x05
00061 #define SEG_DIG5 0x06
00062 #define SEG_DIG6 0x07
00063 #define SEG_DIG7 0x08
00064 #define SEG_DEC_MODE 0x09
00065 #define SEG_INTENSITY 0x0a
00066 #define SEG_SCAN_LIM 0x0b
00067 #define SEG_SHUTDOWN 0x0c
00068 #define SEG_FEATURE 0x0e
00069 #define SEG_DSP_TEST 0x0f
00070
00071
00072 #define SHUTDOWN_RESET 0x00
00073 #define SHUTDOWN_SOFT 0x80
00074 #define NORM_OP_RESET 0x01
00075 #define NORM_OP_SOFT 0x81
00076
00077
00078 #define NO_DIG_DECODE 0x00
00079 #define DIG_0_DECODE 0x01
00080 #define DIG_0_3_DECODE 0x0f
00081 #define DIG_0_7_DECODE 0xff
00082
00083 #define TEST_MODE_OFF 0x00
00084 #define TEST_MODE_ON 0x01
00085
00086
00087 #define DISPLAY_LIMIT 2
00088
00089 #define MAX_7SEG_DIGITS 3
00090
00091
00092 #ifndef DISP_7SEG_WRITE_POLLS
00093 #define DISP_7SEG_WRITE_POLLS 1000
00094 #endif
00095
00096
00097
00098 #include <cfg/memory.h>
00099
00100 #include <dev/blockdev.h>
00101 #include <dev/spi_7seg.h>
00102
00103 #ifndef SPI_RATE_DISP_7SEG
00104 #define SPI_RATE_DISP_7SEG 1000000
00105
00106
00107
00108
00109 #endif
00110
00111 #ifndef SPI_MODE_DISP_7SEG
00112 #ifdef SPI_CSHIGH_DISP_7SEG
00113 #define SPI_MODE_DISP_7SEG (SPI_MODE_3 | SPI_MODE_CSHIGH)
00114 #else
00115 #define SPI_MODE_DISP_7SEG SPI_MODE_3
00116 #endif
00117 #endif
00118
00119 #include <cfg/arch/gpio.h>
00120 #include <dev/spibus_at91.h>
00121
00125 NUTSPINODE nodeSpi7SEG = {
00126 &NUT_CONFIG_7SEG_SPIBUS,
00127 NULL,
00128 SPI_RATE_DISP_7SEG,
00129 SPI_MODE_DISP_7SEG,
00130 8,
00131 NUT_CONFIG_7SEG_CS
00132 };
00133
00137 NUTDEVICE devSpi7SEG = {
00138 NULL,
00139 {'7', 'S', 'E', 'G', 0, 0, 0},
00140 IFTYP_BLKIO,
00141 0,
00142 0,
00143 &nodeSpi7SEG,
00144 0,
00145 Spi7segInit,
00146 0,
00147 0,
00148 0,
00149 #ifdef __HARVARD_ARCH__
00150 0,
00151 #endif
00152 0,
00153 0,
00154 0
00155 };
00156
00166 static int disp7segCommand(NUTSPINODE * node, uint8_t addr, CONST void *txbuf, void *rxbuf, int xlen)
00167 {
00168 int rc = -1;
00169 NUTSPIBUS *bus;
00170 uint8_t *tmp;
00171 uint8_t cmd[2];
00172
00173 NUTASSERT(node != NULL);
00174 bus = (NUTSPIBUS *) node->node_bus;
00175 NUTASSERT(bus != NULL);
00176 NUTASSERT(bus->bus_alloc != NULL);
00177 NUTASSERT(bus->bus_transfer != NULL);
00178 NUTASSERT(bus->bus_release != NULL);
00179
00180
00181 cmd[0] = addr;
00182
00183 tmp = (uint8_t *)txbuf;
00184
00185 cmd[1] = tmp[0];
00186
00187
00188 rc = (*bus->bus_alloc) (node, 1000);
00189 if (rc == 0) {
00190 rc = (*bus->bus_transfer) (node, cmd, NULL, 2);
00191
00192 (*bus->bus_release) (node);
00193 }
00194 return rc;
00195 }
00196
00197
00210 int Spi7segInit(NUTDEVICE * dev)
00211 {
00212 uint8_t data;
00213
00214
00215
00216 NUTSPINODE *node;
00217
00218
00219
00220 NUTASSERT(dev != NULL);
00221 NUTASSERT(dev->dev_dcb != NULL);
00222 NUTASSERT(dev->dev_icb != NULL);
00223
00224 node = dev->dev_icb;
00225 data = TEST_MODE_OFF;
00226 disp7segCommand(node, SEG_DSP_TEST, &data, NULL, 1);
00227
00228 disp7segCommand(node, SEG_DSP_TEST, &data, NULL, 1);
00229
00230 disp7segCommand(node, SEG_DSP_TEST, &data, NULL, 1);
00231
00232 data = NORM_OP_RESET;
00233 disp7segCommand(node, SEG_SHUTDOWN, &data, NULL, 1);
00234
00235 data = 2;
00236 disp7segCommand(node, SEG_SCAN_LIM, &data, NULL, 1);
00237
00238 data = NO_DIG_DECODE;
00239 disp7segCommand(node, SEG_DEC_MODE, &data, NULL, 1);
00240
00241 data = 0x0F;
00242 disp7segCommand(node, SEG_INTENSITY, &data, NULL, 1);
00243
00244 data = 0;
00245 disp7segCommand(node, SEG_DIG0, &data, NULL, 1);
00246
00247 disp7segCommand(node, SEG_DIG1, &data, NULL, 1);
00248
00249 disp7segCommand(node, SEG_DIG2, &data, NULL, 1);
00250
00251 return 0;
00252
00253 }
00254
00255
00256
00257 static const unsigned char CharLookup[] = {
00258 (0x7E),
00259 (0x30),
00260 (0x6D),
00261 (0x79),
00262 (0x33),
00263 (0x5B),
00264 (0x5F),
00265 (0x70),
00266 (0x7F),
00267 (0x7B),
00268 (0x77),
00269 (0x1F),
00270 (0x0D),
00271 (0x3D),
00272 (0x4F),
00273 (0x47),
00274 (0x5F),
00275 (0x37),
00276 (0x10),
00277 (0x3C),
00278 (0x0F),
00279 (0x0E),
00280 (0x76),
00281 (0x15),
00282 (0x1D),
00283 (0x67),
00284 (0x73),
00285 (0x05),
00286 (0x5B),
00287 (0x0F),
00288 (0x3E),
00289 (0x1C),
00290 (0x3F),
00291 (0x37),
00292 (0x3B),
00293 (0x6D),
00294 (0x01),
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 };
00305 #define HUNDRED 2
00306 #define TENNER 1
00307 #define ANY 0
00308 void display_7seg(NUTDEVICE * dev, uint16_t number)
00309 {
00310 uint8_t display[3], next=0;
00311 NUTSPINODE *node;
00312 NUTASSERT(dev->dev_icb != NULL);
00313 node = dev->dev_icb;
00314
00315 if (number< 1000)
00316 {
00317 display[HUNDRED] = number / 100;
00318 display[TENNER] = (number % 100) / 10;
00319 display[ANY] = (number % 100) % 10;
00320 }
00321 else
00322 {
00323
00324 }
00325
00326
00327 for (next=0;next < 3;next++)
00328 {
00329 disp7segCommand(node, 2-next+1, &CharLookup[display[next]], NULL, 1);
00330
00331 }
00332 }
00333
00334 uint8_t display_buffer[MAX_7SEG_DIGITS] = { 0, 0, 0 };
00335
00336 void print_7seg(NUTDEVICE *dev, char* chars)
00337 {
00338 uint8_t count=0;
00339 NUTSPINODE *node;
00340 NUTASSERT(dev->dev_icb != NULL);
00341 node = dev->dev_icb;
00342 for(count=0; count<MAX_7SEG_DIGITS; count++)
00343 {
00344 uint8_t display = 0;
00345 if(chars[count] == 0)
00346 {
00347 break;
00348 }
00349 else if(chars[count] >= '0' && chars[count] <= '9')
00350 {
00351 display = CharLookup[chars[count] - '0'];
00352 }
00353 else if(chars[count] >= 'A' && chars[count] <= 'Z')
00354 {
00355 display = CharLookup[chars[count] - 'A' + 10];
00356 }
00357 else if(chars[count] >= 'a' && chars[count] <= 'z')
00358 {
00359 display = CharLookup[chars[count] - 'a' + 10];
00360 }
00361 else if(chars[count] == '-')
00362 {
00363 display = CharLookup[36];
00364 }
00365
00366 display_buffer[count] &= 0x80;
00367 display_buffer[count] |= (display & 0x7F);
00368 disp7segCommand(node, MAX_7SEG_DIGITS-count, &(display_buffer[count]), NULL, 1);
00369 }
00370 }
00371
00372 void dot_7seg(NUTDEVICE *dev, uint8_t dotNumber, uint8_t dotCommand)
00373 {
00374 uint8_t count=0;
00375 NUTSPINODE *node;
00376 NUTASSERT(dev->dev_icb != NULL);
00377 node = dev->dev_icb;
00378 if(dotNumber<MAX_7SEG_DIGITS)
00379 {
00380 switch(dotCommand)
00381 {
00382 case DOT_7SEG_SET:
00383 display_buffer[MAX_7SEG_DIGITS-dotNumber-1] |= 0x80;
00384 break;
00385 case DOT_7SEG_CLEAR:
00386 display_buffer[MAX_7SEG_DIGITS-dotNumber-1] &= 0x7F;
00387 break;
00388 case DOT_7SEG_FLIP:
00389 display_buffer[MAX_7SEG_DIGITS-dotNumber-1] ^= 0x80;
00390 break;
00391 default:
00392 break;
00393 }
00394 }
00395 for(count=0; count<MAX_7SEG_DIGITS; count++)
00396 {
00397 disp7segCommand(node, MAX_7SEG_DIGITS-count, &(display_buffer[count]), NULL, 1);
00398 }
00399 }