Advertisement
NittyGritty

Leds.cpp

Jan 31st, 2017
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.20 KB | None | 0 0
  1. #include <Arduino.h>
  2. #include "Leds.h"
  3. #include "PINS.h"
  4. #include "TimerOne.h"
  5.  
  6. #define PERIOD_MICROSECONDS_BRIGHT 100
  7. #define PERIOD_MICROSECONDS_DIM    50
  8. #define DWELL_BRIGHT 0
  9. #define DWELL_DIM    300
  10.  
  11. LEDs leds;
  12.  
  13. // m_RowAnodePins[n] is the Arduino pin connected to the led matrix pin for row n+1
  14. const int LEDs::m_RowAnodePins[8] = MATRIX_ANODE_ROW_PINS;
  15.  
  16. // m_ColCathodeBits[m] is the bit number on the '595 connected to the led matrix pin for col m+1
  17. const int LEDs::m_ColCathodeBits[8] = MATRIX_CATHODE_COL_BITS;
  18.  
  19. void LEDs::Init()
  20. {
  21.   pinMode(PIN_LATCH, OUTPUT);
  22.   pinMode(PIN_CLOCK, OUTPUT);
  23.   pinMode(PIN_DATA, OUTPUT);
  24.  
  25.   // all off
  26.   digitalWrite(PIN_LATCH, LOW);
  27.   shiftOut(PIN_DATA, PIN_CLOCK, MSBFIRST, 0x00);  
  28.   digitalWrite(PIN_LATCH, HIGH);
  29.   for (int row = 0; row < 8; row++)
  30.   {
  31.     pinMode(m_RowAnodePins[row], OUTPUT);
  32.     digitalWrite(m_RowAnodePins[row], HIGH);    
  33.   }
  34.   m_iOrientation = eUp;
  35.   m_iBrightness = eHigh;
  36.   Clear();
  37.   Show();
  38.   m_iUpdateRow = 0;
  39.   m_iUpdateCol = 0;
  40.   m_iDwellCounter = 0;
  41.   m_bDwellStart = false;
  42.   m_pPixels = m_pPixelsA;
  43.   m_pNextPixels = m_pPixelsB;
  44.   Timer1.initialize(PERIOD_MICROSECONDS_BRIGHT);
  45.   Timer1.attachInterrupt(LEDs::Callback);
  46. }
  47.  
  48. void LEDs::Mode(tOrientation Orientation)
  49. {
  50.   noInterrupts();
  51.   m_iOrientation = Orientation;
  52.   interrupts();
  53. }
  54.  
  55. LEDs::tBrightness LEDs::Brightness()
  56. {
  57.   return m_iBrightness;
  58. }
  59.  
  60.  
  61. void LEDs::Brightness(tBrightness Bright)
  62. {
  63.   m_iBrightness = Bright;
  64.   noInterrupts();
  65.   Timer1.setPeriod((m_iBrightness == eHigh)?PERIOD_MICROSECONDS_BRIGHT:PERIOD_MICROSECONDS_DIM);
  66.   interrupts();
  67. }
  68.  
  69. void LEDs::Clear()
  70. {
  71.   for (int Row = 0; Row < 8; Row++)
  72.     m_pNextPixels[Row] = 0x00;
  73. }
  74.  
  75. void LEDs::Fill()
  76. {
  77.   for (int Row = 0; Row < 8; Row++)
  78.     m_pNextPixels[Row] = 0xFF;
  79. }
  80.  
  81. void LEDs::Set(int Row, int Col, bool On)
  82. {
  83.   int Bit = On?1:0;
  84.   switch (m_iOrientation)
  85.   {
  86.     case eDown:
  87.     {
  88.       // pin 1 top right
  89.       bitWrite(m_pNextPixels[7-Row], 7-Col, Bit);
  90.       break;
  91.     }
  92.     case eLeft:
  93.     {
  94.       // pin 1 bottom right
  95.       bitWrite(m_pNextPixels[Col], 7-Row, Bit);
  96.       break;
  97.     }
  98.     case eRight:
  99.     {
  100.       // pin 1 top left
  101.       bitWrite(m_pNextPixels[7-Col], Row, Bit);
  102.       break;
  103.     }
  104.     default:
  105.     {
  106.       // pin 1 bottom left
  107.       bitWrite(m_pNextPixels[Row], Col, Bit);
  108.       break;
  109.     }
  110.   }
  111. }
  112.  
  113. void LEDs::Show()
  114. {
  115.   noInterrupts();
  116.   byte* pSwap = m_pPixels;
  117.   m_pPixels = m_pNextPixels;
  118.   m_pNextPixels = pSwap;
  119.   interrupts();
  120. }
  121.  
  122. byte* LEDs::RawData()
  123. {
  124.   return m_pNextPixels;
  125. }
  126.  
  127. void LEDs::Callback()
  128. {
  129.   leds.Update();
  130. }
  131.  
  132. void LEDs::PortShiftOut(byte latchMask, byte dataMask, byte clockMask, byte Value)
  133. {
  134.   // we want our interrupt handler to be as fast as possible so a custom shiftOut.
  135.   // the three pins must be on the same port
  136.   byte Mask = 0x80;
  137.   PORT_SHIFTOUT &= ~latchMask;
  138.  
  139.   //  MSBFIRST
  140.   while (Mask)
  141.   {
  142.     if (Value & Mask)
  143.       PORT_SHIFTOUT |=  dataMask;
  144.     else
  145.       PORT_SHIFTOUT &= ~dataMask;
  146.                
  147.     PORT_SHIFTOUT |=  clockMask;
  148.     PORT_SHIFTOUT &= ~clockMask;
  149.     Mask >>= 1;
  150.   }
  151.   PORT_SHIFTOUT |= latchMask;
  152. }
  153.  
  154. void LEDs::Update()
  155. {
  156.   if (m_iDwellCounter)
  157.   {
  158.     // idle to extend the off time and dim the display
  159.     if (m_bDwellStart)
  160.     {
  161.       m_bDwellStart = false;
  162.       // off:
  163.       digitalWrite(m_RowAnodePins[m_iUpdateRow], HIGH);
  164.       PortShiftOut(PORT_MASK_LATCH, PORT_MASK_DATA, PORT_MASK_CLOCK, 0x00);
  165.     }
  166.     m_iDwellCounter--;
  167.     return;
  168.   }
  169.  
  170.   // off:
  171.   digitalWrite(m_RowAnodePins[m_iUpdateRow], HIGH);
  172.   PortShiftOut(PORT_MASK_LATCH, PORT_MASK_DATA, PORT_MASK_CLOCK, 0x00);
  173.  
  174.   m_iUpdateRow++;
  175.   if (m_iUpdateRow > 7)
  176.   {
  177.     m_iUpdateRow = 0;
  178.     m_iUpdateCol++;
  179.     if (m_iUpdateCol > 7)
  180.     {
  181.       m_iUpdateCol = 0;
  182.       m_bDwellStart = true;
  183.       m_iDwellCounter = (m_iBrightness == eHigh)?DWELL_BRIGHT:DWELL_DIM;
  184.     }
  185.   }
  186.  
  187.   if (bitRead(m_pPixels[m_iUpdateRow], m_iUpdateCol) && m_iBrightness != eOff)
  188.   {
  189.     // on:
  190.     digitalWrite(m_RowAnodePins[m_iUpdateRow], LOW);    
  191.     PortShiftOut(PORT_MASK_LATCH, PORT_MASK_DATA, PORT_MASK_CLOCK, bit(m_ColCathodeBits[m_iUpdateCol]));
  192.   }
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement