Grzegorz Kaczmarek
/
Max7221
Fix to have load pin working with SPI1.
Fork of Max7221 by
Diff: MAX7221/Max7221.cpp
- Revision:
- 1:d8589d1f368c
- Child:
- 2:828c62cc1861
diff -r cb8e1d05a4a7 -r d8589d1f368c MAX7221/Max7221.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAX7221/Max7221.cpp Tue Aug 06 08:18:53 2013 +0000 @@ -0,0 +1,195 @@ +#include "mbed.h" +#include "Max7221.h" + +int Max7221::maxInUseSPI1 = 0; +int Max7221::maxInUseSPI2 = 0; +SPI *Max7221::spi1=NULL; +SPI *Max7221::spi2=NULL; +DigitalOut *Max7221::load1=NULL; +DigitalOut *Max7221::load2=NULL; + +Max7221::Max7221(PinName msoi, PinName mclk, PinName load){ + switch (msoi) { + case p5: maxInUseSPI1++; + this->id=maxInUseSPI1; + this->maxInUse=&maxInUseSPI1; + if (spi1 ==NULL) { + spi1 = new SPI(msoi, NC, mclk); + load1 = new DigitalOut(load); + } else { + //TODO: Check that load pin is the same for all SP2 + } + this->max72_spi=spi1; + this->load = load2; + break; + case p11: maxInUseSPI2++; + this->id=maxInUseSPI2; + this->maxInUse=&maxInUseSPI2; + if (spi2 ==NULL) { + spi2 = new SPI(msoi, NC, mclk); + load2 = new DigitalOut(load); + } else { + //TODO: Check that load pin is the same for all SP2 + } + this->max72_spi=spi2; + this->load = load2; + break; + default: error("Not a SPI port"); + } + +} + +void Max7221::Write( unsigned int reg, unsigned int col) { +//maxOne is for adressing different MAX7219's, +//while having a couple of them cascaded + int c = 0; + *load = LOW; + + for ( c = *maxInUse; c > this->id; c--) { + max72_spi->write(0); // no-op + max72_spi->write(0); // no-op + } + + max72_spi->write(reg); // specify register + max72_spi->write(col); // put data + + for ( c=this->id-1; c >= 1; c--) { + max72_spi->write(0); // no-op + max72_spi->write(0); // no-op + } + *load = HIGH; +} + +void Max7221::Setup () { + // initiation of the max 7219 + // SPI setup: 8 bits, mode 0 + max72_spi->format(8, 0); + + // going by the datasheet, min clk is 100ns so theoretically 10MHz should work... + max72_spi->frequency(10*MHZ); + + Write(max7219_reg_scanLimit, 0x07); + Write(max7219_reg_decodeMode, 0xff); // using an led matrix (not digits) + Write(max7219_reg_shutdown, 0x01); // not in shutdown mode + Write(max7219_reg_displayTest, 0x00); // no display test + for (int e=1; e<=8; e++) { // empty registers, turn all LEDs off + Write(e,0xf); + } + Write(max7219_reg_intensity, 0x01 & 0x0f); // the first 0x0f is the value you can set + // range: 0x00 to 0x0f +} + + +void Max7221::WriteAll (unsigned int reg, unsigned int col) { // initialize all MAX7219's in the system + if(load1 !=NULL) { + *load1 = LOW; // begin + for ( int c=1; c<= maxInUseSPI1; c++) { + spi1->write(reg); // specify register + spi1->write(col); // put data + } + *load1 = HIGH; + } + if(load2 !=NULL) { + *load2 = LOW; + for ( int c=1; c<= maxInUseSPI2; c++) { + spi2->write(reg); // specify register + spi2->write(col); // put data + } + *load2 = HIGH; + } +} + +void Max7221::WriteInt( int value ){ + char buffer[16]; + + //TODO:SET UPPERBOUND AND LOWERBOUND based on NUMDIGITS + if (value <= UPPERBOUND && value >= LOWERBOUND) { + sprintf(buffer,"%8d",value); + } else { + sprintf(buffer,"--------"); + } + + Write(max7219_reg_decodeMode, 0xff); + for (int i=0;i<NUMDIGITS;i++) { + switch(buffer[i]){ + case 0x2d: buffer[i]=0xa; break; + case 0x20: buffer[i]=0xf; break; + default: buffer[i]= buffer[i] & 0x0f; + } + Write(NUMDIGITS-i,buffer[i]); + } +} + +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); + + // 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::SetupAll () { + // initiation of the max 7219 + // SPI setup: 8 bits, mode 0 + if(spi1!=NULL) { + spi1->format(8, 0); + spi1->frequency(10*MHZ); + } + if(spi2!=NULL) { + spi2->format(8, 0); + spi2->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); + } + WriteAll(max7219_reg_intensity, 0x01 & 0x0f); // the first 0x0f is the value you can set + // range: 0x00 to 0x0f +}