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