Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: DRIVERS/CHEM_BOX_COMMON.cpp
- Revision:
- 0:7798270c1f52
- Child:
- 1:d64ac853223c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DRIVERS/CHEM_BOX_COMMON.cpp Sat Jan 25 19:10:17 2014 +0000
@@ -0,0 +1,1828 @@
+#include "mbed.h"
+#include "CHEM_BOX_INTERFACE.h"
+#include "MODSERIAL.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+//Mbed Objects
+
+DigitalOut AIO_ADC1_CS(p30);
+
+DigitalOut AIO_ADC2_CS(p29);
+
+PwmOut BUZZER_CONTROL(p26);
+
+DigitalOut MCU_SR_CLEAR(p25);
+
+DigitalOut AIO_DAC1_CS(p24);
+
+DigitalOut AIO_DAC2_CS(p23);
+
+DigitalOut MFC_POWER_CONTROL(p22);
+
+PwmOut FAN_CONTROL(p21);
+
+SPI SPI1(p5,p6,p7);
+
+DigitalOut MCU_SR_LOAD(p8);
+
+SPI SPI0(p11,p12,p13);
+
+DigitalOut SmartSwitch_SS(p14);
+
+BusOut TEMP_SENSE_ADDRESS(p15,p16,p17,p18);
+
+DigitalOut TEMP_SENSE_CS(p19);
+
+DigitalIn LCD_SWITCH(p20);
+
+MODSERIAL RS232_0(p9, p10, 1024, 1024);
+
+MODSERIAL RS232_1(p28, p27, 1024, 1024);
+
+// Make TX buffer 1024bytes and RX buffer use 512bytes.
+MODSERIAL PC(USBTX, USBRX, 1024, 1024); // tx, rx
+
+//Local Variables
+
+
+static uint8_t HeaterBits = 0;
+
+static uint16_t SolenoidBits = 0;
+
+static uint8_t DigitalOutputBits = 0;
+
+Timeout BuzzTimeout;
+
+static uint16_t Thermocouple_FAULT = 0;
+
+static uint16_t Thermocouple_SCV = 0;
+
+static uint16_t Thermocouple_SCG = 0;
+
+static uint16_t Thermocouple_OC= 0;
+
+static float Temperature[12];
+
+static float InternalTemperature[12];
+
+static uint16_t ReadRawADC(uint8_t Channel);
+
+
+//Local Functions
+
+void InitTerminal();
+
+void WriteRAW_DAC_Value(uint8_t Channel,uint16_t Data);
+
+
+
+void InitChemBox()
+{
+
+ AIO_ADC1_CS = 1;
+
+ AIO_ADC2_CS = 1;
+
+ BUZZER_CONTROL.period_ms(1.0);
+
+ MCU_SR_CLEAR = 1;
+
+ AIO_ADC1_CS = 1;
+
+ AIO_ADC2_CS = 1;
+
+ MFC_POWER_CONTROL = 0;
+
+ FAN_CONTROL.period_us(1000);
+
+ FAN_CONTROL.write(0);
+
+ SPI1.format(8,0);
+
+ SPI1.frequency(4000000);
+
+ MCU_SR_LOAD = 0;
+
+ SPI0.format(8,0);
+
+ SPI0.frequency(4000000);
+
+ SmartSwitch_SS = 1;
+
+ TEMP_SENSE_ADDRESS = 0;
+
+ TEMP_SENSE_CS = 1;
+
+ HeaterBits = 0;
+
+ SolenoidBits = 0;
+
+ DigitalOutputBits = 0;
+
+ Thermocouple_FAULT = 0;
+
+ Thermocouple_SCV = 0;
+
+ Thermocouple_SCG = 0;
+
+ Thermocouple_OC= 0;
+
+ InitTerminal();
+
+ GFX_Init();
+}
+
+
+void SetFanSpeed(uint8_t S)
+{
+ if(S>100)
+ S = 100;
+
+ FAN_CONTROL = (float)(S)/100.0;
+
+}
+
+void EnableFan()
+{
+ SetFanSpeed(100);
+}
+
+void DisableFan()
+{
+ SetFanSpeed(0);
+}
+
+void BuzzOff()
+{
+ BUZZER_CONTROL = 0;
+}
+
+void Buzz(float Time)
+{
+ BUZZER_CONTROL = 0.5;
+ BuzzTimeout.attach(&BuzzOff, Time);
+
+}
+
+
+void EnableHeater(uint8_t RelayIndex)
+{
+ HeaterBits |= (1<<RelayIndex);
+}
+
+void DisableHeater(uint8_t RelayIndex)
+{
+ HeaterBits &= ~(1<<RelayIndex);
+}
+
+void EnableSolenoidValve(uint8_t SolenoidIndex)
+{
+ SolenoidBits |= (1<<SolenoidIndex);
+}
+
+void DisableSolenoidValue(uint8_t SolenoidIndex)
+{
+ SolenoidBits &= ~(1<<SolenoidIndex);
+}
+
+void DisableAllHeatersAndSolenoids()
+{
+
+ SolenoidBits = 0;
+ HeaterBits = 0;
+
+ MCU_SR_CLEAR = 1;
+
+ MCU_SR_CLEAR = 0;
+
+ MCU_SR_CLEAR = 1;
+
+ MCU_SR_LOAD = 1;
+
+ MCU_SR_LOAD = 0;
+}
+
+void EnableMiscDigitalOutput(uint8_t DigitalOutIndex)
+{
+ DigitalOutputBits |= (1<<DigitalOutIndex);
+}
+
+void DisableMiscDigitalOutput(uint8_t DigitalOutIndex)
+{
+ DigitalOutputBits &= ~(1<<DigitalOutIndex);
+}
+
+void FlushDigitalIO()
+{
+ SPI1.format(8,0);
+
+ SPI1.write((SolenoidBits >> 8) & 0xFF);
+ SPI1.write(SolenoidBits & 0xFF);
+ SPI1.write(HeaterBits & 0xFF);
+ SPI1.write(DigitalOutputBits & 0xFF);
+
+ MCU_SR_LOAD = 1;
+ MCU_SR_LOAD = 0;
+}
+
+//Make sure to call ReadThermocouple befor eyou call this so internal variables are updated
+uint16_t ReadThermocouple_OC()
+{
+ return Thermocouple_OC;
+}
+//Make sure to call ReadThermocouple befor eyou call this so internal variables are updated
+uint16_t ReadThermocouple_SCG()
+{
+ return Thermocouple_SCG;
+}
+//Make sure to call ReadThermocouple befor eyou call this so internal variables are updated
+uint16_t ReadThermocouple_SCV()
+{
+ return Thermocouple_SCV;
+}
+//Make sure to call ReadThermocouple befor eyou call this so internal variables are updated
+uint16_t ReadThermocouple_FAULT()
+{
+ return Thermocouple_FAULT;
+}
+
+
+float ReadInternalTemperature(uint8_t ThermocoupleIndex)
+{
+ ReadThermocouple(ThermocoupleIndex); //this will yank out the Data
+ return InternalTemperature[ThermocoupleIndex];
+}
+
+
+
+float ReadThermocouple(uint8_t ThermocoupleIndex)
+{
+ uint8_t i=0;
+ uint32_t ThermocoupleData = 0;
+ uint8_t TempData[4];
+
+ int16_t InternalTemp = 0;
+ int16_t ThermocoupleTemp = 0;
+
+ //reset SPi format
+ SPI1.format(8,0);
+
+ TEMP_SENSE_ADDRESS = ThermocoupleIndex & 0x1f;
+
+ TEMP_SENSE_CS = 0;
+
+ for(i=0;i<4;i++)
+ TempData[i] = SPI1.write(0);
+
+ TEMP_SENSE_CS = 1;
+
+
+ ThermocoupleData = (uint32_t)(TempData[3]) |
+ (((uint32_t)(TempData[2]))<<8) |
+ (((uint32_t)(TempData[1]))<<16) |
+ (((uint32_t)(TempData[0]))<<24);
+
+
+ if(ThermocoupleData & 0x01)
+ Thermocouple_OC |= (1<<ThermocoupleIndex);
+ else
+ Thermocouple_OC &= ~(1<<ThermocoupleIndex);
+
+ if(ThermocoupleData & 0x02)
+ Thermocouple_SCG |= (1<<ThermocoupleIndex);
+ else
+ Thermocouple_SCG &= ~(1<<ThermocoupleIndex);
+
+ if(ThermocoupleData & 0x04)
+ Thermocouple_SCV |= (1<<ThermocoupleIndex);
+ else
+ Thermocouple_SCV &= ~(1<<ThermocoupleIndex);
+
+ if(ThermocoupleData & (1<<16))
+ Thermocouple_FAULT |= (1<<ThermocoupleIndex);
+ else
+ Thermocouple_FAULT &= ~(1<<ThermocoupleIndex);
+
+ if(ThermocoupleData & (1<<15))
+ InternalTemp = (int16_t) ( ( (ThermocoupleData>>4) & 0xFFF) | 0xF000); //Sign extend in this case.... we need to map a 12 bit signed number to 16-bits
+ else
+ InternalTemp = (int16_t)( ( (ThermocoupleData>>4) & 0xFFF));
+
+
+ if(ThermocoupleData & (0x10000000))
+ ThermocoupleTemp = (int16_t)(((ThermocoupleData>>18) & 0x2FFF) | 0xC000); //Sign extend in this case.... we need to map a 14 bit signed number to 16-bits
+ else
+ ThermocoupleTemp = (int16_t)(((ThermocoupleData>>18) & 0x2FFF));
+
+ Temperature[ThermocoupleIndex] = (float)ThermocoupleTemp/4.0;
+
+ InternalTemperature[ThermocoupleIndex] = (float)InternalTemp/16.0;;
+
+ return Temperature[ThermocoupleIndex];
+}
+
+float ReadMFC_AnalogInput(uint8_t Channel)
+{
+ if(Channel > 7)
+ Channel = 7;
+
+ return ((float)(ReadRawADC(Channel)) /4095.0) * 5.0;
+
+}
+
+void EnableMFC_Power()
+{
+ MFC_POWER_CONTROL = 1;
+}
+
+void DisableMFC_Power()
+{
+ MFC_POWER_CONTROL = 0;
+}
+
+
+float ReadMISC_AnalogInput(uint8_t Channel)
+{
+
+ if(Channel > 3)
+ Channel = 3;
+
+ return ((float)(ReadRawADC(Channel + 9)) /4095.0) * 5.0;
+
+}
+
+float Read4to20(uint8_t Channel)
+{
+
+ if(Channel > 1)
+ Channel = 1;
+
+ return (((float)(ReadRawADC(Channel + 7)) /4095.0) * 5.0) / 240;
+
+}
+
+
+static uint16_t ReadRawADC(uint8_t Channel)
+{
+ uint8_t ControlByte[3];
+ uint8_t ADC_Data[3];
+ uint16_t V;
+
+ SPI0.format(8,0); //The ADC requires mode 0,0
+
+ /*See Microchip manual DS21298E-page 21*/
+
+ ControlByte[0] = (((Channel&0x07)>>2) & 0x01) | (3<<1);
+ ControlByte[1] = Channel<<6;
+ ControlByte[2] = 0;
+
+
+ if(Channel<8)
+ AIO_ADC1_CS = 0;
+ else
+ AIO_ADC2_CS = 0;
+
+ //unroll the loop
+ ADC_Data[0] = SPI0.write(ControlByte[0]);
+ ADC_Data[1] = SPI0.write(ControlByte[1]);
+ ADC_Data[2] = SPI0.write(ControlByte[2]);
+
+ AIO_ADC1_CS = 1;
+ AIO_ADC2_CS = 1;
+
+
+ V = ((uint16_t)(ADC_Data[1])<<8 | (uint16_t)(ADC_Data[2])) & 0xFFF;
+
+ return (V);
+
+}
+
+
+void WriteMFC_AnalogOut(uint8_t Channel,float Value)
+{
+
+ if(Channel>7)
+ Channel = 7;
+
+ if(Value >5.0)
+ Value = 5.0;
+
+ if(Value<0.0)
+ Value = 0.0;
+
+ WriteRAW_DAC_Value(Channel,(uint16_t)((Value/5.0) * 4095));
+
+}
+
+void WriteMISC_AnalogOut(uint8_t Channel,float Value)
+{
+ if(Channel>3)
+ Channel = 3;
+
+ if(Value >5.0)
+ Value = 5.0;
+
+ if(Value<0.0)
+ Value = 0.0;
+
+ WriteRAW_DAC_Value(8+Channel,(uint16_t)((Value/5.0)*4095));
+}
+
+
+void WriteRAW_DAC_Value(uint8_t Channel,uint16_t Data)
+{
+
+ uint16_t DataOut;
+
+ if(Channel<8)
+ AIO_DAC1_CS = 0;
+ else
+ AIO_DAC2_CS = 0;
+
+ SPI0.format(8,1); //The DAC requires mode 0,1
+
+ DataOut = ((uint16_t)(Channel) & 0x7)<<12 | (Data & 0xFFF);
+
+ SPI0.write((DataOut>>8)&0xFF);
+ SPI0.write(DataOut&0xFF);
+
+ AIO_DAC1_CS = 1;
+ AIO_DAC2_CS = 1;
+
+}
+
+
+
+
+#define MAX_TERMINAL_LINE_CHARS 128
+#define MAX_TERMINAL_CMD_CHARS 64
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+typedef void (*TerminalCallback)(char *);
+
+
+typedef struct
+{
+ const char *CommandString;
+ TerminalCallback Callback;
+ const char *HelpString;
+
+} TerminalCallbackRecord;
+
+//Callback function prototypes
+void TerminalCmd_Help(char *arg);
+void TerminalCmd_Stub(char *arg);
+void TerminalCmd_EnableHeater(char *arg);
+void TerminalCmd_DisableHeater(char *arg);
+void TerminalCmd_EnableSolenoidValve(char *arg);
+void TerminalCmd_DisableSolenoidValue(char *arg);
+void TerminalCmd_DisableAllHeatersAndSolenoids(char *arg);
+void TerminalCmd_EnableMiscDigitalOutput(char *arg);
+void TerminalCmd_DisableMiscDigitalOutput(char *arg);
+void TerminalCmd_FlushDigitalIO(char *arg);
+void TerminalCmd_FanOn(char *arg);
+void TerminalCmd_FanOff(char *arg);
+void TerminalCmd_Buzz(char *arg);
+void TerminalCmd_T(char *arg);
+void TerminalCmd_MFCI(char *arg);
+void TerminalCmd_MFCO(char *arg);
+void TerminalCmd_4TO20(char *arg);
+void TerminalCmd_AIN(char *arg);
+void TerminalCmd_MFCON(char *arg);
+void TerminalCmd_MFCOFF(char *arg);
+void TerminalCmd_AOUT(char *arg);
+void TerminalCmd_Reset(char *arg);
+
+//Populate this array with the callback functions and their terminal command string
+TerminalCallbackRecord MyTerminalCallbackRecords[] ={ {"reset",TerminalCmd_Reset,"Resets the CHEM box"},
+
+ {"help",TerminalCmd_Help,"Lists available commands"},
+
+ {"EH",TerminalCmd_EnableHeater,"Enables a heater channel. Argument should be between 0 and 7. Outputs will update when a FDIO command is issued"},
+
+ {"DH",TerminalCmd_DisableHeater,"Disables a heater channel. Argument should be between 0 and 7. Outputs will update when a FDIO command is issued"},
+
+ {"ESV",TerminalCmd_EnableSolenoidValve,"Enables a solenoid channel. Argument should be between 0 and 11. Outputs will update when a FDIO command is issued"},
+
+ {"DSV",TerminalCmd_DisableSolenoidValue,"Disables a solenoid channel. Argument should be between 0 and 11. Outputs will update when a FFDIO command is issued"},
+
+ {"DAHAS",TerminalCmd_DisableAllHeatersAndSolenoids,"Disables all heaters and solenoids. Command is immediately executed."},
+
+ {"EMDO",TerminalCmd_EnableMiscDigitalOutput,"Enables a misc. digital output. Argument should be between 0 and 3. Output will update when a FDIO command is issued"},
+
+ {"DMDO",TerminalCmd_DisableMiscDigitalOutput,"Enables a misc. digital output. Argument should be between 0 and 3. Output will update when a FDIO command is issued"},
+
+ {"FDIO",TerminalCmd_FlushDigitalIO,"Updates the all of the digital IO channels"},
+
+ {"FON",TerminalCmd_FanOn,"Turns on the fans"},
+
+ {"FOFF",TerminalCmd_FanOff,"Turns off the fans"},
+
+ {"BUZZ",TerminalCmd_Buzz,"Buzz for a little bit. Argument should be a floating point number representing the number of seconds to buzz"},
+
+ {"T",TerminalCmd_T,"Read thermocouple channel"},
+
+ {"MFCI",TerminalCmd_MFCI,"Reads in voltage from MFC channel"},
+
+ {"MFCO",TerminalCmd_MFCO,"Sets voltage at MFC output channel. First argument should be the channel. Second argument should be the voltage. I.E. MFCO 1.45"},
+
+ {"AOUT",TerminalCmd_AOUT,"Sets voltage at misc. output channel. First argument should be the channel. Second argument should be the voltage. I.E. AOUT 3.211"},
+
+ {"4TO20",TerminalCmd_4TO20,"Reads a 4 to 20 mA channel"},
+
+ {"AIN",TerminalCmd_AIN,"Reads a general purpose analog in channel"},
+
+ {"MFCON",TerminalCmd_MFCON,"Turns on the MFC power"},
+
+ {"MFCOFF",TerminalCmd_MFCOFF,"Turns off the MFC power"}
+ };
+
+
+extern "C" void mbed_reset();
+
+void TerminalCmd_Reset(char *arg)
+{
+ mbed_reset();
+}
+
+void TerminalCmd_Stub(char *arg)
+{
+ PC.printf("stub \r\n");
+}
+
+void TerminalCmd_MFCI(char *arg)
+{
+ int Channel = -1;
+ float Data;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ if(Channel>=0 && Channel <=6)
+ {
+ Data = ReadMFC_AnalogInput(Channel);
+ PC.printf("MFCI:%d:%.3f",Channel,Data);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 6",Channel);
+ }
+ }
+ else
+ {
+ for(Channel = 0; Channel<=6; Channel++)
+ {
+ Data = ReadMFC_AnalogInput(Channel);
+ PC.printf("MFCI:%d:%.3f\r\n",Channel,Data);
+ }
+ }
+}
+
+void TerminalCmd_MFCON(char *arg)
+{
+ EnableMFC_Power();
+}
+
+
+void TerminalCmd_MFCOFF(char *arg)
+{
+ DisableMFC_Power();
+}
+
+
+void TerminalCmd_MFCO(char *arg)
+{
+ int Channel = -1;
+ float Data = 0.0;
+
+ if(sscanf(arg,"%d %f",&Channel,&Data) == 2)
+ {
+ if(Channel>=0 && Channel <=7)
+ {
+ WriteMFC_AnalogOut(Channel,Data);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 1",Channel);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Channel should be an integer between 0 and 7 and value should be a float between 0.0 and 5.0. i.e. MFCO 2 4.45",arg);
+ }
+}
+
+void TerminalCmd_AOUT(char *arg)
+{
+ int Channel = -1;
+ float Data = 0.0;
+
+ if(sscanf(arg,"%d %f",&Channel,&Data) == 2)
+ {
+ if(Channel>=0 && Channel <=3)
+ {
+ WriteMISC_AnalogOut(Channel,Data);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 3",Channel);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Channel should be an integer between 0 and 7 and value should be a float between 0.0 and 5.0. i.e. AOUT 1 1.25",arg);
+ }
+}
+
+void TerminalCmd_4TO20(char *arg)
+{
+ int Channel = -1;
+ float Data;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ if(Channel>=0 && Channel <=1)
+ {
+ Data = Read4to20(Channel);
+ PC.printf("4TO20:%d:%.3f",Channel,Data);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 1",Channel);
+ }
+ }
+ else
+ {
+
+ for(Channel = 0;Channel<=1;Channel++)
+ {
+ Data = Read4to20(Channel);
+ PC.printf("4TO20:%d:%.3f\r\n",Channel,Data);
+ }
+
+ }
+
+
+}
+
+void TerminalCmd_AIN(char *arg)
+{
+ int Channel = -1;
+ float Data;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ if(Channel>=0 && Channel <=3)
+ {
+ Data = ReadMISC_AnalogInput(Channel);
+ PC.printf("AIN:%d:%.3f",Channel,Data);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 3",Channel);
+ }
+ }
+ else
+ {
+ for(Channel = 0;Channel<=3;Channel++)
+ {
+ Data = ReadMISC_AnalogInput(Channel);
+ PC.printf("AIN:%d:%.3f\r\n",Channel,Data);
+ }
+ }
+}
+
+
+
+void TerminalCmd_EnableHeater(char *arg)
+{
+ int Channel = -1;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ if(Channel>=0 && Channel <=7)
+ {
+ EnableHeater(Channel);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 7",Channel);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Should be integer between 0 and 7",arg);
+ }
+}
+
+void TerminalCmd_DisableHeater(char *arg)
+{
+int Channel = -1;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ if(Channel>=0 && Channel <=7)
+ {
+ DisableHeater(Channel);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 7",Channel);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Should be integer between 0 and 7",arg);
+ }
+
+}
+
+void TerminalCmd_EnableSolenoidValve(char *arg)
+{
+
+int Channel = -1;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ if(Channel>=0 && Channel <=11)
+ {
+ EnableSolenoidValve(Channel);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 11",Channel);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Should be integer between 0 and 11",arg);
+ }
+}
+
+void TerminalCmd_DisableSolenoidValue(char *arg)
+{
+int Channel = -1;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ if( Channel >= 0 && Channel <= 11)
+ {
+ DisableSolenoidValue(Channel);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 11",Channel);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Should be integer between 0 and 11",arg);
+ }
+
+}
+void TerminalCmd_DisableAllHeatersAndSolenoids(char *arg)
+{
+
+ DisableAllHeatersAndSolenoids();
+
+}
+
+void TerminalCmd_EnableMiscDigitalOutput(char *arg)
+{
+int Channel = -1;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ if(Channel>=0 && Channel <=3)
+ {
+ EnableMiscDigitalOutput(Channel);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 3",Channel);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Should be integer between 0 and 3",arg);
+ }
+
+}
+
+void TerminalCmd_DisableMiscDigitalOutput(char *arg)
+{
+int Channel = -1;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ if(Channel>=0 && Channel <=3)
+ {
+ DisableMiscDigitalOutput(Channel);
+ }
+ else
+ {
+ PC.printf("%d is an invalid channel. Channel should be integer between 0 and 3",Channel);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Should be integer between 0 and 3",arg);
+ }
+
+}
+
+void TerminalCmd_FlushDigitalIO(char *arg)
+{
+ FlushDigitalIO();
+}
+
+void TerminalCmd_FanOn(char *arg)
+{
+ SetFanSpeed(100); //PWMing the FANs doesn't work with the ME40100V1 models! WE will just on or off
+}
+
+void TerminalCmd_FanOff(char *arg)
+{
+ SetFanSpeed(0); //PWMing the FANs doesn't work with the ME40100V1 models! WE will just on or off
+}
+
+void TerminalCmd_Fan(char *arg)
+{
+int Speed = -1;
+
+ if(sscanf(arg,"%d",&Speed) == 1)
+ {
+ if(Speed>=0 && Speed<=100)
+ {
+ SetFanSpeed(Speed);
+ }
+ else
+ {
+ PC.printf("%d is an invalid speed. Speed should be between 0 and 100",Speed);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Should be integer between 0 and 100",arg);
+ }
+
+}
+
+
+void TerminalCmd_T(char *arg)
+{
+ float Temp = 0;
+ int Channel = -1;
+
+ if(sscanf(arg,"%d",&Channel) == 1)
+ {
+ Temp = ReadThermocouple(Channel);
+ PC.printf("TEMP:%d:%.2f\r\n",Channel,Temp);
+ }
+ else
+ {
+ for(Channel = 0; Channel<12;Channel++)
+ {
+ Temp = ReadThermocouple(Channel);
+ PC.printf("TEMP:%d:%.2f\r\n",Channel,Temp);
+ }
+ }
+}
+
+void TerminalCmd_Buzz(char *arg)
+{
+
+ float T = -1.0;
+
+ if(sscanf(arg,"%f",&T) == 1)
+ {
+ if(T>=0.0 && T<=5.0)
+ {
+ Buzz(T);
+ }
+ else
+ {
+ PC.printf("%f is an invalid time period for buzz. Time should be between 0.0 and 5.0 seconds",T);
+ }
+ }
+ else
+ {
+ PC.printf("Bad argument... %s. Should be float between 0.0 and 5.0",arg);
+ }
+
+}
+
+
+
+
+//*****************************************************************
+//Plumbing.....
+//*****************************************************************
+
+#define NUM_TERMINAL_COMMANDS (sizeof(MyTerminalCallbackRecords)/sizeof(TerminalCallbackRecord))
+
+char TerminalLineBuf[MAX_TERMINAL_LINE_CHARS];
+uint8_t TerminalPos;
+char TerminalCmdBuf[MAX_TERMINAL_CMD_CHARS+1];
+char TerminalArgs[MAX_TERMINAL_LINE_CHARS-MAX_TERMINAL_CMD_CHARS];
+uint8_t NextCharIn;
+uint8_t CmdFound;
+
+void TerminalBootMsg()
+{
+
+PC.printf("\r\n\r\n");
+PC.printf("***********************************\r\n");
+PC.printf("CHEM Control Box \r\n");
+PC.printf("API Version %s \r\n",API_VERSION);
+PC.printf("Copyright (C) <2013> Eli Hughes\r\n");
+PC.printf("Wavenumber LLC\r\n");
+PC.printf("***********************************\r\n\r\n>");
+
+}
+
+void InitTerminal()
+{
+
+ PC.baud(115200);
+ TerminalPos = 0;
+ CmdFound = 0;
+ TerminalBootMsg();
+}
+
+void TerminalCmd_Help(char *arg)
+{
+ uint8_t i;
+
+ PC.printf("\r\n\r\nCommand List:\r\n");
+ PC.printf("----------------------\r\n");
+
+ for(i=0;i<NUM_TERMINAL_COMMANDS;i++)
+ {
+ PC.printf("%s ----> %s\r\n\r\n",MyTerminalCallbackRecords[i].CommandString,MyTerminalCallbackRecords[i].HelpString);
+ }
+
+ PC.printf("\r\n\r\n");
+}
+
+void TerminalCmd_Reboot(char *arg)
+{
+ TerminalBootMsg();
+}
+
+void ProcessTerminal()
+{
+ uint8_t i,j;
+ uint8_t ArgsFound;
+
+ if(PC.readable())
+ {
+ NextCharIn = PC.getc();
+
+ switch(NextCharIn)
+ {
+ case '\r':
+
+ TerminalLineBuf[TerminalPos++] = 0x0;
+ PC.putc(NextCharIn);
+
+ if(TerminalPos > 1)
+ {
+ //find the command
+ i=0;
+ while(TerminalLineBuf[i]>0x20 && TerminalLineBuf[i]<0x7f)
+ {
+ TerminalCmdBuf[i] = TerminalLineBuf[i];
+ i++;
+
+ if(i==MAX_TERMINAL_CMD_CHARS)
+ {
+ break;
+ }
+ }
+
+ TerminalCmdBuf[i] = 0;
+ TerminalCmdBuf[i+1] = 0;
+
+
+ ArgsFound = TRUE;
+ memset(TerminalArgs,0x00,sizeof(TerminalArgs));
+ //scan for num terminator or next non whitespace
+ while(TerminalLineBuf[i]<=0x20 && (i<MAX_TERMINAL_LINE_CHARS))
+ {
+ if(TerminalLineBuf[i] == 0x00)
+ {
+
+ //if we find a NULL terminator before a non whitespace character they flag for no arguments
+ ArgsFound = FALSE;
+ break;
+ }
+ i++;
+ }
+
+ if(ArgsFound == TRUE)
+ {
+ strcpy(TerminalArgs,&TerminalLineBuf[i]);
+
+ //trim trailing whitespace
+ i = sizeof(TerminalArgs)-1;
+
+ while((TerminalArgs[i]<0x21) && (i>0))
+ {
+ TerminalArgs[i]= 0x00;
+ i--;
+ }
+ }
+
+ CmdFound = FALSE;
+ for(j=0;j<NUM_TERMINAL_COMMANDS;j++)
+ {
+ if(strcmp(TerminalCmdBuf,MyTerminalCallbackRecords[j].CommandString) == 0)
+ {
+ PC.printf("\r\n");
+ if(MyTerminalCallbackRecords[j].Callback != NULL)
+ MyTerminalCallbackRecords[j].Callback(TerminalArgs);
+
+ CmdFound = TRUE;
+ break;
+ }
+ }
+ if(CmdFound == FALSE)
+ {
+ PC.printf("\r\n%s command not recognized.\r\n\r\n",TerminalCmdBuf);
+ TerminalCmd_Help("no arg");
+
+ }
+ }
+ PC.printf("\r\n>");
+ TerminalPos = 0;
+
+ break;
+
+ case '\b':
+ if(TerminalPos > 0)
+ {
+ TerminalPos--;
+ PC.putc(NextCharIn);
+ }
+ break;
+
+ default:
+
+ if(TerminalPos == 0 && NextCharIn == 0x020)
+ {
+ //Do nothing if space bar is pressed at beginning of line
+ }
+ else if(NextCharIn >= 0x20 && NextCharIn<0x7F)
+ {
+
+ if(TerminalPos < MAX_TERMINAL_LINE_CHARS-1)
+ {
+ TerminalLineBuf[TerminalPos++] = NextCharIn;
+ PC.putc(NextCharIn);
+ }
+ }
+
+ break;
+
+ }
+ }
+
+}
+
+
+
+
+
+// _ _____ _____ _______ _____ _____ _ _ _____ _____ _____
+// | | / ____| __ \ / / ____| __ \ /\ | __ \| | | |_ _/ ____|/ ____|
+// | | | | | | | | / / | __| |__) | / \ | |__) | |__| | | || | | (___
+// | | | | | | | |/ /| | |_ | _ / / /\ \ | ___/| __ | | || | \___ \
+// | |___| |____| |__| / / | |__| | | \ \ / ____ \| | | | | |_| || |____ ____) |
+// |______\_____|_____/_/ \_____|_| \_\/_/ \_\_| |_| |_|_____\_____|_____/
+//
+//
+
+void SmartSwitch_Reset();
+void SmartSwitch_SetBrightness(uint8_t Brightness);
+void InitSmartSwitch();
+void PowerUpSmartSwitch();
+void PowerDownSmartSwitch();
+void SmartSwitchWriteByte(uint8_t DataOut);
+void SmartSwitch_SetBackLightColor2(uint8_t RGB);
+void SmartSwitch_ImageDump(uint8_t *Img);
+void SmartSwitchClear();
+
+
+
+
+#define BACK_BUFFER_SIZE_X (64)
+#define BACK_BUFFER_SIZE_Y (32)
+
+#define PHYSICAL_DISPLAY_XRES (uint8_t)(64)
+#define PHYSICAL_DISPLAY_YRES (uint8_t)(32)
+#define DISPLAY_X_WIDTH_BYTE (PHYSICAL_DISPLAY_XRES>>3)
+#define DISPLAY_BUFFER_TOTAL_SIZE (DISPLAY_X_WIDTH_BYTE*PHYSICAL_DISPLAY_YRES*2)
+#define GREEN_DATA_BUFFER_OFFSET (DISPLAY_X_WIDTH_BYTE * PHYSICAL_DISPLAY_YRES)
+#define PHYSICAL_DISPLAY_X_WIDTH_IN_BYTES (PHYSICAL_DISPLAY_XRES>>3)
+#define PHYSICAL_DISPLAY_PLANE_BUFFER_SIZE (PHYSICAL_DISPLAY_X_WIDTH_IN_BYTES * PHYSICAL_DISPLAY_YRES)
+#define PHYSICAL_DISPLAY_BUFFER_TOTAL_SIZE (PHYSICAL_DISPLAY_X_WIDTH_IN_BYTES * PHYSICAL_DISPLAY_YRES*2)
+
+#define SMART_SWITCH_CMD_DISPLAY_DATA 0x55
+#define SMART_SWITCH_CMD_SET_BACKLIGHT_COLOR 0x40
+#define SMART_SWITCH_CMD_SET_BRIGHTNESS 0x41
+#define SMART_SWITCH_CMD_RESET 0x5E
+#define SMART_SWITCH_CMD_RESET_PARAMETER 0x03
+
+#define SMART_SWITCH_BACKLIGHT_RED (0x03<<4)
+#define SMART_SWITCH_BACKLIGHT_YELLOW (0x03<<4)|(0x03<<2)
+#define SMART_SWITCH_BACKLIGHT_GREEN (0x03<<2)
+
+ #define GFX_MAX_STRING_LEN 32
+
+void SmartSwitch_ImageDump(uint8_t *Img)
+{
+ int i;
+
+ SPI1.format(8,2);
+
+ SmartSwitch_SS = 0;
+ SmartSwitchWriteByte(SMART_SWITCH_CMD_DISPLAY_DATA);
+
+ for(i=0;i<256;i++)
+ {
+ SmartSwitchWriteByte(Img[i]);
+ }
+
+ SmartSwitch_SS = 1;
+}
+
+void SmartSwitchClear()
+{
+ int i;
+
+
+ SPI1.format(8,2);
+
+ SmartSwitch_SS = 0;
+ SmartSwitchWriteByte(SMART_SWITCH_CMD_DISPLAY_DATA);
+
+ for(i=0;i<256;i++)
+ {
+ SmartSwitchWriteByte(0x00);
+ }
+
+ SmartSwitch_SS = 1;
+}
+
+void SmartSwitch_Reset()
+{
+
+ SPI1.format(8,2);
+
+ SmartSwitch_SS = 0;
+ SmartSwitchWriteByte(SMART_SWITCH_CMD_RESET);
+ SmartSwitchWriteByte(SMART_SWITCH_CMD_RESET_PARAMETER);
+ SmartSwitch_SS = 1;
+}
+
+void SmartSwitch_SetBackLightColor(uint8_t Red,uint8_t Green,uint8_t Blue)
+{
+
+ SPI1.format(8,2);
+
+ SmartSwitch_SS = 0;
+ SmartSwitchWriteByte(SMART_SWITCH_CMD_SET_BACKLIGHT_COLOR);
+ SmartSwitchWriteByte(Red<<6 | Green<<4 | Blue <<2 | 0x3);
+ SmartSwitch_SS = 1;
+}
+
+void SmartSwitch_SetBackLightColor2(uint8_t RGB)
+{
+ SPI1.format(8,2);
+
+ SmartSwitch_SS = 0;
+ SmartSwitchWriteByte(SMART_SWITCH_CMD_SET_BACKLIGHT_COLOR);
+ SmartSwitchWriteByte(RGB<<2 | 0x3);
+ SmartSwitch_SS = 1;
+}
+
+void SmartSwitch_SetBrightness(uint8_t Brightness)
+{
+ SPI1.format(8,2);
+
+ SmartSwitch_SS = 0;
+ SmartSwitchWriteByte(SMART_SWITCH_CMD_SET_BRIGHTNESS);
+ SmartSwitchWriteByte(Brightness<<5 | 0x1F);
+ SmartSwitch_SS = 1;
+}
+
+void InitSmartSwitch()
+{
+ SmartSwitch_SS = 1;
+ SmartSwitch_Reset();
+}
+
+void SmartSwitchWriteByte(uint8_t DataOut)
+{
+
+ SPI1.write(DataOut);
+
+}
+
+
+//Linking Functions to Physical Screen
+//***********************************************************************************
+
+void GFX_InitPhysicalScreen()
+{
+ InitSmartSwitch();
+}
+
+
+const uint8_t BitReverseTable[256] =
+{
+0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+void GFX_DumpRenderContextToPhysicalScreen(RenderContext *Image)
+{
+ int x,y;
+ uint8_t NextByteOut;
+
+ SPI1.format(8,2);
+
+ SmartSwitch_SS = 0;
+ SmartSwitchWriteByte(SMART_SWITCH_CMD_DISPLAY_DATA);
+
+ for(y=0;y<PHYSICAL_DISPLAY_YRES;y++)
+ {
+ for(x=0;x<PHYSICAL_DISPLAY_X_WIDTH_IN_BYTES;x++)
+ {
+ //Need to rotate the display 180 degrees
+ NextByteOut = Image->RenderPlane.BitPlaneSpace[(((PHYSICAL_DISPLAY_YRES - y - 1) * PHYSICAL_DISPLAY_X_WIDTH_IN_BYTES)) + x];
+ SmartSwitchWriteByte(BitReverseTable[NextByteOut]);
+ }
+ }
+ SmartSwitch_SS = 1;
+}
+
+
+//Device Independent Functions
+//***********************************************************************************
+
+//Reserve Space for the backbuffer
+
+RenderContext BackBuffer;
+uint8_t BackBufferRenderPlaneSpace[PHYSICAL_DISPLAY_PLANE_BUFFER_SIZE];
+
+int16_t GFX_Drawcharacter(RenderContext *Image, uint8_t character, int16_t StartX, int16_t StartY, GFXFont *MyFont);
+int16_t GFX_GetStringWidth(char * String,GFXFont * MyFont);
+
+//FontData
+
+#define FONT5x7_FONT_WIDTH 5
+#define FONT5x7_FONT_HEIGHT 8
+#define FONT5x7_FONT_ELEMENTS 128
+#define FONT5x7_FONT_COLUMN_SIZE_IN_BYTE 1
+
+uint8_t FontTable_Font5x7 [640] = {
+0x00 ,0x08 ,0x0C ,0xFA ,0x81 ,0xFA ,0x0C ,0x08 ,0x00 ,0x00 ,0x00 ,0x10 ,0x30 ,0x5F ,0x81 ,0x5F ,
+0x30 ,0x10 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xBE ,0x00 ,0x00 ,0x00 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x00 ,0x28 ,
+0xFE ,0x28 ,0xFE ,0x28 ,0x48 ,0xFE ,0x54 ,0xFE ,0x24 ,0x06 ,0xE6 ,0x10 ,0xCE ,0xC0 ,0x60 ,0x92 ,
+0x94 ,0x78 ,0x10 ,0x06 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7C ,0x82 ,0x00 ,0x00 ,0x00 ,0x82 ,0x7C ,0x00 ,
+0x00 ,0x00 ,0x54 ,0x38 ,0xFE ,0x38 ,0x54 ,0x10 ,0x10 ,0x7C ,0x10 ,0x10 ,0x80 ,0x60 ,0x00 ,0x00 ,
+0x00 ,0x10 ,0x10 ,0x10 ,0x10 ,0x10 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0xC0 ,0x30 ,0x0C ,0x02 ,0x00 ,
+0x7C ,0xA2 ,0x92 ,0x8A ,0x7C ,0x88 ,0x84 ,0xFE ,0x80 ,0x80 ,0x84 ,0xC2 ,0xA2 ,0x92 ,0x8C ,0x44 ,
+0x92 ,0x92 ,0x92 ,0x6C ,0x10 ,0x18 ,0x14 ,0xFE ,0x10 ,0x4E ,0x8A ,0x8A ,0x8A ,0x72 ,0x7C ,0x92 ,
+0x92 ,0x92 ,0x64 ,0x02 ,0xC2 ,0x22 ,0x12 ,0x0E ,0x6C ,0x92 ,0x92 ,0x92 ,0x6C ,0x0C ,0x92 ,0x92 ,
+0x92 ,0x7C ,0x48 ,0x00 ,0x00 ,0x00 ,0x00 ,0x80 ,0x68 ,0x00 ,0x00 ,0x00 ,0x10 ,0x28 ,0x44 ,0x82 ,
+0x00 ,0x28 ,0x28 ,0x28 ,0x28 ,0x00 ,0x82 ,0x44 ,0x28 ,0x10 ,0x00 ,0x04 ,0x02 ,0xA2 ,0x12 ,0x0C ,
+0x3C ,0x42 ,0x9A ,0xA2 ,0x1C ,0xF8 ,0x14 ,0x12 ,0x14 ,0xF8 ,0xFE ,0x92 ,0x92 ,0x92 ,0x6C ,0x7C ,
+0x82 ,0x82 ,0x82 ,0x44 ,0xFE ,0x82 ,0x82 ,0x44 ,0x38 ,0xFE ,0x92 ,0x92 ,0x82 ,0x82 ,0xFE ,0x12 ,
+0x12 ,0x02 ,0x02 ,0x7C ,0x92 ,0x92 ,0x92 ,0x74 ,0xFE ,0x10 ,0x10 ,0x10 ,0xFE ,0x82 ,0x82 ,0xFE ,
+0x82 ,0x82 ,0x40 ,0x80 ,0x80 ,0x80 ,0x7E ,0xFE ,0x10 ,0x28 ,0x44 ,0x82 ,0xFE ,0x80 ,0x80 ,0x80 ,
+0x00 ,0xFE ,0x04 ,0x08 ,0x04 ,0xFE ,0xFE ,0x04 ,0x18 ,0x20 ,0xFE ,0x7C ,0x82 ,0x82 ,0x82 ,0x7C ,
+0xFE ,0x12 ,0x12 ,0x12 ,0x0C ,0x7C ,0x82 ,0xA2 ,0xC2 ,0xFC ,0xFE ,0x12 ,0x32 ,0x52 ,0x8C ,0x4C ,
+0x92 ,0x92 ,0x92 ,0x64 ,0x02 ,0x02 ,0xFE ,0x02 ,0x02 ,0x7E ,0x80 ,0x80 ,0x80 ,0x7E ,0x3E ,0x40 ,
+0x80 ,0x40 ,0x3E ,0xFE ,0x40 ,0x20 ,0x40 ,0xFE ,0xC6 ,0x28 ,0x10 ,0x28 ,0xC6 ,0x02 ,0x04 ,0xF8 ,
+0x04 ,0x02 ,0xC2 ,0xA2 ,0x92 ,0x8A ,0x86 ,0xFE ,0x82 ,0x82 ,0x00 ,0x00 ,0x02 ,0x0C ,0x30 ,0xC0 ,
+0x00 ,0x82 ,0x82 ,0xFE ,0x00 ,0x00 ,0x04 ,0x02 ,0x04 ,0x00 ,0x00 ,0x80 ,0x80 ,0x80 ,0x80 ,0x80 ,
+0x06 ,0x08 ,0x00 ,0x00 ,0x00 ,0x70 ,0x88 ,0x88 ,0x70 ,0x80 ,0xFC ,0x90 ,0x90 ,0x60 ,0x00 ,0x70 ,
+0x88 ,0x88 ,0x88 ,0x00 ,0x60 ,0x90 ,0x90 ,0x7C ,0x80 ,0x70 ,0xA8 ,0xA8 ,0x90 ,0x00 ,0x10 ,0xF8 ,
+0x14 ,0x04 ,0x00 ,0x98 ,0xA4 ,0xA4 ,0x78 ,0x00 ,0xFC ,0x20 ,0x10 ,0xE0 ,0x00 ,0xE8 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x40 ,0x80 ,0x80 ,0x74 ,0x00 ,0xFC ,0x20 ,0x50 ,0x88 ,0x00 ,0xFC ,0x00 ,0x00 ,0x00 ,
+0x00 ,0xF0 ,0x08 ,0x30 ,0x08 ,0xF0 ,0xF8 ,0x08 ,0x08 ,0xF0 ,0x00 ,0x70 ,0x88 ,0x88 ,0x70 ,0x00 ,
+0xF8 ,0x24 ,0x24 ,0x18 ,0x00 ,0x18 ,0x24 ,0x24 ,0xF8 ,0x00 ,0xF0 ,0x08 ,0x08 ,0x10 ,0x00 ,0x90 ,
+0xA8 ,0xA8 ,0x48 ,0x00 ,0x08 ,0x7C ,0x88 ,0x00 ,0x00 ,0x78 ,0x80 ,0x80 ,0x78 ,0x00 ,0x38 ,0x40 ,
+0x80 ,0x40 ,0x38 ,0x78 ,0x80 ,0x40 ,0x80 ,0x78 ,0x88 ,0x50 ,0x20 ,0x50 ,0x88 ,0x08 ,0x10 ,0xE0 ,
+0x10 ,0x08 ,0xC8 ,0xA8 ,0x98 ,0x00 ,0x00 ,0x10 ,0x6C ,0x82 ,0x00 ,0x00 ,0xFE ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x82 ,0x6C ,0x10 ,0x00 ,0x00 ,0x08 ,0x04 ,0x08 ,0x10 ,0x08 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 };
+
+uint8_t CharacterWidthTable_Font5x7 [128] = {
+0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,
+0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,
+0x05 ,0x01 ,0x03 ,0x05 ,0x05 ,0x05 ,0x05 ,0x01 ,0x02 ,0x02 ,0x05 ,0x05 ,0x02 ,0x05 ,0x01 ,0x04 ,
+0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x01 ,0x01 ,0x04 ,0x04 ,0x04 ,0x05 ,
+0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x04 ,0x05 ,0x05 ,0x05 ,
+0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x05 ,0x03 ,0x04 ,0x05 ,0x03 ,0x05 ,
+0x02 ,0x05 ,0x04 ,0x04 ,0x05 ,0x04 ,0x04 ,0x04 ,0x04 ,0x01 ,0x04 ,0x04 ,0x01 ,0x05 ,0x04 ,0x05 ,
+0x05 ,0x05 ,0x04 ,0x04 ,0x03 ,0x04 ,0x05 ,0x05 ,0x05 ,0x05 ,0x03 ,0x03 ,0x01 ,0x05 ,0x05 ,0x05 };
+
+#define FONT3x5_FONT_WIDTH 3
+#define FONT3x5_FONT_HEIGHT 5
+#define FONT3x5_ELEMENTS 128
+#define FONT3x5_FONT_COLUMN_SIZE_IN_BYTE 1
+
+
+uint8_t FontTable_Font3x5 [384] = {
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x17 ,0x00 ,0x00 ,0x03 ,0x00 ,0x03 ,0x0E ,0x1F ,0x0E ,0x14 ,0x1F ,0x0A ,0x00 ,
+0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x0E ,0x11 ,0x00 ,0x11 ,0x0E ,0x00 ,0x15 ,0x0E ,
+0x15 ,0x04 ,0x0E ,0x04 ,0x10 ,0x08 ,0x00 ,0x04 ,0x04 ,0x04 ,0x10 ,0x00 ,0x00 ,0x18 ,0x04 ,0x03 ,
+0x0E ,0x11 ,0x0E ,0x12 ,0x1F ,0x10 ,0x19 ,0x15 ,0x16 ,0x11 ,0x15 ,0x0A ,0x07 ,0x04 ,0x1F ,0x17 ,
+0x15 ,0x09 ,0x1E ,0x15 ,0x18 ,0x01 ,0x1D ,0x03 ,0x1B ,0x15 ,0x1B ,0x06 ,0x15 ,0x0E ,0x0A ,0x00 ,
+0x00 ,0x10 ,0x0A ,0x00 ,0x04 ,0x0A ,0x11 ,0x00 ,0x00 ,0x00 ,0x11 ,0x0A ,0x04 ,0x01 ,0x15 ,0x02 ,
+0x09 ,0x15 ,0x0E ,0x1E ,0x05 ,0x1E ,0x1F ,0x15 ,0x0A ,0x0E ,0x11 ,0x0A ,0x1F ,0x11 ,0x0E ,0x1F ,
+0x15 ,0x11 ,0x1F ,0x05 ,0x05 ,0x1E ,0x15 ,0x1D ,0x1F ,0x04 ,0x1F ,0x11 ,0x1F ,0x11 ,0x08 ,0x10 ,
+0x0F ,0x1F ,0x06 ,0x19 ,0x1F ,0x10 ,0x10 ,0x1F ,0x02 ,0x1F ,0x1F ,0x06 ,0x1F ,0x1F ,0x11 ,0x1F ,
+0x1F ,0x05 ,0x07 ,0x1F ,0x19 ,0x1F ,0x1F ,0x0D ,0x16 ,0x16 ,0x15 ,0x1D ,0x01 ,0x1F ,0x01 ,0x1F ,
+0x10 ,0x1F ,0x0F ,0x10 ,0x0F ,0x1F ,0x08 ,0x1F ,0x1B ,0x04 ,0x1B ,0x01 ,0x1E ,0x01 ,0x19 ,0x15 ,
+0x13 ,0x1F ,0x11 ,0x00 ,0x03 ,0x0C ,0x10 ,0x11 ,0x1F ,0x00 ,0x02 ,0x01 ,0x02 ,0x10 ,0x10 ,0x10 ,
+0x01 ,0x02 ,0x00 ,0x08 ,0x14 ,0x1C ,0x1F ,0x14 ,0x08 ,0x0C ,0x12 ,0x12 ,0x08 ,0x14 ,0x1F ,0x0C ,
+0x16 ,0x16 ,0x14 ,0x0E ,0x05 ,0x06 ,0x15 ,0x0F ,0x1F ,0x04 ,0x18 ,0x1D ,0x00 ,0x00 ,0x10 ,0x0D ,
+0x00 ,0x1F ,0x0C ,0x12 ,0x1F ,0x00 ,0x00 ,0x1C ,0x08 ,0x1C ,0x1C ,0x02 ,0x1C ,0x0C ,0x12 ,0x0C ,
+0x1E ,0x05 ,0x02 ,0x02 ,0x05 ,0x1E ,0x1C ,0x02 ,0x04 ,0x14 ,0x1A ,0x00 ,0x04 ,0x1E ,0x04 ,0x1E ,
+0x10 ,0x1E ,0x0E ,0x10 ,0x0E ,0x1C ,0x08 ,0x1C ,0x12 ,0x0C ,0x12 ,0x12 ,0x0C ,0x02 ,0x12 ,0x1A ,
+0x16 ,0x04 ,0x0E ,0x11 ,0x1F ,0x00 ,0x00 ,0x11 ,0x0E ,0x04 ,0x02 ,0x02 ,0x04 ,0x00 ,0x00 ,0x00 };
+
+
+uint8_t CharacterWidthTable_Font3x5 [128] = {
+0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,
+0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,
+0x03 ,0x01 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x01 ,0x02 ,0x03 ,0x03 ,0x03 ,0x02 ,0x03 ,0x01 ,0x03 ,
+0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x01 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,
+0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,
+0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x02 ,0x03 ,0x02 ,0x03 ,0x03 ,
+0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x01 ,0x03 ,0x03 ,0x01 ,0x03 ,0x03 ,0x03 ,
+0x03 ,0x03 ,0x03 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x01 ,0x03 ,0x03 ,0x03 };
+
+GFXFont Font5x7;
+GFXFont Font3x5;
+
+void GFX_Init()
+{
+
+ //Staticially Allocate and setup the backbuffer space;
+
+ BackBuffer.RenderPlane.BitPlaneSpace = &BackBufferRenderPlaneSpace[0];
+
+ BackBuffer.SizeX = BACK_BUFFER_SIZE_X;
+ BackBuffer.SizeY = BACK_BUFFER_SIZE_Y;
+
+ BackBuffer.RenderPlane.SizeX = BACK_BUFFER_SIZE_X;
+ BackBuffer.RenderPlane.SizeY = BACK_BUFFER_SIZE_Y;
+
+
+ GFX_FullDisplayBufferClear(&BackBuffer);
+
+ //Initialize the stock fonts
+
+ Font5x7.CharacterWidthTable = (uint8_t *)CharacterWidthTable_Font5x7;
+ Font5x7.FontBuffer = (uint8_t *)FontTable_Font5x7;
+ Font5x7.FontHeight = FONT5x7_FONT_HEIGHT;
+ Font5x7.FontWidth = FONT5x7_FONT_WIDTH;
+ Font5x7.BytesPerColumn = FONT5x7_FONT_COLUMN_SIZE_IN_BYTE;
+
+ Font3x5.CharacterWidthTable = (uint8_t *)CharacterWidthTable_Font3x5;
+ Font3x5.FontBuffer = (uint8_t *)FontTable_Font3x5;
+ Font3x5.FontHeight = FONT3x5_FONT_HEIGHT;
+ Font3x5.FontWidth = FONT3x5_FONT_WIDTH;
+ Font3x5.BytesPerColumn = FONT3x5_FONT_COLUMN_SIZE_IN_BYTE;
+
+ GFX_InitPhysicalScreen();
+
+}
+
+
+
+void GFX_FullDisplayBufferClear(RenderContext *Image)
+{
+ BitPlane_Clear(&Image->RenderPlane);
+}
+
+
+void GFX_PutPixel(RenderContext *Image, int16_t x, int16_t y)
+{
+ if((x<Image->SizeX) && (y<Image->SizeY) && (x>=0) && (y>=0))
+ {
+ BitPlane_Put(&Image->RenderPlane,Image->SizeX-x-1,Image->SizeY-y-1,TRUE);
+ }
+}
+
+
+
+#ifndef _INLINE_GFX_GET_PIXEL
+uint8_t GFX_GetPixel(RenderContext *Image, int16_t x, int16_t y)
+{
+ uint8_t PixelColor = 0;
+
+ if((x<Image->SizeX) && (y<Image->SizeY) && (x>=0) && (y>=0))
+ {
+
+ PixelColor = BitPlane_Get(&Image->RenderPlane,x,y);
+ }
+
+ return PixelColor;
+}
+#endif
+
+
+void GFX_DrawHline(RenderContext *Image, int16_t XStart, int16_t XStop, int16_t Y)
+{
+ int16_t LineStart;
+ int16_t LineStop;
+ uint16_t i;
+
+ if((Y<Image->SizeY) && (Y>=0))
+ {
+ if(XStart>XStop)
+ {
+ LineStart = XStop;
+ LineStop = XStart;
+ }
+ else
+ {
+ LineStart = XStart;
+ LineStop = XStop;
+ }
+
+ if(LineStart<0)
+ {
+ LineStart = 0;
+ }
+
+ if(LineStop>Image->SizeX)
+ {
+ LineStop = Image->SizeX-1;
+ }
+
+ if(LineStart == LineStop)
+ {
+ GFX_PutPixel(Image,LineStart,Y);
+ }
+ else
+ {
+ for(i=LineStart; i<=LineStop ; i++)
+ {
+ GFX_PutPixel(Image,i,Y);
+ }
+ }
+ }
+
+}
+
+
+
+ void GFX_DrawVline(RenderContext *Image, int16_t YStart, int16_t YStop, int16_t X)
+{
+ int16_t LineStart;
+ int16_t LineStop;
+ int16_t i;
+
+ if((X<Image->SizeX) && (X>=0))
+ {
+
+ if(YStart>YStop)
+ {
+ LineStart = YStop;
+ LineStop = YStart;
+ }
+ else
+ {
+ LineStart = YStart;
+ LineStop = YStop;
+ }
+
+ if(LineStart<0)
+ {
+ LineStart = 0;
+ }
+
+
+ if(LineStop>Image->SizeY)
+ {
+ LineStop = Image->SizeY-1;
+ }
+
+ for(i=LineStart; i<=LineStop ; i++)
+ {
+ GFX_PutPixel(Image,X,i);
+ }
+ }
+}
+
+
+void GFX_DrawLine(RenderContext * Image, int16_t X1,int16_t Y1, int16_t X2,int16_t Y2)
+{
+ //A simple Implementation of Bresenham's line Algorithm
+ int16_t StartX,StopX,StartY,StopY;
+ int16_t dX,dY;
+ int16_t Y_Numerator;
+ int16_t X_Numerator;
+ int16_t Y;
+ int16_t X;
+ int16_t i;
+ uint8_t YDir = 0;
+ //First Make sure that it is left to right
+ //If not them flop them
+ if(X2>X1)
+ {
+ StartX = X1;
+ StopX = X2;
+ StartY = Y1;
+ StopY = Y2;
+ }
+ else
+ {
+ StartX = X2;
+ StopX = X1;
+ StartY = Y2;
+ StopY = Y1;
+ }
+ GFX_PutPixel(Image, StopX,StopY);
+ if(StopY>=StartY)
+ {
+ dY = StopY - StartY;
+ YDir = 0;
+ }
+ else
+ {
+ dY = StartY - StopY;
+ YDir = 1;
+ }
+ dX = StopX - StartX;
+ //Now, if the slope is less greater than one, we need to swap all X/Y operations
+ if(dY<=dX)
+ {
+ //Slope is less than one, proceed at normal and step along the x axis
+ Y=StartY; //start the whole part of the Y value at the starting pixeel.
+ X=StartX;
+ //We need to start the numerator of the fraction half way through the fraction so evertyhing rounds at
+ //fraction midpoint
+ Y_Numerator = dX>>1; //The fraction demonimator is assumeed to be dX
+ // out fixed point Y value is Y + (Y_Numerator / dX)
+ //Every time we step the X coordinate by one, we need to step
+ //out Y coordinate by dY/dX. We do this by just adding dY to our
+ //numerator. When the numerator gets bigger than the
+ //denomiator, the increment the whole part by one and decrement the numerator
+ //by the denominator
+ for(i=0;i<dX;i++)
+ {
+ GFX_PutPixel(Image,X,Y);
+ X++;
+ //Now do all the fractional stuff
+ Y_Numerator += dY;
+ if(Y_Numerator >= dX)
+ {
+ Y_Numerator-=dX;
+ if(StopY > StartY)
+ {
+ Y++;
+ }
+ else
+ {
+ Y--;
+ }
+ }
+ }
+ }
+ else
+ {
+ //Same as before by step along the y axis.
+ Y=StartY;
+ X=StartX;
+ X_Numerator = dY>>1;
+ for(i=0;i<dY;i++)
+ {
+ GFX_PutPixel(Image,X,Y);
+ //Now do all the fractional stuff
+ if(YDir)
+ {
+ Y--;
+ }
+ else
+ {
+ Y++;
+ }
+ X_Numerator += dX;
+ if(X_Numerator >= dY)
+ {
+ X_Numerator-=dY;
+ if(StopX > StartX)
+ {
+ X++;
+ }
+ else
+ {
+ X--;
+ }
+ }
+ }
+ }
+}
+
+void GFX_DrawBox(RenderContext *Image, GFXDisplayBox *Box)
+{
+ GFX_DrawHline(Image,Box->P1.X,Box->P2.X,Box->P1.Y);
+ GFX_DrawHline(Image,Box->P1.X,Box->P2.X,Box->P2.Y);
+ GFX_DrawVline(Image,Box->P1.Y,Box->P2.Y,Box->P1.X);
+ GFX_DrawVline(Image,Box->P1.Y,Box->P2.Y,Box->P2.X);
+}
+
+int16_t GFX_DrawCharacter(RenderContext * Image,uint8_t Character,int16_t StartX, int16_t StartY, GFXFont * MyFont)
+{
+ uint8_t i,j,Mask;
+ uint16_t CharStartIndex,ColumnStartIndex,ByteOffset;
+
+ CharStartIndex = (Character * (MyFont->BytesPerColumn) * (MyFont->FontWidth));
+
+ for(j=0;j<MyFont->CharacterWidthTable[Character];j++)
+ {
+ //Draw the current slice
+ ColumnStartIndex = j* (MyFont->BytesPerColumn);
+
+ for(i=0;i<MyFont->FontHeight;i++)
+ {
+ ByteOffset = i>>3;
+ Mask = 0x01 << (i&0x07);
+
+ if( (MyFont->FontBuffer[CharStartIndex + ColumnStartIndex + ByteOffset]) & Mask)
+ {
+ GFX_PutPixel(Image, StartX, StartY + i);
+ }
+ }
+ StartX++;
+ }
+ return StartX;
+}
+
+
+int16_t GFX_GetStringWidth(char * String,GFXFont * MyFont)
+{
+ uint8_t Ptr = 0;
+ uint8_t NextChar;
+ int16_t StringSize = 0;
+
+ NextChar = String[Ptr];
+ Ptr++;
+
+ while((NextChar!=0) && (Ptr <GFX_MAX_STRING_LEN))
+ {
+ StringSize += MyFont->CharacterWidthTable[NextChar] + 1;
+ NextChar = String[Ptr];
+ Ptr++;
+ }
+
+ return StringSize;
+}
+
+void GFX_DrawCenteredString(RenderContext * Image,char * String,int16_t StartX, int16_t StartY, GFXFont * MyFont)
+{
+ StartX -= (GFX_GetStringWidth(String,MyFont)>>1);
+ GFX_DrawString(Image,String,StartX,StartY,MyFont);
+}
+
+void GFX_DrawString(RenderContext * Image,char * String,int16_t StartX, int16_t StartY, GFXFont * MyFont)
+{
+
+uint8_t Ptr = 0;
+uint8_t NextChar;
+
+NextChar = String[Ptr];
+
+ while((NextChar!=0) && (Ptr <GFX_MAX_STRING_LEN))
+ {
+ StartX = GFX_DrawCharacter(Image,NextChar,StartX,StartY,MyFont);
+ Ptr++;
+ NextChar = String[Ptr];
+ StartX++;
+ }
+
+}
+
+char GFXStringBuf[64];
+
+void GFX_printf(RenderContext * Image,int16_t StartX, int16_t StartY, GFXFont * MyFont, const char *FormatString,...)
+{
+ va_list argptr;
+ va_start(argptr,FormatString);
+ vsprintf((char *)GFXStringBuf,FormatString,argptr);
+ va_end(argptr);
+
+ GFX_DrawString(Image,GFXStringBuf,StartX,StartY,MyFont);
+}
+
+#ifndef INLINE_BITPLANE_PUT
+void BitPlane_Put(BitPlane * BP, uint16_t X,uint16_t Y, uint8_t Value)
+{
+ uint16_t Offset;
+ uint8_t Mask;
+
+ Offset = (Y * ((BP->SizeX)>>3)) + (X>>3);
+ Mask = 0x01 << (X & 0x07);
+
+ if(Value)
+ {
+ BP->BitPlaneSpace[Offset] |= Mask;
+ }
+ else
+ {
+ BP->BitPlaneSpace[Offset] &= ~Mask;
+ }
+}
+#endif
+
+#ifndef INLINE_BITPLANE_GET
+uint8_t BitPlane_Get(BitPlane * BP, uint16_t X,uint16_t Y)
+{
+ uint16_t Offset;
+ uint8_t Mask;
+
+ Offset = (Y * ((BP->SizeX)>>3)) + (X>>3);
+ Mask = 0x01 << (X & 0x07);
+
+ if((BP->BitPlaneSpace[Offset])&Mask)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+#endif
+
+void BitPlane_Clear(BitPlane * BP)
+{
+ uint16_t PlaneSpaceSize;
+ uint16_t i;
+
+ PlaneSpaceSize = ((BP->SizeX)>>3) * BP->SizeY;
+
+ for (i=0;i<PlaneSpaceSize;i++) {
+ BP->BitPlaneSpace[i] = 0;
+ }
+}
