Fix to have load pin working with SPI1.

Dependencies:   mbed

Fork of Max7221 by Dwayne Dilbeck

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?

UserRevisionLine numberNew 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