spi_7seg.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2009 by egnite GmbH
00003  * Copyright (C) 2006 by egnite Software GmbH
00004  *
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the copyright holders nor the names of
00017  *    contributors may be used to endorse or promote products derived
00018  *    from this software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00027  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00028  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00029  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00030  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  * For additional information see http://www.ethernut.de/
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 /* shutdown register (0x0c) */
00079 #define SHUTDOWN_RESET  0x00
00080 #define SHUTDOWN_SOFT   0x80
00081 #define NORM_OP_RESET   0x01
00082 #define NORM_OP_SOFT    0x81
00083 
00084 /* decode en register (0x09) */
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 /* scan limit register (0x0b) */
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     /* write address */
00171      cmd[0] = addr;
00172     
00173     tmp = (uint8_t *)txbuf;
00174     /* write data */
00175      cmd[1] = tmp[0];
00176     //cmd[1] = (uint8_t )txbuf[0];
00177     /* write data */
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 //  uint8_t cmd;
00204 //  int rc;
00205  //   NUTBLOCKIO *blkio;
00206     NUTSPINODE *node;
00207    // uint8_t sr;
00208     //int_fast8_t i;
00209 
00210     NUTASSERT(dev != NULL);
00211     NUTASSERT(dev->dev_dcb != NULL);
00212     NUTASSERT(dev->dev_icb != NULL);
00213     //blkio = dev->dev_dcb;
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     /* '0' */(0x7E),
00249     /* '1' */(0x30),
00250     /* '2' */(0x6D),
00251     /* '3' */(0x79),
00252     /* '4' */(0x33),
00253     /* '5' */(0x5B),
00254     /* '6' */(0x5F),
00255     /* '7' */(0x70),
00256     /* '8' */(0x7F),
00257     /* '9' */(0x7B),
00258     /* 'A' */(0x77),
00259     /* 'b' */(0x1F),
00260     /* 'c' */(0x0D),
00261     /* 'd' */(0x3D),
00262     /* 'E' */(0x4F),
00263     /* 'F' */(0x47),
00264     /* 'G' */(0x5F),
00265     /* 'H' */(0x37),
00266     /* 'i' */(0x10),
00267     /* 'J' */(0x3C),
00268     /* 'K' */(0x0F),
00269     /* 'L' */(0x0E),
00270     /* 'M' */(0x76),
00271     /* 'N' */(0x15),
00272     /* 'O' */(0x1D),
00273     /* 'P' */(0x67),
00274     /* 'Q' */(0x73),
00275     /* 'R' */(0x05),
00276     /* 'S' */(0x5B),
00277     /* 'T' */(0x0F),
00278     /* 'U' */(0x3E),
00279     /* 'V' */(0x1C),
00280     /* 'W' */(0x3F),
00281     /* 'X' */(0x37),
00282     /* 'Y' */(0x3B),
00283     /* 'Z' */(0x6D),
00284     /* '-' */(0x01),
00285     /*set point on lower right side*/
00286 //  {'.', (unsigned char)DISPL_DP},
00287     /*unset point on lower right side*/
00288 //  {'^', (unsigned char)~(DISPL_DP)},
00289     /*
00290     switch all segments off
00291     NOTE do not remove the line below!
00292     */
00293 //  {' ', (unsigned char)DISPL_OFF},
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         {/*distance between 0 and 99,9 meters*/
00307            display[HUNDRED]        = number / 100;
00308            display[TENNER]              = (number % 100) / 10;
00309            display[ANY]     = (number % 100) % 10;
00310         }
00311     else 
00312         {
00313          /*TODO FEHLER anzeigen */
00314         }
00315        
00316 
00317     for (next=0;next < 3;next++)
00318     {
00319         disp7segCommand(node,  2-next+1, &CharLookup[display[next]], NULL, 1);
00320         // printf("addr: %d data:0x%2X\n",2-next+1,CharLookup[display[next]] );
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         //save char independent of decimal point
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 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/