program UltimateCommandStation; { Declarations section } // Serial Flash Chip Select connection var CS_Serial_Flash_bit: sbit at LATD14_bit; CS_Serial_Flash_Direction_bit: sbit at TRISD14_bit; // TFT module connections var TFT_DataPort : char at LATE; TFT_RST : sbit at LATD7_bit; TFT_BLED : sbit at LATD2_bit; TFT_RS : sbit at LATD9_bit; TFT_CS : sbit at LATD10_bit; TFT_RD : sbit at LATD5_bit; TFT_WR : sbit at LATD4_bit; TFT_DataPort_Direction : char at TRISE; TFT_RST_Direction : sbit at TRISD7_bit; TFT_BLED_Direction : sbit at TRISD2_bit; TFT_RS_Direction : sbit at TRISD9_bit; TFT_CS_Direction : sbit at TRISD10_bit; TFT_RD_Direction : sbit at TRISD5_bit; TFT_WR_Direction : sbit at TRISD4_bit; // End TFT module connections // DCC Connection Pins H_Bridge_A_Lo : sbit at LATB4_bit; H_Bridge_A_Hi : sbit at LATB5_bit; H_Bridge_B_Lo : sbit at LATB6_bit; H_Bridge_B_Hi : sbit at LATB7_bit; PreambleSyncPin : sbit at LATB1_bit; // Output at the end of the preamble DCC_Programming_ACK_Pin : sbit at RB0_bit; // Input so use the port and not the latch H_Bridge_A_Lo_Direction : sbit at TRISB4_bit; H_Bridge_A_Hi_Direction : sbit at TRISB5_bit; H_Bridge_B_Lo_Direction : sbit at TRISB6_bit; H_Bridge_B_Hi_Direction : sbit at TRISB7_bit; PreambleSyncPinDirection : sbit at TRISB1_bit; DCC_Programming_ACK_Direction : sbit at TRISB0_bit; Dcc_Timer_PR : Word at PR1; // DCC Interrupt Rollover // End DCC Connection Pins procedure DrawFrame(); begin TFT_Fill_Screen(CL_WHITE); TFT_Set_Pen(CL_BLACK, 1); TFT_Line(20, 220, 300, 220); TFT_LIne(20, 46, 300, 46); TFT_Set_Font(@HandelGothic_BT21x22_Regular, CL_RED, FO_HORIZONTAL); TFT_Write_Text('Ultimate DCC CommandStation', 15, 14); TFT_Set_Font(@Verdana12x13_Regular, CL_BLACK, FO_HORIZONTAL); TFT_Write_Text('OpenLCB', 19, 223); TFT_Set_Font(@Verdana12x13_Regular, CL_RED, FO_HORIZONTAL); TFT_Write_Text('www.openlcb.org', 200, 223); TFT_Set_Font(@TFT_defaultFont, CL_BLACK, FO_HORIZONTAL); end; procedure ToggleBridge; begin H_Bridge_A_Lo := 0; // Bridge Off H_Bridge_A_Hi := 0; // Bridge Off H_Bridge_B_Lo := 0; // Bridge Off H_Bridge_B_Hi := 0; // Bridge Off if Track.TX_Flags.TRANSMITTING_FLAG_DCC_PIN_BIT = 1 then begin H_Bridge_A_Lo := 1; H_Bridge_B_Hi := 1; end else begin H_Bridge_A_Hi := 1; H_Bridge_B_Lo := 1; end; end; procedure OPStack_DCC_Timer(); iv IVT_ADDR_T1INTERRUPT; ics ICS_AUTO; begin T1IF_bit := 0; // Clear the Flag // if CommandStationRamData.OverloadDetected then // begin // Toggle the Bridge off //// H_Bridge_A_Lo := 0; // Bridge Off // H_Bridge_A_Hi := 0; // Bridge Off // H_Bridge_B_Lo := 0; // Bridge Off // H_Bridge_B_Hi := 0; // Bridge Off // end else begin // if CommandStationConfigurationShadowRam.OutputMode = CONFIG_OUTPUTMODE_SERVICE_MODE then // begin // RunServiceMode // Command Station is in Service Mode // end else begin // Command Station is in Main Line Mode // if CommandStationConfigurationShadowRam.DccBusMode = CONFIG_NMRA_DCC_TRANSMITTER then // If we are a DCC Transmitter then handle that // RunNmraDccTranmitter; // if CommandStationConfigurationShadowRam.RailComEnable = CONFIG_RAILCOM_ENABLED then // begin // if Track.TX_Flags.TRANSMITTING_FLAG_RAIL_COM_CUTOUT_BIT = 1 then // begin // H_Bridge_A_Lo := 1; // Short the Rails // H_Bridge_B_Lo := 1; // end else // ToggleBridge // end else ToggleBridge; // Now we can update the xxxx_DCC_PIN_BIT flags for the next 56us time slot NMRA_DCC_58us_TimeTick(@Track); // < 1us // NMRA_DCC_TransmitterStateMachine(@Track, False, CommandStationConfigurationShadowRam.RailComEnable = CONFIG_RAILCOM_ENABLED); // < 5us NMRA_DCC_TransmitterStateMachine(@Track, False, False); // < 5us NMRA_DCC_LoadPacketIntoTransmitterStateMachine(@Track, PREAMBLE_BIT_COUNT_NORMAL); // < 11us Max end end; end; procedure OPStack_100ms_Timer(); iv IVT_ADDR_T2INTERRUPT; ics ICS_AUTO; begin T2IF_bit := 0; OPStackCore_Timer; end; begin H_Bridge_A_Lo_Direction := 0; H_Bridge_A_Hi_Direction := 0; H_Bridge_B_Lo_Direction := 0; H_Bridge_B_Hi_Direction := 0; { Main program } NMRA_DCC_Initialize(4060); // DCC_TIMER_58US = 4060; // Clock ticks every 1/140Mhz * 2 * 4060 = 58us interrupts MCU_Setup_Initialize; MCU_EnableSerialFlash; MCU_EnableUARTA; MCU_EnableTFT; TFT_BLED_Direction := 0; // Set TFT backlight pin as output TFT_BLED := 1; // Turn on TFT backlight DrawFrame(); OPStackCore_Initialize; MCU_EnableCAN; MCU_Enable100msTimer; MCU_EnableDCCTimer(4060); // DCC_TIMER_58US = 4060; // Clock ticks every 1/140Mhz * 2 * 4060 = 58us interrupts OPStackCore_Enable(True); UART1_Write_Text('Mustangpeak DCC Command Station v0.1 Booted'+LF); delay_ms(100); while True do begin OPStackCore_Process; if UART1_Data_Ready then begin case UART1_Read of 'B','b' : OPStackBuffers_PrintBuffers; 'A', 'a' : OPStackNode_PrintAliases; 'D', 'd' : begin WordToStr(Track.Main.Count, s1); UART1_Write_Text('DCC Track Count: ' + s1 + LF); WordToStr(Track.Main.MaxCount, s1); UART1_Write_Text('DCC Track MaxCount: ' + s1 + LF); WordToStr(Track.Main.Peak, s1); UART1_Write_Text('DCC Track Peak: ' + s1 + LF); WordToStr(Track.Priority.Count, s1); UART1_Write_Text('DCC Track Priority Count: ' + s1 + LF); WordToStr(Track.Priority.MaxCount, s1); UART1_Write_Text('DCC Track Priority MaxCount: ' + s1 + LF); WordToStr(Track.Priority.Peak, s1); UART1_Write_Text('DCC Track Priority Peak: ' + s1 + LF); end; end; end; end; end.