![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Fix to have load pin working with SPI1.
Fork of Max7221 by
Max7221.cpp@6:191569a26f50, 2015-11-19 (annotated)
- Committer:
- ky3orr
- Date:
- Thu Nov 19 23:58:07 2015 +0000
- Revision:
- 6:191569a26f50
- Parent:
- 5:1f3dbf38d027
- Child:
- 7:a160cb7cdd86
1st refactor to have library working with single SPI only.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jakowisp | 2:828c62cc1861 | 1 | /** |
jakowisp | 2:828c62cc1861 | 2 | * @file Max7221.cpp |
jakowisp | 2:828c62cc1861 | 3 | * @brief This file defines the Max7221 class methods and the default values for static variables |
jakowisp | 2:828c62cc1861 | 4 | * |
jakowisp | 2:828c62cc1861 | 5 | * @author Dwayne S. Dilbeck |
jakowisp | 2:828c62cc1861 | 6 | * |
jakowisp | 2:828c62cc1861 | 7 | * @date 8/6/2013 |
jakowisp | 2:828c62cc1861 | 8 | */ |
jakowisp | 1:d8589d1f368c | 9 | #include "mbed.h" |
jakowisp | 1:d8589d1f368c | 10 | #include "Max7221.h" |
jakowisp | 1:d8589d1f368c | 11 | |
jakowisp | 2:828c62cc1861 | 12 | ///Intialize the Class static members |
jakowisp | 2:828c62cc1861 | 13 | ///Devices used per SPI bus are set to ZERO |
ky3orr | 6:191569a26f50 | 14 | int Max7221::maxInUseSPI = 0; |
jakowisp | 2:828c62cc1861 | 15 | ///Set the static pointers to the SPI busses to NULL |
ky3orr | 6:191569a26f50 | 16 | SPI *Max7221::spi=NULL; |
jakowisp | 2:828c62cc1861 | 17 | ///Set the static pointers to the load signals to NULL |
ky3orr | 6:191569a26f50 | 18 | DigitalOut *Max7221::cs=NULL; |
jakowisp | 1:d8589d1f368c | 19 | |
jakowisp | 2:828c62cc1861 | 20 | /** |
jakowisp | 2:828c62cc1861 | 21 | * Constructor. This is the default constructor |
jakowisp | 2:828c62cc1861 | 22 | * @author Dwayne S. Dilbeck |
jakowisp | 2:828c62cc1861 | 23 | * @param msoi The SPI pin used as input to the device. Valid values for LPC1768 are p5 or p11 |
jakowisp | 2:828c62cc1861 | 24 | * @param mclk The SPI pin used as clock for the device. Valid values for LPC1768 are p7 or p13 |
jakowisp | 2:828c62cc1861 | 25 | * @param load The pin used to control load for the device. Any pin capable for DigitalOut can be used, but the same load pin must be used for |
jakowisp | 2:828c62cc1861 | 26 | * device that share the same msoi and mclk pins |
jakowisp | 2:828c62cc1861 | 27 | * @date 8/6/2013 |
jakowisp | 2:828c62cc1861 | 28 | */ |
jakowisp | 1:d8589d1f368c | 29 | Max7221::Max7221(PinName msoi, PinName mclk, PinName load){ |
ky3orr | 6:191569a26f50 | 30 | ///Set this insctance to pointers to the correct static pointers |
ky3orr | 6:191569a26f50 | 31 | this->id=maxInUseSPI; |
ky3orr | 6:191569a26f50 | 32 | this->maxInUse=&maxInUseSPI; |
ky3orr | 6:191569a26f50 | 33 | ///If no devices have been assigned to the SPI bus it must be initialized |
ky3orr | 6:191569a26f50 | 34 | if (spi ==NULL) { |
ky3orr | 6:191569a26f50 | 35 | spi = new SPI(msoi, NC, mclk); |
ky3orr | 6:191569a26f50 | 36 | cs = new DigitalOut(load); |
ky3orr | 6:191569a26f50 | 37 | } |
ky3orr | 6:191569a26f50 | 38 | this->max7221_spi= spi; |
ky3orr | 6:191569a26f50 | 39 | this->max7221_cs = cs; |
jakowisp | 1:d8589d1f368c | 40 | } |
jakowisp | 1:d8589d1f368c | 41 | |
jakowisp | 2:828c62cc1861 | 42 | /** |
jakowisp | 2:828c62cc1861 | 43 | * This method is used to write a byte of data to a specified register for only the device defined in this class instance |
jakowisp | 2:828c62cc1861 | 44 | * @author Dwayne S. Dilbeck |
jakowisp | 2:828c62cc1861 | 45 | * @param reg The register to write to. |
jakowisp | 2:828c62cc1861 | 46 | * @param data The value to be written. |
jakowisp | 2:828c62cc1861 | 47 | * @date 8/6/2013 |
jakowisp | 2:828c62cc1861 | 48 | *//** |
jakowisp | 2:828c62cc1861 | 49 | * This method is used to write a byte of data to a specified register for only the device defined in this class instance |
jakowisp | 2:828c62cc1861 | 50 | * @author Dwayne S. Dilbeck |
jakowisp | 2:828c62cc1861 | 51 | * @param reg The register to write to. |
jakowisp | 2:828c62cc1861 | 52 | * @param data The value to be written. |
jakowisp | 2:828c62cc1861 | 53 | * @date 8/6/2013 |
jakowisp | 2:828c62cc1861 | 54 | */ |
jakowisp | 2:828c62cc1861 | 55 | void Max7221::Write( unsigned int reg, unsigned int data) { |
jakowisp | 1:d8589d1f368c | 56 | int c = 0; |
ky3orr | 6:191569a26f50 | 57 | *cs = LOW; |
jakowisp | 1:d8589d1f368c | 58 | |
jakowisp | 2:828c62cc1861 | 59 | ///if there are multiple devices sharing the SPI buss and they preceed the current device in the cascade Write a NOOP to them |
jakowisp | 1:d8589d1f368c | 60 | for ( c = *maxInUse; c > this->id; c--) { |
ky3orr | 6:191569a26f50 | 61 | max7221_spi->write(0); // no-op |
ky3orr | 6:191569a26f50 | 62 | max7221_spi->write(0); // no-op |
jakowisp | 1:d8589d1f368c | 63 | } |
jakowisp | 2:828c62cc1861 | 64 | ///Write to this device registers |
ky3orr | 6:191569a26f50 | 65 | max7221_spi->write(reg); // specify register |
ky3orr | 6:191569a26f50 | 66 | max7221_spi->write(data); // put data |
jakowisp | 1:d8589d1f368c | 67 | |
jakowisp | 2:828c62cc1861 | 68 | ///if there are multiple devices sharing the SPI buss and they follow the current device in the cascade Write a NOOP to them |
jakowisp | 1:d8589d1f368c | 69 | for ( c=this->id-1; c >= 1; c--) { |
ky3orr | 6:191569a26f50 | 70 | max7221_spi->write(0); // no-op |
ky3orr | 6:191569a26f50 | 71 | max7221_spi->write(0); // no-op |
jakowisp | 1:d8589d1f368c | 72 | } |
ky3orr | 6:191569a26f50 | 73 | *cs = HIGH; |
jakowisp | 1:d8589d1f368c | 74 | } |
jakowisp | 1:d8589d1f368c | 75 | |
jakowisp | 2:828c62cc1861 | 76 | /** |
jakowisp | 2:828c62cc1861 | 77 | * This method is used to write an intial set off values to the device to prepare it for use. |
jakowisp | 2:828c62cc1861 | 78 | * @author Dwayne S. Dilbeck |
jakowisp | 2:828c62cc1861 | 79 | * @date 8/6/2013 |
jakowisp | 2:828c62cc1861 | 80 | */ |
jakowisp | 1:d8589d1f368c | 81 | void Max7221::Setup () { |
jakowisp | 2:828c62cc1861 | 82 | // initiation of the max 7221 |
jakowisp | 1:d8589d1f368c | 83 | // SPI setup: 8 bits, mode 0 |
ky3orr | 6:191569a26f50 | 84 | max7221_spi->format(8, 0); |
jakowisp | 1:d8589d1f368c | 85 | |
jakowisp | 1:d8589d1f368c | 86 | // going by the datasheet, min clk is 100ns so theoretically 10MHz should work... |
ky3orr | 6:191569a26f50 | 87 | max7221_spi->frequency(10*MHZ); |
jakowisp | 1:d8589d1f368c | 88 | |
jakowisp | 2:828c62cc1861 | 89 | Write(max7219_reg_scanLimit, 0x07); ///ENABLE all 8 digits |
jakowisp | 2:828c62cc1861 | 90 | Write(max7219_reg_decodeMode, 0xff); // Turn on Code B font decode for all digits |
jakowisp | 2:828c62cc1861 | 91 | Write(max7219_reg_shutdown, 0x01); // Disable shutdown mode |
jakowisp | 2:828c62cc1861 | 92 | Write(max7219_reg_displayTest, 0x00); // Disable display test |
jakowisp | 2:828c62cc1861 | 93 | for (int e=1; e<=8; e++) { // Write blank to all digits |
jakowisp | 1:d8589d1f368c | 94 | Write(e,0xf); |
jakowisp | 1:d8589d1f368c | 95 | } |
jakowisp | 2:828c62cc1861 | 96 | Write(max7219_reg_intensity, 0x01 ); // Set the display intensity to a low level. |
jakowisp | 1:d8589d1f368c | 97 | // range: 0x00 to 0x0f |
jakowisp | 1:d8589d1f368c | 98 | } |
jakowisp | 1:d8589d1f368c | 99 | |
jakowisp | 2:828c62cc1861 | 100 | /** |
jakowisp | 2:828c62cc1861 | 101 | * This method is used to write a byte of data to a specified register for all the devices instantiated. |
jakowisp | 2:828c62cc1861 | 102 | * @author Dwayne S. Dilbeck |
jakowisp | 2:828c62cc1861 | 103 | * @param reg The register to write to. |
jakowisp | 2:828c62cc1861 | 104 | * @param data The value to be written. |
jakowisp | 2:828c62cc1861 | 105 | * @date 8/6/2013 |
jakowisp | 2:828c62cc1861 | 106 | */ |
jakowisp | 2:828c62cc1861 | 107 | void Max7221::WriteAll (unsigned int reg, unsigned int data) { |
jakowisp | 2:828c62cc1861 | 108 | ///Write to all the devices on SPI Bus #1 first |
ky3orr | 6:191569a26f50 | 109 | if(cs !=NULL) { |
ky3orr | 6:191569a26f50 | 110 | *cs = LOW; // begin |
ky3orr | 6:191569a26f50 | 111 | for ( int c=1; c<= maxInUseSPI; c++) { |
ky3orr | 6:191569a26f50 | 112 | spi->write(reg); // specify register |
ky3orr | 6:191569a26f50 | 113 | spi->write(data); // put data |
jakowisp | 1:d8589d1f368c | 114 | } |
ky3orr | 6:191569a26f50 | 115 | *cs = HIGH; |
jakowisp | 1:d8589d1f368c | 116 | } |
jakowisp | 1:d8589d1f368c | 117 | } |
jakowisp | 2:828c62cc1861 | 118 | /** |
jakowisp | 2:828c62cc1861 | 119 | * This method is used to display an integer to the specified device instance. Underflow and overflow result in '-' written to all digits |
jakowisp | 2:828c62cc1861 | 120 | * @author Dwayne S. Dilbeck |
jakowisp | 2:828c62cc1861 | 121 | * @param value An integer value to display |
jakowisp | 2:828c62cc1861 | 122 | * @date 8/6/2013 |
jakowisp | 2:828c62cc1861 | 123 | */ |
jakowisp | 1:d8589d1f368c | 124 | void Max7221::WriteInt( int value ){ |
jakowisp | 1:d8589d1f368c | 125 | char buffer[16]; |
jakowisp | 1:d8589d1f368c | 126 | |
jakowisp | 2:828c62cc1861 | 127 | ///TODO:SET UPPERBOUND AND LOWERBOUND based on NUMDIGITS |
jakowisp | 2:828c62cc1861 | 128 | ///Check the the INT value can be displayed and convert to a string. |
jakowisp | 1:d8589d1f368c | 129 | if (value <= UPPERBOUND && value >= LOWERBOUND) { |
jakowisp | 1:d8589d1f368c | 130 | sprintf(buffer,"%8d",value); |
jakowisp | 1:d8589d1f368c | 131 | } else { |
jakowisp | 1:d8589d1f368c | 132 | sprintf(buffer,"--------"); |
jakowisp | 1:d8589d1f368c | 133 | } |
jakowisp | 2:828c62cc1861 | 134 | ///In case a program changed the decode mode, set it again. |
jakowisp | 1:d8589d1f368c | 135 | Write(max7219_reg_decodeMode, 0xff); |
jakowisp | 1:d8589d1f368c | 136 | for (int i=0;i<NUMDIGITS;i++) { |
jakowisp | 2:828c62cc1861 | 137 | ///For each character of the string, convert the ASCII to the datacode needed by the device |
jakowisp | 1:d8589d1f368c | 138 | switch(buffer[i]){ |
jakowisp | 1:d8589d1f368c | 139 | case 0x2d: buffer[i]=0xa; break; |
jakowisp | 1:d8589d1f368c | 140 | case 0x20: buffer[i]=0xf; break; |
jakowisp | 1:d8589d1f368c | 141 | default: buffer[i]= buffer[i] & 0x0f; |
jakowisp | 1:d8589d1f368c | 142 | } |
jakowisp | 2:828c62cc1861 | 143 | ///Call function to write the data for each character of the srting. |
jakowisp | 1:d8589d1f368c | 144 | Write(NUMDIGITS-i,buffer[i]); |
jakowisp | 1:d8589d1f368c | 145 | } |
jakowisp | 1:d8589d1f368c | 146 | } |
jakowisp | 1:d8589d1f368c | 147 | |
jakowisp | 2:828c62cc1861 | 148 | /** |
jakowisp | 2:828c62cc1861 | 149 | * This method is used to display a floating point number to the specified device instance. |
jakowisp | 2:828c62cc1861 | 150 | * Underflow and overflow result in '-' written to all digits. The digits after the decimal |
jakowisp | 2:828c62cc1861 | 151 | * point are truncated to fit the display. |
jakowisp | 2:828c62cc1861 | 152 | * @author Dwayne S. Dilbeck |
jakowisp | 2:828c62cc1861 | 153 | * @param value A float value to display |
jakowisp | 2:828c62cc1861 | 154 | * @date 8/6/2013 |
jakowisp | 2:828c62cc1861 | 155 | */ |
jakowisp | 1:d8589d1f368c | 156 | void Max7221::WriteFloat( float value ){ |
jakowisp | 1:d8589d1f368c | 157 | char buffer[32]; |
jakowisp | 1:d8589d1f368c | 158 | int ptr=-1,len; |
jakowisp | 1:d8589d1f368c | 159 | int i; |
jakowisp | 1:d8589d1f368c | 160 | |
jakowisp | 1:d8589d1f368c | 161 | sprintf(buffer,"%f",value); |
jakowisp | 1:d8589d1f368c | 162 | len=strlen(buffer); |
jakowisp | 1:d8589d1f368c | 163 | i=len-1; |
jakowisp | 1:d8589d1f368c | 164 | while(buffer[i]==0x30) { |
jakowisp | 1:d8589d1f368c | 165 | buffer[i]='\0'; |
jakowisp | 1:d8589d1f368c | 166 | i--; |
jakowisp | 1:d8589d1f368c | 167 | len--; |
jakowisp | 1:d8589d1f368c | 168 | } |
jakowisp | 1:d8589d1f368c | 169 | for( i =0; i<=len; i++) { |
jakowisp | 1:d8589d1f368c | 170 | switch(buffer[i]){ |
jakowisp | 1:d8589d1f368c | 171 | case 0x2d: buffer[i]=0xa; break; |
jakowisp | 1:d8589d1f368c | 172 | case 0x20: buffer[i]=0xf; break; |
jakowisp | 1:d8589d1f368c | 173 | case 0x2e: buffer[i]=buffer[i-1] | 0x80; |
jakowisp | 1:d8589d1f368c | 174 | ptr = i-1; |
jakowisp | 1:d8589d1f368c | 175 | break; |
jakowisp | 1:d8589d1f368c | 176 | default: buffer[i]= buffer[i]; |
jakowisp | 1:d8589d1f368c | 177 | } |
jakowisp | 1:d8589d1f368c | 178 | if (ptr != -1) { |
jakowisp | 1:d8589d1f368c | 179 | buffer[i-1]=buffer[i]; |
jakowisp | 1:d8589d1f368c | 180 | } |
jakowisp | 1:d8589d1f368c | 181 | } |
jakowisp | 1:d8589d1f368c | 182 | |
jakowisp | 1:d8589d1f368c | 183 | len=strlen(buffer); |
jakowisp | 1:d8589d1f368c | 184 | Write(max7219_reg_decodeMode, 0xff); |
jakowisp | 1:d8589d1f368c | 185 | |
jakowisp | 1:d8589d1f368c | 186 | // If too large for display set to '-' |
jakowisp | 1:d8589d1f368c | 187 | if(len > NUMDIGITS && (ptr==-1 || ptr>NUMDIGITS)) |
jakowisp | 1:d8589d1f368c | 188 | for (int i=0;i<NUMDIGITS;i++) { |
jakowisp | 1:d8589d1f368c | 189 | buffer[i]=0x0a; |
jakowisp | 1:d8589d1f368c | 190 | } |
jakowisp | 1:d8589d1f368c | 191 | //if number is smaller than display, fill with ' ' |
jakowisp | 1:d8589d1f368c | 192 | if (len<=NUMDIGITS) { |
jakowisp | 1:d8589d1f368c | 193 | for (int i=1;i<=NUMDIGITS;i++) { |
jakowisp | 1:d8589d1f368c | 194 | if(len-i>=0) { |
jakowisp | 1:d8589d1f368c | 195 | Write(i,buffer[len-i]); |
jakowisp | 1:d8589d1f368c | 196 | } else { |
jakowisp | 1:d8589d1f368c | 197 | Write(i,0xf); |
jakowisp | 1:d8589d1f368c | 198 | } |
jakowisp | 1:d8589d1f368c | 199 | } |
jakowisp | 1:d8589d1f368c | 200 | } else { |
jakowisp | 1:d8589d1f368c | 201 | //Write out the buffer, truncating the decimal digits if larger than display |
jakowisp | 1:d8589d1f368c | 202 | for (int i=0;i<NUMDIGITS;i++) { |
jakowisp | 1:d8589d1f368c | 203 | Write(NUMDIGITS-i,buffer[i]); |
jakowisp | 1:d8589d1f368c | 204 | } |
jakowisp | 1:d8589d1f368c | 205 | } |
jakowisp | 1:d8589d1f368c | 206 | } |
jakowisp | 1:d8589d1f368c | 207 | |
jakowisp | 2:828c62cc1861 | 208 | /** |
jakowisp | 2:828c62cc1861 | 209 | * This method is used to write an intial set off values to ALL device to prepare them for use. |
jakowisp | 2:828c62cc1861 | 210 | * @author Dwayne S. Dilbeck |
jakowisp | 2:828c62cc1861 | 211 | * @date 8/6/2013 |
jakowisp | 2:828c62cc1861 | 212 | */ |
jakowisp | 1:d8589d1f368c | 213 | void Max7221::SetupAll () { |
jakowisp | 1:d8589d1f368c | 214 | // initiation of the max 7219 |
jakowisp | 1:d8589d1f368c | 215 | // SPI setup: 8 bits, mode 0 |
ky3orr | 6:191569a26f50 | 216 | if(spi!=NULL) { |
ky3orr | 6:191569a26f50 | 217 | spi->format(8, 0); |
ky3orr | 6:191569a26f50 | 218 | spi->frequency(10*MHZ); |
ky3orr | 6:191569a26f50 | 219 | } |
jakowisp | 1:d8589d1f368c | 220 | WriteAll(max7219_reg_scanLimit, 0x07); |
jakowisp | 1:d8589d1f368c | 221 | WriteAll(max7219_reg_decodeMode, 0xff); // using an led matrix (not digits) |
jakowisp | 1:d8589d1f368c | 222 | WriteAll(max7219_reg_shutdown, 0x01); // not in shutdown mode |
jakowisp | 1:d8589d1f368c | 223 | WriteAll(max7219_reg_displayTest, 0x00); // no display test |
jakowisp | 1:d8589d1f368c | 224 | for (int e=1; e<=8; e++) { // empty registers, turn all LEDs off |
jakowisp | 1:d8589d1f368c | 225 | WriteAll(e,0xf); |
jakowisp | 1:d8589d1f368c | 226 | } |
jakowisp | 1:d8589d1f368c | 227 | WriteAll(max7219_reg_intensity, 0x01 & 0x0f); // the first 0x0f is the value you can set |
jakowisp | 1:d8589d1f368c | 228 | // range: 0x00 to 0x0f |
jakowisp | 1:d8589d1f368c | 229 | } |
jakowisp | 2:828c62cc1861 | 230 |