From 1cbcba924f62eb7f69296d61f4f739dae0a8dfd3 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Thu, 27 Jul 2017 11:46:04 +1000 Subject: Adding auto-rotation to the screen Adds auto rotation support using the proper orientation detection. (Not using raw values). Should Fix and close #29 --- workspace/ts100/inc/I2C.h | 3 +- workspace/ts100/inc/MMA8652FC.h | 9 +- workspace/ts100/inc/Modes.h | 3 +- workspace/ts100/inc/Oled.h | 3 +- workspace/ts100/inc/Settings.h | 6 +- workspace/ts100/src/I2C.c | 266 +++++++++++++++++++++++++++++++--------- workspace/ts100/src/MMA8652FC.c | 19 ++- workspace/ts100/src/Main.c | 10 +- workspace/ts100/src/Modes.c | 60 +++++---- workspace/ts100/src/Oled.c | 31 +++-- workspace/ts100/src/Settings.c | 2 +- 11 files changed, 296 insertions(+), 116 deletions(-) (limited to 'workspace') diff --git a/workspace/ts100/inc/I2C.h b/workspace/ts100/inc/I2C.h index b20378b2..ab0293dc 100644 --- a/workspace/ts100/inc/I2C.h +++ b/workspace/ts100/inc/I2C.h @@ -11,6 +11,7 @@ void I2C_Configuration(void); void I2C_PageWrite(u8* pbuf, u8 numbyte, u8 deviceaddr); -void I2C_PageRead(u8* pbuf, u8 numbyte, u8 deviceaddr, u8 readaddr); +int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer, + uint16_t numByteToRead); #endif /******************************** END OF FILE *********************************/ diff --git a/workspace/ts100/inc/MMA8652FC.h b/workspace/ts100/inc/MMA8652FC.h index d7107e5b..380ea29c 100644 --- a/workspace/ts100/inc/MMA8652FC.h +++ b/workspace/ts100/inc/MMA8652FC.h @@ -14,9 +14,8 @@ #ifndef __MMA8652FC__H #define __MMA8652FC__H - -void StartUp_Accelerometer(uint8_t sensitivity);//This is the only function we expose - +void StartUp_Accelerometer(uint8_t sensitivity); //This is the only function we expose +uint8_t getOrientation(); //--------------MMA8652 Device ID----------------------------------------------// #define DEVICE_ADDR 0X1D @@ -99,8 +98,6 @@ void StartUp_Accelerometer(uint8_t sensitivity);//This is the only function we e #define INT_SOURCE 0X0C #define DEVICE_ID 0X0D - - //-----STATUS_REG(0X00)-----Bit Define----------------------------------------// #define ZYXDR_BIT 0X08 //----XYZ_DATA_CFG_REG(0xE)-Bit Define----------------------------------------// @@ -123,7 +120,7 @@ void StartUp_Accelerometer(uint8_t sensitivity);//This is the only function we e //---------CTRL_REG2(0X2B)Bit Define------------------------------------------// #define MODS_MASK 0x03 //Oversampling Mode 4 #define Normal_Mode 0x0 //Normal=0,Low Noise Low Power MODS=1, - //HI RESOLUTION=2,LOW POWER MODS = 11 +//HI RESOLUTION=2,LOW POWER MODS = 11 //----CTRL_REG4---Interrupt Enable BIT ---------------------------------------// //0 interrupt is disabled (default) //1 interrupt is enabled diff --git a/workspace/ts100/inc/Modes.h b/workspace/ts100/inc/Modes.h index 432b0ab2..d81209cc 100644 --- a/workspace/ts100/inc/Modes.h +++ b/workspace/ts100/inc/Modes.h @@ -16,6 +16,7 @@ #include "PID.h" #include "Settings.h" #include "Analog.h" +#include "MMA8652FC.h" #include typedef enum { STARTUP, //we are sitting on the prompt to push a button @@ -41,7 +42,7 @@ typedef enum { TEMPDISPLAY, TEMPROUNDING, DISPUPDATERATE, - LEFTY, + SCREENROTATION, BOOSTMODE, BOOSTTEMP, POWERDISPLAY, diff --git a/workspace/ts100/inc/Oled.h b/workspace/ts100/inc/Oled.h index f477ef35..2241f722 100644 --- a/workspace/ts100/inc/Oled.h +++ b/workspace/ts100/inc/Oled.h @@ -32,5 +32,6 @@ void OLED_DrawThreeNumber(uint16_t in, uint8_t x); void OLED_DrawIDLELogo(); void OLED_DrawSymbol(uint8_t x, uint8_t symbol); const u8* Oled_DrawArea(u8 x0, u8 y0, u8 wide, u8 high, const u8* ptr); +void OLED_SetOrientation(uint8_t ori); +uint8_t OLED_GetOrientation(); #endif -/******************************** END OF FILE *********************************/ diff --git a/workspace/ts100/inc/Settings.h b/workspace/ts100/inc/Settings.h index a3b6fea7..16dc47b6 100644 --- a/workspace/ts100/inc/Settings.h +++ b/workspace/ts100/inc/Settings.h @@ -12,7 +12,7 @@ #include #include "stm32f10x_flash.h" #include "Oled.h" -#define SETTINGSVERSION 13 /*Change this if you change the struct below to prevent people getting out of sync*/ +#define SETTINGSVERSION 14 /*Change this if you change the struct below to prevent people getting out of sync*/ //Display Speeds #define DISPLAYMODE_FAST (0x00) #define DISPLAYMODE_MEDIUM (0x01) @@ -30,10 +30,10 @@ typedef struct { uint32_t SleepTemp; //temp to drop to in sleep uint8_t version; //Used to track if a reset is needed on firmware upgrade uint8_t SleepTime; //minutes timeout to sleep - uint8_t cutoutSetting:4; //(3 bits) The voltage we cut out at for under voltage + uint8_t cutoutSetting:3; //(3 bits) The voltage we cut out at for under voltage uint8_t powerDisplay:1; //Toggle to swap the arrows with a power readout instead uint8_t displayTempInF:1; //If we need to convert the C reading to F - uint8_t flipDisplay:1; //If true we want to invert the display for lefties + uint8_t OrientationMode:2; //If true we want to invert the display for lefties uint8_t sensitivity:6; //Sensitivity of accelerometer (5 bits) uint8_t ShutdownTime:6; //Time until unit shuts down if left alone uint8_t displayUpdateSpeed:2; //How fast the display updates / temp showing mode diff --git a/workspace/ts100/src/I2C.c b/workspace/ts100/src/I2C.c index e03a7129..5703f961 100644 --- a/workspace/ts100/src/I2C.c +++ b/workspace/ts100/src/I2C.c @@ -4,6 +4,19 @@ */ #include "I2C.h" +/* I2C STOP mask */ +#define CR1_STOP_Set ((uint16_t)0x0200) +#define CR1_STOP_Reset ((uint16_t)0xFDFF) + +/* I2C ACK mask */ +#define CR1_ACK_Set ((uint16_t)0x0400) +#define CR1_ACK_Reset ((uint16_t)0xFBFF) + +/* I2C POS mask */ +#define CR1_POS_Set ((uint16_t)0x0800) +#define CR1_POS_Reset ((uint16_t)0xF7FF) + +#define NULL ((void *)0) /* * Configure the I2C port hardware */ @@ -60,89 +73,222 @@ void I2C_PageWrite(u8* buf, u8 nbyte, u8 deviceaddr) { } } +//Based on code from http://iamjustinwang.blogspot.com.au/2016/03/stm32f103-i2c-master-driver.html +int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer, + uint16_t numByteToRead) { -/* - * Read Page of data using I2C1 peripheral - */ + __IO uint32_t temp = 0; + volatile int I2C_TimeOut = 0; -void I2C_PageRead(u8* buf, u8 nbyte, u8 deviceaddr, u8 readaddr) { - I2C_GenerateSTART(I2C1, ENABLE); - while (I2C_GetFlagStatus(I2C1, I2C_FLAG_SB) == RESET) - ; - I2C_Send7bitAddress(I2C1, deviceaddr << 1, I2C_Direction_Transmitter); - while (I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET) - ; - I2C_GetFlagStatus(I2C1, I2C_FLAG_MSL); - while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == RESET) - ; - // Send an 8bit byte address - I2C_SendData(I2C1, readaddr); + // /* While the bus is busy * / + I2C_TimeOut = 3000; while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) { + if (I2C_TimeOut-- <= 0) { + return 1; + } } - I2C_AcknowledgeConfig(I2C1, DISABLE); - I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Current); + + // * Send START condition * / I2C_GenerateSTART(I2C1, ENABLE); + + // / * Test on EV5 and clear it * / + I2C_TimeOut = 3000; while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { + if (I2C_TimeOut-- <= 0) { + return 1; + } + } + + // / * Send address for write * / + I2C_Send7bitAddress(I2C1, deviceAddr, I2C_Direction_Transmitter); + + // / * Test on EV6 and clear it * / + I2C_TimeOut = 3000; + while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { + if (I2C_TimeOut-- <= 0) { + return 1; + } } - I2C_Send7bitAddress(I2C1, deviceaddr << 1, I2C_Direction_Receiver); - while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR)) { + + // / * Send the internal address to read from: Only one byte address * / + I2C_SendData(I2C1, readAddr); + + /// * Test on EV8 and clear it * / + I2C_TimeOut = 3000; + while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { + if (I2C_TimeOut-- <= 0) { + return 1; + } } - if (nbyte == 1) { - // Clear Ack bit - I2C_AcknowledgeConfig(I2C1, DISABLE); - // EV6_1 -- must be atomic -- Clear ADDR, generate STOP + + /// * Send STRAT condition a second time * / + I2C_GenerateSTART(I2C1, ENABLE); + + /// * Test on EV5 and clear it * / + I2C_TimeOut = 3000; + while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { + if (I2C_TimeOut-- <= 0) { + return 1; + } + } + + // * Send address for read * / + I2C_Send7bitAddress(I2C1, deviceAddr, I2C_Direction_Receiver); + + if (numByteToRead == 1) { + /* Wait until ADDR is set */ + I2C_TimeOut = 3000; + while ((I2C1->SR1 & 0x0002) != 0x0002) { + if (I2C_TimeOut-- <= 0) { + return 1; + } + } + /* Clear ACK bit */ + I2C1->CR1 &= CR1_ACK_Reset; + /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3 + software sequence must complete before the current byte end of transfer */ __disable_irq(); - (void) I2C1->SR2; + /* Clear ADDR flag */ + temp = I2C1->SR2; + /* Program the STOP */ I2C_GenerateSTOP(I2C1, ENABLE); + /* Re-enable IRQs */ __enable_irq(); - // Receive data EV7 - while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE)) { + /* Wait until a data is received in DR register (RXNE = 1) EV7 */ + I2C_TimeOut = 3000; + while ((I2C1->SR1 & 0x00040) != 0x000040) { + if (I2C_TimeOut-- <= 0) { + return 1; + } } - *buf++ = I2C_ReceiveData(I2C1); - } else if (nbyte == 2) { - // Set POS flag - I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Next); - // EV6_1 -- must be atomic and in this order + /* Read the data */ + *pBuffer = I2C1->DR; + + } else if (numByteToRead == 2) { + + /* Set POS bit */ + I2C1->CR1 |= CR1_POS_Set; + /* Wait until ADDR is set: EV6 */ + I2C_TimeOut = 3000; + while ((I2C1->SR1 & 0x0002) != 0x0002) { + if (I2C_TimeOut-- <= 0) { + return 1; + } + } + /* EV6_1: The acknowledge disable should be done just after EV6, + that is after ADDR is cleared, so disable all active IRQs around ADDR clearing and + ACK clearing */ __disable_irq(); - (void) I2C1->SR2; // Clear ADDR flag - I2C_AcknowledgeConfig(I2C1, DISABLE); // Clear Ack bit + /* Clear ADDR by reading SR2 register */ + temp = I2C1->SR2; + /* Clear ACK */ + I2C1->CR1 &= CR1_ACK_Reset; + /*Re-enable IRQs */ __enable_irq(); - // EV7_3 -- Wait for BTF, program stop, read data twice - while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF)) { + /* Wait until BTF is set */ + I2C_TimeOut = 3000; + while ((I2C1->SR1 & 0x00004) != 0x000004) { + if (I2C_TimeOut-- <= 0) { + return 1; + } } + /* Disable IRQs around STOP programming and data reading */ __disable_irq(); + /* Program the STOP */ I2C_GenerateSTOP(I2C1, ENABLE); - *buf++ = I2C1->DR; + /* Read first data */ + *pBuffer = I2C1->DR; + /* Re-enable IRQs */ __enable_irq(); - *buf++ = I2C1->DR; - } else { - (void) I2C1->SR2; // Clear ADDR flag - while (nbyte-- != 3) { - // EV7 -- cannot guarantee 1 transfer completion time, wait for BTF - // instead of RXNE - while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF)) { + /**/ + pBuffer++; + /* Read second data */ + *pBuffer = I2C1->DR; + /* Clear POS bit */ + I2C1->CR1 &= CR1_POS_Reset; + } + + else { //numByteToRead > 2 + // * Test on EV6 and clear it * / + I2C_TimeOut = 3000; + while (!I2C_CheckEvent(I2C1, + I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { + if (I2C_TimeOut-- <= 0) { + return 1; } - *buf++ = I2C_ReceiveData(I2C1); } + // * While there is data to be read * / + while (numByteToRead) { + /* Receive bytes from first byte until byte N-3 */ + if (numByteToRead != 3) { + /* Poll on BTF to receive data because in polling mode we can not guarantee the + EV7 software sequence is managed before the current byte transfer completes */ + I2C_TimeOut = 3000; + while ((I2C1->SR1 & 0x00004) != 0x000004) { + if (I2C_TimeOut-- <= 0) { + return 1; + } + } + /* Read data */ + *pBuffer = I2C1->DR; + pBuffer++; + /* Decrement the read bytes counter */ + numByteToRead--; + } - while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF)) { - } - // EV7_2 -- Figure 1 has an error, doesn't read N-2 ! - I2C_AcknowledgeConfig(I2C1, DISABLE); // clear ack bit - __disable_irq(); - *buf++ = I2C_ReceiveData(I2C1); // receive byte N-2 - I2C_GenerateSTOP(I2C1, ENABLE); // program stop - __enable_irq(); - *buf++ = I2C_ReceiveData(I2C1); // receive byte N-1 - // wait for byte N - while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { + /* it remains to read three data: data N-2, data N-1, Data N */ + if (numByteToRead == 3) { + /* Wait until BTF is set: Data N-2 in DR and data N -1 in shift register */ + I2C_TimeOut = 3000; + while ((I2C1->SR1 & 0x00004) != 0x000004) { + if (I2C_TimeOut-- <= 0) { + return 1; + } + } + /* Clear ACK */ + I2C1->CR1 &= CR1_ACK_Reset; + + /* Disable IRQs around data reading and STOP programming */ + __disable_irq(); + /* Read Data N-2 */ + *pBuffer = I2C1->DR; + /* Increment */ + pBuffer++; + /* Program the STOP */ + I2C1->CR1 |= CR1_STOP_Set; + /* Read DataN-1 */ + *pBuffer = I2C1->DR; + /* Re-enable IRQs */ + __enable_irq(); + /* Increment */ + pBuffer++; + /* Wait until RXNE is set (DR contains the last data) */ + I2C_TimeOut = 3000; + while ((I2C1->SR1 & 0x00040) != 0x000040) { + if (I2C_TimeOut-- <= 0) { + return 1; + } + } + /* Read DataN */ + *pBuffer = I2C1->DR; + /* Reset the number of bytes to be read by master */ + numByteToRead = 0; + } } - *buf++ = I2C_ReceiveData(I2C1); - nbyte = 0; } - // Wait for stop - while (I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)) { + + /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */ + I2C_TimeOut = 3000; + while ((I2C1->CR1 & 0x200) == 0x200) { + if (I2C_TimeOut-- <= 0) { + return 1; + } } - return; + + // * Enable Acknowledgment to be ready for another reception * / + I2C_AcknowledgeConfig(I2C1, ENABLE); + + return 0; + } diff --git a/workspace/ts100/src/MMA8652FC.c b/workspace/ts100/src/MMA8652FC.c index 9e96bf0f..06552b94 100644 --- a/workspace/ts100/src/MMA8652FC.c +++ b/workspace/ts100/src/MMA8652FC.c @@ -23,12 +23,22 @@ void I2C_RegisterWrite(uint8_t reg, uint8_t data) { } uint8_t I2C_RegisterRead(uint8_t reg) { - u8 tx_data[3]; - tx_data[0] = reg; - I2C_PageRead(tx_data, 1, DEVICE_ADDR, reg); + u8 tx_data[1]; + I2C_Master_Read(DEVICE_ADDR << 1, reg, tx_data, 1); return tx_data[0]; } +uint8_t getOrientation() { +//First read the PL_STATUS register + uint8_t plStatus = I2C_RegisterRead(PL_STATUS_REG); + plStatus >>= 1; //We dont need the up/down bit + plStatus &= 0x03; //mask to the two lower bits + //0 == left handed + //1 == right handed + + return plStatus; +} + void StartUp_Accelerometer(uint8_t sensitivity) { I2C_RegisterWrite(CTRL_REG2, 0); //Normal mode I2C_RegisterWrite( CTRL_REG2, 0x40); // Reset all registers to POR values @@ -39,8 +49,9 @@ void StartUp_Accelerometer(uint8_t sensitivity) { I2C_RegisterWrite(FF_MT_THS_REG, 0x80 | sens); // Set threshold I2C_RegisterWrite(FF_MT_COUNT_REG, 0x02); // Set debounce to 100ms - + I2C_RegisterWrite(PL_CFG_REG, 0x40); //Enable the orientation detection I2C_RegisterWrite( CTRL_REG4, 0x04); // Enable motion interrupt I2C_RegisterWrite( CTRL_REG5, 0x04);// Route motion interrupts to INT1 ->PB5 ->EXTI5 I2C_RegisterWrite( CTRL_REG1, 0x11); // ODR=800 Hz, Active mode + } diff --git a/workspace/ts100/src/Main.c b/workspace/ts100/src/Main.c index 157b4141..0e156213 100644 --- a/workspace/ts100/src/Main.c +++ b/workspace/ts100/src/Main.c @@ -38,10 +38,14 @@ void setup() { StartUp_Accelerometer(systemSettings.sensitivity); //Start the accelerometer setupPID(); //Init the PID values readIronTemp(systemSettings.tempCalibration, 0, 0); //load the default calibration value - Init_Oled(systemSettings.flipDisplay); //Init the OLED display + if (systemSettings.OrientationMode == 2) + Init_Oled(!getOrientation()); //Init the OLED display + else + Init_Oled(systemSettings.OrientationMode); //Init the OLED display OLED_DrawString("VER 1.16", 8); //Version Number - delayMs(300); //Pause to show version number + delayMs(400); //Pause to show version number showBootLogoIfavailable(); - Start_Watchdog(1000); //start the system watch dog as 1 second timeout + Start_Watchdog(5000); //start the system watch dog as 5 second timeout + } diff --git a/workspace/ts100/src/Modes.c b/workspace/ts100/src/Modes.c index fb3ce4c2..ec90e4b2 100644 --- a/workspace/ts100/src/Modes.c +++ b/workspace/ts100/src/Modes.c @@ -5,17 +5,17 @@ * Author: Ralim */ #include "Modes.h" -const char *SettingsLongNames[] = { - " Power source. Sets cutoff voltage. ", - " Sleep Temperature ", " Sleep Timeout ", - " Shutdown Timeout ", - " Motion Sensitivity <0.Off 1.least sensitive 9.most sensitive>", - " Temperature Unit", " Temperature Rounding Amount", - " Temperature Display Update Rate", - " Flip Display for Left Hand", - " Enable front key boost 450C mode when soldering", - " Temperature when in boost mode", - " Changes the arrows to a power display when soldering" }; +const char *SettingsLongNames[] = + { " Power source. Sets cutoff voltage. ", + " Sleep Temperature ", " Sleep Timeout ", + " Shutdown Timeout ", + " Motion Sensitivity <0.Off 1.least sensitive 9.most sensitive>", + " Temperature Unit", " Temperature Rounding Amount", + " Temperature Display Update Rate", + " Display Orientation ", + " Enable front key boost 450C mode when soldering", + " Temperature when in boost mode", + " Changes the arrows to a power display when soldering" }; uint8_t StatusFlags = 0; uint32_t temporaryTempStorage = 0; @@ -37,6 +37,7 @@ void ProcessUI() { switch (operatingMode) { case STARTUP: + if (Buttons == (BUT_A | BUT_B)) { operatingMode = THERMOMETER; } else if (Buttons == BUT_A) { @@ -109,7 +110,7 @@ void ProcessUI() { } break; case TEMP_ADJ: - if (systemSettings.flipDisplay) { + if (OLED_GetOrientation() == 1) { if (Buttons == BUT_B) { //A key pressed so we are moving down in temp @@ -198,8 +199,10 @@ void ProcessUI() { systemSettings.displayTempInF = !systemSettings.displayTempInF; break; - case LEFTY: - systemSettings.flipDisplay = !systemSettings.flipDisplay; + case SCREENROTATION: + systemSettings.OrientationMode++; + systemSettings.OrientationMode = systemSettings.OrientationMode % 3; + break; case MOTIONSENSITIVITY: systemSettings.sensitivity++; @@ -329,12 +332,12 @@ void ProcessUI() { } else { //User is calibrating the dc input if (Buttons == BUT_A) { - if (!systemSettings.flipDisplay) + if (!systemSettings.OrientationMode) systemSettings.voltageDiv++; else systemSettings.voltageDiv--; } else if (Buttons == BUT_B) { - if (!systemSettings.flipDisplay) + if (!systemSettings.OrientationMode) systemSettings.voltageDiv--; else systemSettings.voltageDiv++; @@ -403,11 +406,15 @@ void drawTemp(uint16_t temp, uint8_t x, uint8_t roundingMode) { */ void DrawUI() { static uint32_t lastOLEDDrawTime = 0; + static uint16_t lastSolderingDrawnTemp1 = 0; static uint16_t lastSolderingDrawnTemp2 = 0; - static uint8_t settingsLongTestScrollPos = 0; uint16_t temp = readIronTemp(0, 0, 0xFFFF); + if (systemSettings.OrientationMode == 2) { + //Automatic mode + OLED_SetOrientation(!getOrientation()); + } switch (operatingMode) { case STARTUP: //We are chilling in the idle mode @@ -474,7 +481,7 @@ void DrawUI() { if (systemSettings.powerDisplay) { //We want to draw in a neat little bar graph of power being pushed to the tip //ofset 11 - uint16_t count = getIronTimer() / (40000 / 28); + uint16_t count = getIronTimer() / (30000 / 28); if (count > 28) count = 28; OLED_DrawWideChar((count), 6); @@ -563,12 +570,19 @@ void DrawUI() { else OLED_DrawString("TMPUNT C", 8); break; - case LEFTY: + case SCREENROTATION: - if (systemSettings.flipDisplay) - OLED_DrawString("FLPDSP T", 8); - else - OLED_DrawString("FLPDSP F", 8); + switch (systemSettings.OrientationMode) { + case 0: + OLED_DrawString("DSPROT R", 8); + break; + case 1: + OLED_DrawString("DSPROT L", 8); + break; + case 2: + OLED_DrawString("DSPROT A", 8); + break; + } break; case MOTIONSENSITIVITY: OLED_DrawString("MSENSE ", 7); diff --git a/workspace/ts100/src/Oled.c b/workspace/ts100/src/Oled.c index 0043b593..5e4e2b20 100644 --- a/workspace/ts100/src/Oled.c +++ b/workspace/ts100/src/Oled.c @@ -14,10 +14,12 @@ #include "Font.h" int8_t displayOffset = 32; +uint8_t currentOrientation = 0; /*Setup params for the OLED screen*/ /*http://www.displayfuture.com/Display/datasheet/controller/SSD1307.pdf*/ /*All commands are prefixed with 0x80*/ -u8 OLED_Setup_Array[46] = { 0x80, 0xAE,/*Display off*/ +u8 OLED_Setup_Array[46] = { /**/ +0x80, 0xAE,/*Display off*/ 0x80, 0xD5,/*Set display clock divide ratio / osc freq*/ 0x80, 0x52,/*Unknown*/ 0x80, 0xA8,/*Set Multiplex Ratio*/ @@ -60,18 +62,7 @@ void Oled_DisplayOff(void) { I2C_PageWrite(data, 6, DEVICEADDR_OLED); } -/* - * This sets the OLED screen to invert the screen (flip it vertically) - * This is used if the unit is set to left hand mode - */ -void Oled_DisplayFlip() { - u8 data[2] = { 0x80, 0XC8 }; - I2C_PageWrite(data, 2, DEVICEADDR_OLED); - data[1] = 0xA1; - I2C_PageWrite(data, 2, DEVICEADDR_OLED); - displayOffset = 0; -} /* Description: write a command to the Oled display Input: number of bytes to write, array to write @@ -150,8 +141,8 @@ void GPIO_Init_OLED(void) { Description: Initializes the Oled screen *******************************************************************************/ void Init_Oled(uint8_t leftHanded) { + currentOrientation = leftHanded; u8 param_len; - OLED_RST(); delayMs(5); OLED_ACT(); //Toggling reset to reset the oled @@ -161,6 +152,10 @@ void Init_Oled(uint8_t leftHanded) { OLED_Setup_Array[11] = 0xC8; OLED_Setup_Array[19] = 0xA1; displayOffset = 0; + } else { + OLED_Setup_Array[11] = 0xC0; + OLED_Setup_Array[19] = 0x40; + displayOffset = 32; } I2C_PageWrite((u8 *) OLED_Setup_Array, param_len, DEVICEADDR_OLED); } @@ -287,3 +282,13 @@ void OLED_DrawIDLELogo() { void OLED_DrawSymbol(uint8_t x, uint8_t symbol) { Oled_DrawArea(x * FONT_WIDTH, 0, 16, 16, SymbolTable + (symbol * 32)); } + +void OLED_SetOrientation(uint8_t ori) { + if (ori != currentOrientation) { + Init_Oled(ori); + } +} + +uint8_t OLED_GetOrientation() { + return currentOrientation; +} diff --git a/workspace/ts100/src/Settings.c b/workspace/ts100/src/Settings.c index 707a1e80..71bd81d6 100644 --- a/workspace/ts100/src/Settings.c +++ b/workspace/ts100/src/Settings.c @@ -64,7 +64,7 @@ void resetSettings() { systemSettings.cutoutSetting = 0; //default to no cut-off voltage systemSettings.version = SETTINGSVERSION;//Store the version number to allow for easier upgrades systemSettings.displayTempInF = 0; //default to C - systemSettings.flipDisplay = 0; //Default to right handed mode + systemSettings.OrientationMode = 2; //Default to automatic systemSettings.sensitivity = 6; //Default high sensitivity systemSettings.tempCalibration = 239; //Default to their calibration value systemSettings.voltageDiv = 144; //Default divider from schematic -- cgit v1.2.3