MHVLib  20111011
An efficiency oriented runtime library for AVR microcontrollers
A:/eclipse/mhvlib/MHV_PWMMatrix.cpp
Go to the documentation of this file.
00001 /* Copyright (c) 2011, Make, Hack, Void Inc
00002  * All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *  * Redistributions of source code must retain the above copyright
00007  *    notice, this list of conditions and the following disclaimer.
00008  *  * Redistributions in binary form must reproduce the above copyright
00009  *    notice, this list of conditions and the following disclaimer in the
00010  *    documentation and/or other materials provided with the distribution.
00011  *  * Neither the name of the Make, Hack, Void nor the
00012  *    names of its contributors may be used to endorse or promote products
00013  *    derived from this software without specific prior written permission.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00016  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00018  * DISCLAIMED. IN NO EVENT SHALL MAKE, HACK, VOID BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00020  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00021  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00022  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00023  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025  */
00026 
00027 #include "MHV_PWMMatrix.h"
00028 #include <string.h>
00029 #include <math.h>
00030 
00031 #define pixel(pixelCol, pixelRow) _frameBuffer[pixelRow * _colCount + pixelCol]
00032 
00045 MHV_PWMMatrix::MHV_PWMMatrix(uint16_t rowCount, uint16_t colCount, uint8_t *frameBuffer,
00046                 MHV_RingBuffer *txBuffers,
00047                 void (*rowOn)(uint16_t row),
00048                 void (*rowOff)(uint16_t row),
00049                 void (*colOn)(uint16_t column),
00050                 void (*colOff)(uint16_t column),
00051                 MHV_PWMMATRIX_MODE mode) :
00052                         MHV_Display_Monochrome_Buffered (rowCount, colCount, frameBuffer, txBuffers) {
00053         uint8_t i;
00054 
00055         _currentRow = 0;
00056         _currentCol = 0;
00057         _currentLevel = 0;
00058 
00059         if (MHV_PWMMATRIX_MODE_AUTO == mode) {
00060                 _mode = (rowCount <= colCount) ? MHV_PWMMATRIX_MODE_ROWS : MHV_PWMMATRIX_MODE_COLS;
00061         } else {
00062                 _mode = mode;
00063         }
00064 
00065         _rowOn = rowOn;
00066         _rowOff = rowOff;
00067         _colOn = colOn;
00068         _colOff = colOff;
00069 
00070         for (i = 0; i < _rowCount; i++) {
00071                 _rowOff(i);
00072         }
00073         for (i = 0; i < _colCount; i++) {
00074                 _colOff(i);
00075         }
00076 }
00077 
00081 inline void MHV_PWMMatrix::tickRow(void) {
00082         uint16_t                i;
00083 
00084         if (0 == _currentLevel) {
00085                 // Turn on the current row
00086                 _rowOn(_currentRow);
00087                 for (i = 0; i < _colCount; i++) {
00088                         if (pixel(i, _currentRow) > 0) {
00089                                 _colOn(i);
00090                         }
00091                 }
00092         } else {
00093                 // Turn off pixels that get switched off on this pass
00094                 for (i = 0; i < _colCount; i++) {
00095                         if (pixel(i, _currentRow) <= _currentLevel) {
00096                                 _colOff(i);
00097                         }
00098                 }
00099         }
00100 
00101         if (255 == ++_currentLevel) {
00102                 // Turn off the current row & advance
00103                 _rowOff(_currentRow);
00104 
00105                 _currentLevel = 0;
00106                 if (++_currentRow == _rowCount) {
00107                         _currentRow = 0;
00108                 }
00109         }
00110 }
00111 
00115 inline void MHV_PWMMatrix::tickCol(void) {
00116         uint16_t                i;
00117 
00118         if (0 == _currentLevel) {
00119                 // Turn on the current column
00120                 _colOn(_currentCol);
00121                 for (i = 0; i < _rowCount; i++) {
00122                         if (pixel(_currentCol, i) > 0) {
00123                                 _rowOn(i);
00124                         }
00125                 }
00126         } else {
00127                 // Turn off pixels that get switched off on this pass
00128                 for (i = 0; i < _rowCount; i++) {
00129                         if (pixel(_currentCol, i) <= _currentLevel) {
00130                                 _rowOff(i);
00131                         }
00132                 }
00133         }
00134 
00135         if (255 == ++_currentLevel) {
00136                 // Turn off the current column & advance
00137                 _colOff(_currentCol);
00138 
00139                 _currentLevel = 0;
00140                 if (++_currentCol == _colCount) {
00141                         _currentCol = 0;
00142                 }
00143         }
00144 }
00145 
00149 inline void MHV_PWMMatrix::tickPixel(void) {
00150         if (0 == _currentLevel) {
00151                 // Turn on the pixel at the current row & column
00152                 _colOn(_currentCol);
00153                 _rowOn(_currentRow);
00154         } else if (pixel(_currentRow, _currentCol) <= _currentLevel) {
00155                 // Turn off the pixel
00156                 _colOff(_currentCol);
00157                 _rowOff(_currentRow);
00158         }
00159 
00160         if (255 == ++_currentLevel) {
00161                 // Advance the column
00162                 if (++_currentCol == _colCount) {
00163                         _currentCol = 0;
00164 
00165                         // Advance the row
00166                         if (++_currentRow == _rowCount) {
00167                                 _currentRow = 0;
00168                         }
00169                 }
00170         }
00171 }
00172 
00173 
00174 /* Process a timer tick
00175  */
00176 void MHV_PWMMatrix::tick(void) {
00177         switch (_mode) {
00178         case MHV_PWMMATRIX_MODE_ROWS:
00179                 tickRow();
00180                 break;
00181         case MHV_PWMMATRIX_MODE_COLS:
00182                 tickCol();
00183                 break;
00184         case MHV_PWMMATRIX_MODE_INDIVIDUAL:
00185                 tickPixel();
00186                 break;
00187         default:
00188                 break;
00189         }
00190 }