Logo Search packages:      
Sourcecode: ktechlab version File versions  Download package

void PIC14::SsevenSegment ( const Variable pinMap  ) 

Output the working register to the given seven segment.

Parameters:
name The variable giving the pin configuration of the seven segment.

Definition at line 895 of file pic14.cpp.

References Code::append(), Code::instruction(), Variable::name(), PortPin::pin(), Variable::portPinList(), PortPin::portPosition(), Code::queueLabel(), Code::Subroutine, and Variable::type().

Referenced by Parser::processAssignment().

{
      assert( pinMap.type() == Variable::sevenSegmentType );
      assert( pinMap.portPinList().size() == 7 );
      
      QString subName = QString("__output_seven_segment_%1").arg( pinMap.name() );
      
      m_pCode->append( new Instr_call( subName ) );
      
      if ( m_pCode->instruction(subName) )
            return;
      
      // Build up what are going to write to each port from the pin map
      struct SSPortOutput
      {
            bool used; // Wheter we use this port at all
            bool use[8]; // Whether or not we use each pin.
            bool out[16][8]; // The bit to write to each pin for each value.
            uchar useMask; // The bits of use[8] - this is generated later from use[8]
      };
      
      unsigned numPorts = 2;
      SSPortOutput portOutput[ numPorts ];
      memset( portOutput, 0, numPorts * sizeof(SSPortOutput) );
      
      for ( unsigned i = 0; i < 7; ++i )
      {
            PortPin portPin = pinMap.portPinList()[i];
            
            unsigned port = unsigned( portPin.portPosition() );
            unsigned pin = unsigned( portPin.pin() );
            
            portOutput[ port ].used = true;
            portOutput[ port ].use[ pin ] = true;
            
            for ( unsigned num = 0; num < 16; ++num )
            {
                  portOutput[ port ].out[ num ][ pin ] = LEDSegTable[num][ i ];
            }
      }
      
      
      // See if we've used more than one port
      unsigned portsUsed = 0;
      for ( unsigned port = 0; port < numPorts; ++port )
      {
            if ( portOutput[port].used )
                  portsUsed++;
      }
      
      
      // Generate the useMasks
      for ( unsigned port = 0; port < numPorts; ++port )
      {
            portOutput[port].useMask = 0;
            for ( unsigned pin = 0; pin < 8; ++pin )
                  portOutput[port].useMask |= portOutput[port].use[pin] ? (1 << pin) : 0;
      }
      
      
      //BEGIN Generate [subName] Subroutine
      m_pCode->queueLabel( subName, Code::Subroutine );
//    if ( portsUsed > 1 )
      {
            m_pCode->append( new Instr_movwf("__i"), Code::Subroutine );
      }
      
//    bool overwrittenW = false;
      bool overwrittenW = true;
      
      for ( unsigned port = 0; port < numPorts; ++port )
      {
            if ( !portOutput[port].used )
                  continue;
            
            QString portName = QString("PORT%1").arg( char('A'+port) );
            
            // Save the current value of the port pins that we should not be writing to
            m_pCode->append( new Instr_movf( portName, 0 ), Code::Subroutine );
            m_pCode->append( new Instr_andlw( ~portOutput[port].useMask ), Code::Subroutine );
            m_pCode->append( new Instr_movwf( "__j" ), Code::Subroutine );
            
            if ( overwrittenW )
                  m_pCode->append( new Instr_movf("__i",0), Code::Subroutine );
            
            m_pCode->append( new Instr_call( subName + QString("_lookup_%1").arg(port) ), Code::Subroutine );
            overwrittenW = true;
            
            // Restore the state of the pins which aren't used
            m_pCode->append( new Instr_iorwf( "__j", 0 ), Code::Subroutine );
            
            // And write the result to the port
            m_pCode->append( new Instr_movwf( portName ), Code::Subroutine );
      }
      
      m_pCode->append( new Instr_return(), Code::Subroutine );
      //END Generate [subName] Subroutine
      
      // For each port, generate code for looking up the value for writing to it
      for ( unsigned port = 0; port < numPorts; ++port )
      {
            if ( !portOutput[port].used )
                  continue;
            
            m_pCode->queueLabel( subName + QString("_lookup_%1").arg(port), Code::LookupTable );
            m_pCode->append( new Instr_andlw(15), Code::LookupTable );
      
            // Generate the lookup table
            m_pCode->append( new Instr_addwf( "pcl", 1 ), Code::LookupTable );
            for ( unsigned num = 0; num < 16; ++num )
            {
                  unsigned literal = 0;
                  for ( unsigned bit = 0; bit < 8; ++bit )
                        literal += ( portOutput[port].out[num][bit] ? 1 : 0 ) << bit;
                  
                  m_pCode->append( new Instr_retlw( literal ), Code::LookupTable );
            }
      }
}


Generated by  Doxygen 1.6.0   Back to index