Example project for the Rioux Chem control box
Rioux Chem Control Box
This is the example project for the Rioux Chem Control Box. I have posted some youtube videos to guide you through the hardware and software:
Rioux Chem Control Box - Hardware
http://www.youtube.com/watch?v=MoZ92GRYa4s
Rioux Chem Control Box - Software - Part I
http://www.youtube.com/watch?v=_MwaTLL4dyA==
Rioux Chem Control Box - Software - Part II
http://www.youtube.com/watch?v=j_P89izfgoQ
DRIVERS/CHEM_BOX_COMMON.cpp
- Committer:
- wavenumber
- Date:
- 2020-08-31
- Revision:
- 2:73a028278c5c
- Parent:
- 1:d64ac853223c
- Child:
- 3:cb48919cd5e8
File content as of revision 2:73a028278c5c:
#include "mbed.h" #include "CHEM_BOX_INTERFACE.h" #include "MODSERIAL.h" #include <stdio.h> #include <stdarg.h> //Mbed Objects DigitalOut MBED_LED1(LED1); 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 TerminalEcho = 1; 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 before you call this so internal variables are updated uint16_t ReadThermocouple_OC() { return Thermocouple_OC; } //Make sure to call ReadThermocouple before you call this so internal variables are updated uint16_t ReadThermocouple_SCG() { return Thermocouple_SCG; } //Make sure to call ReadThermocouple before you call this so internal variables are updated uint16_t ReadThermocouple_SCV() { return Thermocouple_SCV; } //Make sure to call ReadThermocouple before you 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) / 82; } 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); void TerminalCmd_ECHO_OFF(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"}, {"ECHO_OFF",TerminalCmd_ECHO_OFF,"Disables echoing of characters"} }; extern "C" void mbed_reset(); void TerminalCmd_Reset(char *arg) { mbed_reset(); } void TerminalCmd_Stub(char *arg) { PC.printf("stub \r\n"); } void TerminalCmd_ECHO_OFF(char *arg) { TerminalEcho = 0; } 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:%.5f\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 MBED_LED1 = 1; } void TerminalCmd_FanOff(char *arg) { SetFanSpeed(0); //PWMing the FANs doesn't work with the ME40100V1 models! WE will just on or off MBED_LED1 = 0; } 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; if(TerminalEcho) { 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--; if(TerminalEcho) { 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; if(TerminalEcho) { 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; } }