Grzegorz Kaczmarek
/
Max7221
Fix to have load pin working with SPI1.
Fork of Max7221 by
Diff: Max7221.cpp
- Revision:
- 7:a160cb7cdd86
- Parent:
- 6:191569a26f50
- Child:
- 8:3f5901f2f813
--- a/Max7221.cpp Thu Nov 19 23:58:07 2015 +0000 +++ b/Max7221.cpp Mon Nov 23 11:28:44 2015 +0000 @@ -1,230 +1,105 @@ /** * @file Max7221.cpp -* @brief This file defines the Max7221 class methods and the default values for static variables +* @brief MAX7219/7221 driver class. * -* @author Dwayne S. Dilbeck -* -* @date 8/6/2013 +* @author Grzegorz Kaczmarek +* @comment Code inspired on erlier Dwayne S. Dilbeck's work +* @date 20/11/2015 */ + #include "mbed.h" #include "Max7221.h" -///Intialize the Class static members -///Devices used per SPI bus are set to ZERO -int Max7221::maxInUseSPI = 0; -///Set the static pointers to the SPI busses to NULL -SPI *Max7221::spi=NULL; -///Set the static pointers to the load signals to NULL -DigitalOut *Max7221::cs=NULL; - -/** -* Constructor. This is the default constructor -* @author Dwayne S. Dilbeck -* @param msoi The SPI pin used as input to the device. Valid values for LPC1768 are p5 or p11 -* @param mclk The SPI pin used as clock for the device. Valid values for LPC1768 are p7 or p13 -* @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 -* device that share the same msoi and mclk pins -* @date 8/6/2013 -*/ -Max7221::Max7221(PinName msoi, PinName mclk, PinName load){ - ///Set this insctance to pointers to the correct static pointers - this->id=maxInUseSPI; - this->maxInUse=&maxInUseSPI; - ///If no devices have been assigned to the SPI bus it must be initialized - if (spi ==NULL) { - spi = new SPI(msoi, NC, mclk); - cs = new DigitalOut(load); - } - this->max7221_spi= spi; - this->max7221_cs = cs; +Max7221::Max7221(SPI *spi, DigitalOut *cs, unsigned int position) : + mp_spi(spi), + mp_cs(cs), + m_position(position) +{ } -/** -* This method is used to write a byte of data to a specified register for only the device defined in this class instance -* @author Dwayne S. Dilbeck -* @param reg The register to write to. -* @param data The value to be written. -* @date 8/6/2013 -*//** -* This method is used to write a byte of data to a specified register for only the device defined in this class instance -* @author Dwayne S. Dilbeck -* @param reg The register to write to. -* @param data The value to be written. -* @date 8/6/2013 -*/ -void Max7221::Write( unsigned int reg, unsigned int data) { - int c = 0; - *cs = LOW; - - ///if there are multiple devices sharing the SPI buss and they preceed the current device in the cascade Write a NOOP to them - for ( c = *maxInUse; c > this->id; c--) { - max7221_spi->write(0); // no-op - max7221_spi->write(0); // no-op +void Max7221::CsLow() +{ + if(mp_cs != NULL) { + *mp_cs = LOG_0; } - ///Write to this device registers - max7221_spi->write(reg); // specify register - max7221_spi->write(data); // put data - - ///if there are multiple devices sharing the SPI buss and they follow the current device in the cascade Write a NOOP to them - for ( c=this->id-1; c >= 1; c--) { - max7221_spi->write(0); // no-op - max7221_spi->write(0); // no-op - } - *cs = HIGH; } -/** -* This method is used to write an intial set off values to the device to prepare it for use. -* @author Dwayne S. Dilbeck -* @date 8/6/2013 -*/ -void Max7221::Setup () { - // initiation of the max 7221 - // SPI setup: 8 bits, mode 0 - max7221_spi->format(8, 0); - - // going by the datasheet, min clk is 100ns so theoretically 10MHz should work... - max7221_spi->frequency(10*MHZ); - - Write(max7219_reg_scanLimit, 0x07); ///ENABLE all 8 digits - Write(max7219_reg_decodeMode, 0xff); // Turn on Code B font decode for all digits - Write(max7219_reg_shutdown, 0x01); // Disable shutdown mode - Write(max7219_reg_displayTest, 0x00); // Disable display test - for (int e=1; e<=8; e++) { // Write blank to all digits - Write(e,0xf); +void Max7221::CsHigh() +{ + if(mp_cs != NULL) { + *mp_cs = LOG_1; } - Write(max7219_reg_intensity, 0x01 ); // Set the display intensity to a low level. - // range: 0x00 to 0x0f } -/** -* This method is used to write a byte of data to a specified register for all the devices instantiated. -* @author Dwayne S. Dilbeck -* @param reg The register to write to. -* @param data The value to be written. -* @date 8/6/2013 -*/ -void Max7221::WriteAll (unsigned int reg, unsigned int data) { - ///Write to all the devices on SPI Bus #1 first - if(cs !=NULL) { - *cs = LOW; // begin - for ( int c=1; c<= maxInUseSPI; c++) { - spi->write(reg); // specify register - spi->write(data); // put data - } - *cs = HIGH; +void Max7221::WriteRaw(unsigned int reg, unsigned int data) { + if(mp_spi != NULL) { + mp_spi->write(reg); + mp_spi->write(data); } } -/** -* This method is used to display an integer to the specified device instance. Underflow and overflow result in '-' written to all digits -* @author Dwayne S. Dilbeck -* @param value An integer value to display -* @date 8/6/2013 -*/ -void Max7221::WriteInt( int value ){ - char buffer[16]; - - ///TODO:SET UPPERBOUND AND LOWERBOUND based on NUMDIGITS - ///Check the the INT value can be displayed and convert to a string. - if (value <= UPPERBOUND && value >= LOWERBOUND) { - sprintf(buffer,"%8d",value); - } else { - sprintf(buffer,"--------"); - } - ///In case a program changed the decode mode, set it again. - Write(max7219_reg_decodeMode, 0xff); - for (int i=0;i<NUMDIGITS;i++) { - ///For each character of the string, convert the ASCII to the datacode needed by the device - switch(buffer[i]){ - case 0x2d: buffer[i]=0xa; break; - case 0x20: buffer[i]=0xf; break; - default: buffer[i]= buffer[i] & 0x0f; - } - ///Call function to write the data for each character of the srting. - Write(NUMDIGITS-i,buffer[i]); - } + +void Max7221::Write(unsigned int reg, unsigned int data) { + unsigned int i; + + CsLow(); + WriteRaw(reg, data); + if(m_position > 0) { + i = m_position; + while(i--) { + WriteRaw(max7219_reg_noop, 0x0); + } + } + CsHigh(); +} + +void Max7221::TestMode(bool mode) { + if(mode) { + Write(max7219_reg_displayTest, 0x01); + } else { + Write(max7219_reg_displayTest, 0x00); + } +} + +void Max7221::UseDigitsNo(unsigned int digits_no) { + if((digits_no > 0) && (digits_no < 9)) { + Write(max7219_reg_scanLimit, (digits_no - 1)); + } +} + +void Max7221::DecodeMode(unsigned int mode) { + Write(max7219_reg_decodeMode, mode); } -/** -* This method is used to display a floating point number to the specified device instance. -* Underflow and overflow result in '-' written to all digits. The digits after the decimal -* point are truncated to fit the display. -* @author Dwayne S. Dilbeck -* @param value A float value to display -* @date 8/6/2013 -*/ -void Max7221::WriteFloat( float value ){ - char buffer[32]; - int ptr=-1,len; - int i; - - sprintf(buffer,"%f",value); - len=strlen(buffer); - i=len-1; - while(buffer[i]==0x30) { - buffer[i]='\0'; - i--; - len--; - } - for( i =0; i<=len; i++) { - switch(buffer[i]){ - case 0x2d: buffer[i]=0xa; break; - case 0x20: buffer[i]=0xf; break; - case 0x2e: buffer[i]=buffer[i-1] | 0x80; - ptr = i-1; - break; - default: buffer[i]= buffer[i]; - } - if (ptr != -1) { - buffer[i-1]=buffer[i]; - } - } - - len=strlen(buffer); - Write(max7219_reg_decodeMode, 0xff); +void Max7221::WriteDigit(unsigned int digit_no, unsigned int value) { + if(digit_no < 8) { + Write(digit_no, value); + } +} - // If too large for display set to '-' - if(len > NUMDIGITS && (ptr==-1 || ptr>NUMDIGITS)) - for (int i=0;i<NUMDIGITS;i++) { - buffer[i]=0x0a; - } - //if number is smaller than display, fill with ' ' - if (len<=NUMDIGITS) { - for (int i=1;i<=NUMDIGITS;i++) { - if(len-i>=0) { - Write(i,buffer[len-i]); - } else { - Write(i,0xf); - } - } - } else { - //Write out the buffer, truncating the decimal digits if larger than display - for (int i=0;i<NUMDIGITS;i++) { - Write(NUMDIGITS-i,buffer[i]); - } - } +void Max7221::Intensity(unsigned int intensity) { + if(intensity > 0x0F) { + intensity = 0x0F; + } + Write(max7219_reg_intensity, intensity); } -/** -* This method is used to write an intial set off values to ALL device to prepare them for use. -* @author Dwayne S. Dilbeck -* @date 8/6/2013 -*/ -void Max7221::SetupAll () { - // initiation of the max 7219 - // SPI setup: 8 bits, mode 0 - if(spi!=NULL) { - spi->format(8, 0); - spi->frequency(10*MHZ); - } - WriteAll(max7219_reg_scanLimit, 0x07); - WriteAll(max7219_reg_decodeMode, 0xff); // using an led matrix (not digits) - WriteAll(max7219_reg_shutdown, 0x01); // not in shutdown mode - WriteAll(max7219_reg_displayTest, 0x00); // no display test - for (int e=1; e<=8; e++) { // empty registers, turn all LEDs off - WriteAll(e,0xf); +void Max7221::OperationMode(bool mode) { + if(mode) { + Write(max7219_reg_shutdown, 0x01); + } else { + Write(max7219_reg_shutdown, 0x00); } - WriteAll(max7219_reg_intensity, 0x01 & 0x0f); // the first 0x0f is the value you can set - // range: 0x00 to 0x0f } +void Max7221::Setup () { + unsigned int i; + + TestMode(false); // Disable display test + UseDigitsNo(8); // Use all 8 digits + DecodeMode(0xFF); // Turn on Code B font decode for all digits + for(i=1;i<9;i++) { // Clean all digits + WriteDigit(i, 0x0F); + } + Intensity(0x01); // Set lowest display intensity(0x00-0xFF) + OperationMode(true); // Enable operation mode +}