1
0
forked from me/IronOS

Compare commits

..

19 Commits
v1.06 ... v0.9

Author SHA1 Message Date
Ben V. Brown
718cfc4612 Retune acceleromter to be more sensive 2016-09-29 13:44:14 +10:00
Ben V. Brown
5a581b7a9f Sleep mode bugfix and better display 2016-09-29 13:39:46 +10:00
Ben V. Brown
bbb758fd4c Remove unneeded old font 2016-09-29 13:27:59 +10:00
Ben V. Brown
d4fbe99b8b Accelerometer into motion deteection using App Note 2016-09-29 13:16:21 +10:00
Ben V. Brown
c98e4126b2 Redeuce delay in readings and make it restore timer so we now have awesome performance 2016-09-29 00:31:36 +10:00
Ben V. Brown
c6559312f0 Roughly functioning menu system
Has some functionality issues
Still need settings saving & movement detection
2016-09-21 11:19:41 +10:00
Ben V. Brown
f4d5b8b000 PID regulating (fix error being unsigned..) 2016-09-21 00:26:43 +10:00
Ben V. Brown
65659b7b99 Rough PID added 2016-09-21 00:17:26 +10:00
Ben V. Brown
52e92feae7 Moved to use EXTI to read button status
Temperature sensor appears to work (may need calibration work still)
2016-09-20 23:11:36 +10:00
Ben V. Brown
98ca6784a0 creating the temperature functions 2016-09-20 14:33:59 +10:00
Ben V. Brown
f700422878 Filling out more of the mode change logic 2016-09-19 00:02:16 +10:00
Ben V. Brown
5aa27348b5 Improve Key Names, Add Font drawing,Working on modes 2016-09-18 22:43:35 +10:00
Ben V. Brown
c7e2713004 Creating my own font table for the OLED 2016-09-17 21:13:15 +10:00
Ben V. Brown
4db03d5832 Rename mode to make more sense 2016-09-17 00:00:47 +10:00
Ben V. Brown
f355ff6c01 Temp control working
Fix pid error
Remove pointless static keywords
2016-09-16 22:36:24 +10:00
Ben V. Brown
96bda69a0a Fix heater drive
Needed to enable the AFIO clock for the disabling reset to work.
2016-09-16 21:52:28 +10:00
Ben V. Brown
252c98372d Merge branch 'dev' of github.com:Ralim/ts100 into dev 2016-09-16 19:28:10 +10:00
Ben V. Brown
1ec2477033 Removing USB
Need to refine the drive to the iron tip
2016-09-16 19:23:29 +10:00
Ben V. Brown
6b21844020 Update README.md 2016-09-15 21:25:31 +10:00
33 changed files with 886 additions and 3230 deletions

3
.gitignore vendored
View File

@@ -27,7 +27,7 @@
*.app
*.i*86
*.x86_64
workspace/*.hex
*.hex
# Debug files
*.dSYM/
@@ -36,4 +36,3 @@ workspace/ts100/Debug/*
workspace/.metadata/*
workspace/ts100/.settings/language.settings.xml
workspace/ts100/.cproject

File diff suppressed because it is too large Load Diff

View File

@@ -1,85 +1,21 @@
# TS100
This is a complete re-write of the open source software for the ts100 soldering iron.
This project is feature complete for use as a soldering iron, but is still open to ideas and suggestions.
This is a complete open source re-write of the software for the ts100 soldering iron sold by minidso
This project was started to remove the need for USB for changing system settings.
In the latest official firmware they have also added a settings menu system, so it is still worth comparing the two firmwares to select your preferred option.
This was started to remove the need for usb for changing system settings.
## Features
The software has similar functionality to the original firmware.
# Features Working
* Soldering / Temperature control
* Full PID iron temperature control
* Automatic sleep with selectable sensitivity
* Full PID Iron Temp
* Adjusting temperature
* Automatic sleep
* Motion wake support
* Settings menu
* Input voltage UVLO measurement for battery powered use
* All settings saved
* Improved readability Fonts
* Use hardware features to improve reliability
* Can disable movement detection if desired
* Calibration of the temperature offset
* Basic settings menu
# Upgrading your ts100 iron
This is completely safe, if it goes wrong just put the .hex file from the official website onto the unit and your back to the old firmware. Downloads for the hex files to flash are available on the [releases page.](https://github.com/Ralim/ts100/releases)
**You will need a windows computer (7,8,10 tested), using the normal windows explorer to load the firmware.
The bootloader does not appear to work under mac or linux at the moment.**
1. Hold the button closest to the tip, and plug in the USB to the computer.
2. The unit will appear as a USB drive.
3. Drag the .hex file onto the USB drive.
4. The unit will disconnect and reconnect.
5. The filename will have changed to end in .RDY or .ERR .
6. If it ends with .RDY your done! Otherwise something went wrong.
7. Disconnect the USB and power up the iron. You're good to go.
For the more adventurerous out there, you can also load this firmware onto the device using a SWD programmer.
On the bottom of the MCU riser pcb, there are 4 pads for programming.
There is a complete device flash backup included in this repository. (Note this includes the bootloader, so will need a SWD programmer to load onto the unit). Please do not use the backup of the bootloader for anything malicious, its only saved here for those who are tinkering with their iron and decide to replace it.
# New Menu System
This new firmware uses a new menu system to allow access to the settings on the device.
When on the main screen, the unit shows prompts for the two most common operations.
-> Pressing the button near the tip enters soldering mode
-> Pressing the button near the power input enters the settings menu.
-> Pressing both buttons together enters the Extras menu
## Soldering mode
In this mode the iron works as you would expect, pressing either button will take you to a temperature change screen. Use each button to go up and down in temperature. Pressing both buttons will exit you from the temperature menu (or wait 3 seconds and it will time out).
Pressing both buttons will also exit the soldering mode.
## Settings Menu
This menu allows you to cycle through all the options and set their values.
The button near the tip cycles through the options, and the one near the usb changes the selected option.
Note that settings are not saved until you exit the menu, and some settings such as screen flip do not apply until a power cycle is applied.
* UVCO -> Undervoltage cut out level, settable in 1V increments from 10-24V
* STIME -> Sleep time, how long it takes before the unit goes to sleep
* STMP -> The temperature the unit drops to in sleep mode
* MOTION -> Wether motion detection is enabled or not
* TMPUNIT -> Temperature unit, C or F
* FLPDSP -> Flip display for left handed users
* SENSE -> Motion Sensitivity, H is more sensitive. L is lowest sensitivity (ie takes more movement to trigger)
## Extras Menu
This menu defaults to showing the current temperature on the tip.
Pressing the button near the iron tip will show the current input voltage. Pressing the other button while this is show will allow you to calibrate the reading if your iron is like mine and is not overly accurate out of the factory. (Press buttons to change measurement up and down, press both to exit and save).
Pressing the button near the usb enters the temperature offset setting menu, when the iron is cold, pressing the other button will start the unit calibrating for any offset in the tip temperature.
# Version Changes:
V1.05
- Adds ability to calibrate the input voltage measurement
V1.04
- Increased accuracy of the temperature control
- Improved PID response slightly
- Allows temperature offset calibration
- Nicer idle screen
V1.03
- Improved Button handling
- Ability to set motion sensitivity
- DC voltmeter page shows input voltage
V1.02
- Adds hold both buttons on IDLE to access the therometer mode.
- Changes the exit soldering mode to be holding both buttons (Like original firmware).
# Features still to be implimented
* Input voltage UVLO measurement
* Saving settings to flash for persistance
* Improved GUI
* Manual Temp Calibration
* Use hardware I2C

21
SystemDesign.md Normal file
View File

@@ -0,0 +1,21 @@
# System Design
# Movement Detection
The unit has a MMA8652FC Accelerometer on the small sub board along with the STM32.
This is used for motion detection of the soldering iron.
# USB Disk
When the unit is plugged into the computer, it presents a FAT device to the operating system over the usb connection.
This is implemented using a ram buffer for the disk.
# Future improvements to be made
These features are things I would like to add to the firmware
* Use the sysTick hardware for timing of events
* Move all the settings to an on device menu system instead of usb link
* Move error codes into a unified struct
* Rewrite most of the OLED stack to not require hardcoded values
* Rework the modes of the unit to be neater

Binary file not shown.

BIN
TS100.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

25
VERSION.txt Normal file
View File

@@ -0,0 +1,25 @@
v2.11 update (2015/08/03)
1, optimizing the key for delay;
2, optimized display processing
3, optimization of high-temperature alarm;
4, to increase the maximum voltage alarm;
5, the newly added screen protection, enter standby interface for some time, the screen will shut itself down, or move the iron screen button will automatically light up;
6, optimizing the movement decision
v2.10 update (2015/07/14)
1, temperature calibration is not refresh bug;
2, Cancel USB-powered thermometer into the function;
---Original --
v2.11 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(20150803)
1<EFBFBD><EFBFBD> <09>Ż<EFBFBD><C5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2<EFBFBD><EFBFBD> <09>Ż<EFBFBD><C5BB><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
3<EFBFBD><EFBFBD> <09>Ż<EFBFBD><C5BB><EFBFBD><EFBFBD>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD>
4<EFBFBD><EFBFBD> <09><><EFBFBD>߱<EFBFBD><DFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ѹ<EFBFBD><D1B9>
5<EFBFBD><EFBFBD> <09>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>Լ<EFBFBD><D4BC>رգ<D8B1><D5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
6<EFBFBD><EFBFBD> <09>Ż<EFBFBD><C5BB>ƶ<EFBFBD><C6B6>ж<EFBFBD>
v2.10 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(20150714)
1<EFBFBD><EFBFBD> <09><EFBFBD>У׼ʱû<CAB1><C3BB>ˢ<EFBFBD>µ<EFBFBD>bug<75><67>
2<EFBFBD><EFBFBD> ȡ<><C8A1>USB<53><42><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>¶ȼƵĹ<C6B5><C4B9>ܣ<EFBFBD>

View File

@@ -14,7 +14,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="fr.ac6.managedbuild.config.gnu.cross.exe.debug.1236130657" name="Debug" parent="fr.ac6.managedbuild.config.gnu.cross.exe.debug" postannouncebuildStep="Generating binary and Printing size information:" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;${BuildArtifactFileBaseName}.bin&quot;; arm-none-eabi-size &quot;${BuildArtifactFileName}&quot; ;arm-none-eabi-objcopy -O ihex &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;${BuildArtifactFileBaseName}.hex&quot;">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="fr.ac6.managedbuild.config.gnu.cross.exe.debug.1236130657" name="Debug" parent="fr.ac6.managedbuild.config.gnu.cross.exe.debug" postannouncebuildStep="Generating binary and Printing size information:" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;${BuildArtifactFileBaseName}.bin&quot;; arm-none-eabi-size &quot;${BuildArtifactFileName}&quot; ">
<folderInfo id="fr.ac6.managedbuild.config.gnu.cross.exe.debug.1236130657." name="/" resourcePath="">
<toolChain id="fr.ac6.managedbuild.toolchain.gnu.cross.exe.debug.2123758208" name="Ac6 STM32 MCU GCC" superClass="fr.ac6.managedbuild.toolchain.gnu.cross.exe.debug">
<option id="fr.ac6.managedbuild.option.gnu.cross.mcu.1416828544" name="Mcu" superClass="fr.ac6.managedbuild.option.gnu.cross.mcu" value="STM32F103T8Ux" valueType="string"/>
@@ -69,10 +69,10 @@
<tool id="fr.ac6.managedbuild.tool.gnu.archiver.1926145385" name="MCU GCC Archiver" superClass="fr.ac6.managedbuild.tool.gnu.archiver"/>
<tool id="fr.ac6.managedbuild.tool.gnu.cross.assembler.104990963" name="MCU GCC Assembler" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler">
<option id="gnu.both.asm.option.include.paths.834243276" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/StdPeriph_Driver/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/CMSIS/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/CMSIS/device}&quot;"/>
<listOptionValue builtIn="false" value="/home/ralim/Repo/ts100/workspace/ts100/inc"/>
<listOptionValue builtIn="false" value="/home/ralim/Repo/ts100/workspace/ts100/StdPeriph_Driver/inc"/>
<listOptionValue builtIn="false" value="/home/ralim/Repo/ts100/workspace/ts100/CMSIS/core"/>
<listOptionValue builtIn="false" value="/home/ralim/Repo/ts100/workspace/ts100/CMSIS/device"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1754789872" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.assembler.input.610009869" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler.input"/>
@@ -103,7 +103,7 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="fr.ac6.managedbuild.config.gnu.cross.exe.release.1113492345" name="Release" parent="fr.ac6.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary and Printing size information:" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;${BuildArtifactFileBaseName}.bin&quot;; arm-none-eabi-size -B &quot;${BuildArtifactFileName}&quot;;arm-none-eabi-objcopy -O ihex &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;${BuildArtifactFileBaseName}.hex&quot;">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="fr.ac6.managedbuild.config.gnu.cross.exe.release.1113492345" name="Release" parent="fr.ac6.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating binary and Printing size information:" postbuildStep="arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileBaseName}.elf&quot; &quot;${BuildArtifactFileBaseName}.bin&quot;; arm-none-eabi-size -B &quot;${BuildArtifactFileName}&quot;">
<folderInfo id="fr.ac6.managedbuild.config.gnu.cross.exe.release.1113492345." name="/" resourcePath="">
<toolChain id="fr.ac6.managedbuild.toolchain.gnu.cross.exe.release.668479481" name="Ac6 STM32 MCU GCC" superClass="fr.ac6.managedbuild.toolchain.gnu.cross.exe.release">
<option id="fr.ac6.managedbuild.option.gnu.cross.mcu.302274410" name="Mcu" superClass="fr.ac6.managedbuild.option.gnu.cross.mcu" value="STM32F103T8Ux" valueType="string"/>

View File

@@ -1,2 +1 @@
/Debug/
/Release/

View File

@@ -62,11 +62,11 @@ _Min_Stack_Size = 0x400; /* required amount of stack */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
ROM (rx) : ORIGIN = 0x08004000, LENGTH = 47K
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 64K
}
/*ROM (rx) : ORIGIN = 0x08004000, LENGTH = 48K*/
/*^ The offset at the beginning in the bootloader, 1K at the end for settings (actually 256 bytes, but leaving room for now)*/
/*^ The rom is shortened as the last ~10K is used for storing the virtual USB Disk, and the offset at the beginning in the bootloader*/
/* Sections */
SECTIONS
{

View File

@@ -0,0 +1,43 @@
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. ********************
File Name : APP_Version.h
Version : S100 APP Ver 2.11
Description:
Author : bure & Celery
Data: 2015/08/03
History:
2015/08/03 ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*******************************************************************************/
#ifndef __VERSION_H
#define __VERSION_H
#define M_VER 'V','0'
#define S_VER '0','1'
#define OEM_TYPE "0"
#define APP_BASE 0x0800C000/*Start address of the virtual disk*/
/*----------------------------------------------------------------------------*/
#ifdef TYPE_DS201
#define PRODUCT_INFO "DS201"
#define SCH_VER "1.7B"
#else
#ifdef TYPE_DS202
#include "DS202V1_6.h"
#define FLASH_PAGE 0x0800
#else
#ifdef TYPE_DS203
#define PRODUCT_INFO "DS203"
#define SCH_VER "2.70"
#else
#ifdef TYPE_S100
#define PRODUCT_INFO "TS100"
#include "S100V0_1.h"
#endif
#endif
#endif
#endif
/*----------------------------------------------------------------------------*/
#define DFU_VER {M_VER,'.',S_VER,LCD_M, 0}
#endif /* VERSION_H */
/********************************* END OF FILE ******************************/

View File

@@ -3,18 +3,16 @@
*
* Created on: 20 Sep 2016
* Author: ralim
*
* Interface to the ADC's basically
*/
#ifndef ANALOG_H_
#define ANALOG_H_
#include "stm32f10x.h"
#include "S100V0_1.h"
#include "Bios.h"
#include "Interrupt.h"
extern volatile uint16_t ADC1ConvertedValue[2];
uint16_t Get_ADC1Value(uint8_t i);
uint16_t readIronTemp(uint16_t calibration_temp, uint8_t read,uint16_t setPointTemp); //read the iron temp in C X10
uint16_t readDCVoltage(uint16_t divFactor);/*Get the system voltage X10*/
uint16_t readIronTemp(uint16_t calibration,uint8_t read);
#endif /* ANALOG_H_ */

View File

@@ -7,14 +7,7 @@
#include "stm32f10x.h"
#include "S100V0_1.h"/*For pin definitions*/
#include "Analog.h"/*So that we can attach the DMA to the output array*/
#include "stm32f10x_flash.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_iwdg.h"
#include "misc.h"
extern volatile uint32_t gHeat_cnt;
inline void setIronTimer(uint32_t time) {
@@ -41,4 +34,4 @@ void Init_EXTI(void);
void Start_Watchdog(uint32_t ms);
void Clear_Watchdog(void);
#endif
/********************************* END OF FILE ********************************/

View File

@@ -3,190 +3,88 @@
*
* Created on: 17 Sep 2016
* Author: Ralim
*
* ... This file contains the font...
*/
#ifndef FONT_H_
#define FONT_H_
#define FONT_WIDTH 12 /*How many pixels wide the font is*/
const uint8_t FONT[]={
0x00,0xF0,0xFC,0x0E,0x82,0xC2,0x62,0x1E,0xFC,0xF0,0x00,0x00,
0x00,0x03,0x0F,0x1F,0x11,0x10,0x10,0x1C,0x0F,0x03,0x00,0x00,/*0*/
0x00,0x08,0x04,0x02,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00,0x00,/*1*/
0x00,0x04,0x02,0x02,0x02,0xC6,0xFC,0x78,0x00,0x00,0x00,0x00,
0x00,0x18,0x1C,0x16,0x13,0x11,0x10,0x10,0x10,0x00,0x00,0x00,/*2*/
0x00,0x02,0x02,0x42,0x42,0x66,0xFE,0x9C,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x10,0x10,0x08,0x0F,0x07,0x00,0x00,0x00,/*3*/
0x00,0x00,0x80,0xE0,0x30,0x1C,0x06,0xFE,0xFE,0x00,0x00,0x00,
0x00,0x03,0x03,0x02,0x02,0x02,0x02,0x1F,0x1F,0x02,0x02,0x00,/*4*/
0x00,0x7E,0x7E,0x42,0x42,0x42,0xC2,0x82,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x10,0x10,0x08,0x0F,0x07,0x00,0x00,0x00,/*5*/
0x00,0xE0,0xF8,0x8C,0x44,0x42,0x42,0xC2,0x82,0x80,0x00,0x00,
0x00,0x07,0x0F,0x18,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,/*6*/
0x00,0x02,0x02,0x02,0x02,0xC2,0xF2,0x1E,0x06,0x00,0x00,0x00,
0x00,0x00,0x10,0x1C,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,/*7*/
0x00,0x38,0x7C,0x66,0xC2,0x82,0xC2,0x66,0x7C,0x3C,0x00,0x00,
0x00,0x0E,0x0F,0x19,0x10,0x10,0x10,0x19,0x0F,0x0E,0x00,0x00,/*8*/
0x00,0x78,0x7C,0xC6,0x82,0x82,0x82,0x46,0xFC,0xF8,0x00,0x00,
0x00,0x00,0x10,0x10,0x10,0x10,0x08,0x0C,0x07,0x03,0x00,0x00,/*9*/
const u8 FONT[]={
0x00,0xF0,0xFC,0x0E,0x82,0xC2,0x62,0x1E,0xFC,0xF0,0x00,0x00,0x00,0x00,
0x00,0x03,0x0F,0x1F,0x11,0x10,0x10,0x1C,0x0F,0x03,0x00,0x00,0x00,0x00,/*0*/
0x00,0x08,0x04,0x02,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,/*1*/
0x00,0x04,0x02,0x02,0x02,0xC6,0xFC,0x78,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x18,0x1C,0x16,0x13,0x11,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,/*2*/
0x00,0x02,0x02,0x42,0x42,0x66,0xFE,0x9C,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x10,0x10,0x08,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,/*3*/
0x00,0x00,0x80,0xE0,0x30,0x1C,0x06,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,
0x00,0x03,0x03,0x02,0x02,0x02,0x02,0x1F,0x1F,0x02,0x02,0x00,0x00,0x00,/*4*/
0x00,0x7E,0x7E,0x42,0x42,0x42,0xC2,0x82,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x10,0x10,0x08,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,/*5*/
0x00,0xE0,0xF8,0x8C,0x44,0x42,0x42,0xC2,0x82,0x80,0x00,0x00,0x00,0x00,
0x00,0x07,0x0F,0x18,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,0x00,0x00,/*6*/
0x00,0x02,0x02,0x02,0x02,0xC2,0xF2,0x1E,0x06,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x1C,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*7*/
0x00,0x38,0x7C,0x66,0xC2,0x82,0xC2,0x66,0x7C,0x3C,0x00,0x00,0x00,0x00,
0x00,0x0E,0x0F,0x19,0x10,0x10,0x10,0x19,0x0F,0x0E,0x00,0x00,0x00,0x00,/*8*/
0x00,0x78,0x7C,0xC6,0x82,0x82,0x82,0x46,0xFC,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x10,0x10,0x10,0x08,0x0C,0x07,0x03,0x00,0x00,0x00,0x00,/*9*/
0x00,0x00,0x80,0xF0,0x1E,0x02,0x1E,0xF0,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x1C,0x0F,0x03,0x02,0x02,0x02,0x03,0x0F,0x1C,0x00,0x00,0x00,0x00,/*A*/
0x00,0xFE,0xFE,0x42,0x42,0x42,0xE6,0xBE,0x9C,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,/*B*/
0x00,0xF0,0xF8,0x0C,0x06,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,
0x00,0x03,0x0F,0x0C,0x18,0x10,0x10,0x10,0x08,0x00,0x00,0x00,0x00,0x00,/*C*/
0x00,0xFE,0xFE,0x02,0x02,0x02,0x06,0x0C,0xFC,0xF0,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x18,0x0C,0x07,0x03,0x00,0x00,0x00,0x00,/*D*/
0x00,0xFE,0xFE,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,/*E*/
0x00,0xFE,0xFE,0x82,0x82,0x82,0x82,0x82,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*F*/
0x00,0xF0,0xF8,0x0C,0x06,0x02,0x82,0x82,0x82,0x84,0x00,0x00,0x00,0x00,
0x00,0x03,0x0F,0x0C,0x18,0x10,0x10,0x10,0x1F,0x1F,0x00,0x00,0x00,0x00,/*G*/
0x00,0xFE,0xFE,0x40,0x40,0x40,0x40,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,/*H*/
0x00,0x02,0x02,0x02,0xFE,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,/*I*/
0x00,0x02,0x02,0x02,0x02,0x02,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x08,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,/*J*/
0x00,0xFE,0xFE,0xC0,0xE0,0x30,0x18,0x0C,0x06,0x02,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x01,0x03,0x06,0x0C,0x18,0x10,0x00,0x00,0x00,0x00,/*K*/
0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,/*L*/
0x00,0x00,0xFE,0x06,0x3C,0xC0,0xC0,0x3C,0x06,0xFE,0x00,0x00,0x00,0x00,
0x00,0x10,0x1F,0x00,0x00,0x01,0x01,0x00,0x00,0x1F,0x18,0x00,0x00,0x00,/*M*/
0x00,0xFE,0xFE,0x1E,0x70,0x80,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x03,0x1C,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,/*N*/
0x00,0xF0,0xFC,0x0C,0x02,0x02,0x02,0x0E,0xFC,0xF0,0x00,0x00,0x00,0x00,
0x00,0x03,0x0F,0x1C,0x10,0x10,0x10,0x0C,0x0F,0x03,0x00,0x00,0x00,0x00,/*O*/
0x00,0xFE,0xFE,0x02,0x02,0x02,0x86,0xFC,0x78,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*P*/
0x00,0xF0,0xF8,0x0C,0x02,0x02,0x02,0x02,0x0C,0xFC,0xF0,0x00,0x00,0x00,
0x00,0x03,0x0F,0x1C,0x10,0x30,0x70,0xD8,0x8C,0x8F,0x83,0x40,0x00,0x00,/*Q*/
0x00,0xFE,0xFE,0x42,0x42,0xC2,0xE6,0x3C,0x1C,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x00,0x01,0x0F,0x1C,0x10,0x00,0x00,0x00,0x00,/*R*/
0x00,0x38,0x7C,0x66,0xC2,0xC2,0x82,0x84,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x08,0x10,0x10,0x10,0x10,0x19,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,/*S*/
0x00,0x02,0x02,0x02,0x02,0xFE,0xFE,0x02,0x02,0x02,0x02,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*T*/
0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,
0x00,0x07,0x0F,0x18,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,0x00,0x00,/*U*/
0x00,0x0E,0x7E,0xE0,0x00,0x00,0x00,0xE0,0x7C,0x0E,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0x1F,0x18,0x1F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,/*V*/
0x00,0x7E,0xFE,0x00,0x00,0xE0,0xE0,0x00,0x00,0xFE,0x7E,0x00,0x00,0x00,
0x00,0x00,0x1F,0x18,0x0F,0x01,0x01,0x0F,0x18,0x1F,0x00,0x00,0x00,0x00,/*W*/
0x00,0x02,0x06,0x1C,0x38,0xE0,0xE0,0x38,0x1C,0x06,0x02,0x00,0x00,0x00,
0x00,0x10,0x18,0x0E,0x07,0x01,0x01,0x07,0x0E,0x18,0x10,0x00,0x00,0x00,/*X*/
0x00,0x02,0x0E,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0E,0x02,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*Y*/
0x00,0x02,0x02,0x02,0xC2,0xE2,0x3A,0x0E,0x02,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x1C,0x17,0x11,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,/*Z*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/* */
0x00,0x00,0x80,0xF0,0x1E,0x02,0x1E,0xF0,0x80,0x00,0x00,0x00,
0x00,0x1C,0x0F,0x03,0x02,0x02,0x02,0x03,0x0F,0x1C,0x00,0x00,/*A*/
0x00,0xFE,0xFE,0x42,0x42,0x42,0xE6,0xBE,0x9C,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,0x00,/*B*/
0x00,0xF0,0xF8,0x0C,0x06,0x02,0x02,0x02,0x04,0x00,0x00,0x00,
0x00,0x03,0x0F,0x0C,0x18,0x10,0x10,0x10,0x08,0x00,0x00,0x00,/*C*/
0x00,0xFE,0xFE,0x02,0x02,0x02,0x06,0x0C,0xFC,0xF0,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x18,0x0C,0x07,0x03,0x00,0x00,/*D*/
0x00,0xFE,0xFE,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,/*E*/
0x00,0xFE,0xFE,0x82,0x82,0x82,0x82,0x82,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*F*/
0x00,0xF0,0xF8,0x0C,0x06,0x02,0x82,0x82,0x82,0x84,0x00,0x00,
0x00,0x03,0x0F,0x0C,0x18,0x10,0x10,0x10,0x1F,0x1F,0x00,0x00,/*G*/
0x00,0xFE,0xFE,0x40,0x40,0x40,0x40,0xFE,0xFE,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,/*H*/
0x00,0x02,0x02,0x02,0xFE,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00,0x00,/*I*/
0x00,0x02,0x02,0x02,0x02,0x02,0xFE,0xFE,0x00,0x00,0x00,0x00,
0x00,0x08,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,0x00,0x00,/*J*/
0x00,0xFE,0xFE,0xC0,0xE0,0x30,0x18,0x0C,0x06,0x02,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x01,0x03,0x06,0x0C,0x18,0x10,0x00,0x00,/*K*/
0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,/*L*/
0x00,0x00,0xFE,0x06,0x3C,0xC0,0xC0,0x3C,0x06,0xFE,0x00,0x00,
0x00,0x10,0x1F,0x00,0x00,0x01,0x01,0x00,0x00,0x1F,0x18,0x00,/*M*/
0x00,0xFE,0xFE,0x1E,0x70,0x80,0x00,0xFE,0xFE,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x03,0x1C,0x1F,0x1F,0x00,0x00,0x00,/*N*/
0x00,0xF0,0xFC,0x0C,0x02,0x02,0x02,0x0E,0xFC,0xF0,0x00,0x00,
0x00,0x03,0x0F,0x1C,0x10,0x10,0x10,0x0C,0x0F,0x03,0x00,0x00,/*O*/
0x00,0xFE,0xFE,0x02,0x02,0x02,0x86,0xFC,0x78,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,/*P*/
0x00,0xF0,0xF8,0x0C,0x02,0x02,0x02,0x02,0x0C,0xFC,0xF0,0x00,
0x00,0x03,0x0F,0x1C,0x10,0x30,0x70,0xD8,0x8C,0x8F,0x83,0x40,/*Q*/
0x00,0xFE,0xFE,0x42,0x42,0xC2,0xE6,0x3C,0x1C,0x00,0x00,0x00,
0x00,0x1F,0x1F,0x00,0x00,0x00,0x01,0x0F,0x1C,0x10,0x00,0x00,/*R*/
0x00,0x38,0x7C,0x66,0xC2,0xC2,0x82,0x84,0x00,0x00,0x00,0x00,
0x00,0x08,0x10,0x10,0x10,0x10,0x19,0x0F,0x07,0x00,0x00,0x00,/*S*/
0x00,0x02,0x02,0x02,0x02,0xFE,0xFE,0x02,0x02,0x02,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,/*T*/
0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,
0x00,0x07,0x0F,0x18,0x10,0x10,0x10,0x18,0x0F,0x07,0x00,0x00,/*U*/
0x00,0x0E,0x7E,0xE0,0x00,0x00,0x00,0xE0,0x7C,0x0E,0x00,0x00,
0x00,0x00,0x00,0x03,0x1F,0x18,0x1F,0x03,0x00,0x00,0x00,0x00,/*V*/
0x00,0x7E,0xFE,0x00,0x00,0xE0,0xE0,0x00,0x00,0xFE,0x7E,0x00,
0x00,0x00,0x1F,0x18,0x0F,0x01,0x01,0x0F,0x18,0x1F,0x00,0x00,/*W*/
0x00,0x02,0x06,0x1C,0x38,0xE0,0xE0,0x38,0x1C,0x06,0x02,0x00,
0x00,0x10,0x18,0x0E,0x07,0x01,0x01,0x07,0x0E,0x18,0x10,0x00,/*X*/
0x00,0x02,0x0E,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0E,0x02,0x00,
0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,/*Y*/
0x00,0x02,0x02,0x02,0xC2,0xE2,0x3A,0x0E,0x02,0x00,0x00,0x00,
0x00,0x10,0x1C,0x17,0x11,0x10,0x10,0x10,0x10,0x00,0x00,0x00,/*Z*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/* */
0x00,0x60,0xF0,0x98,0x0C,0x06,0x02,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00,0x00,0x00,0x00,/*<*/
0x00,0x02,0x06,0x0C,0x98,0xF0,0x60,0x00,0x00,0x00,0x00,0x00,
0x00,0x04,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*>*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00,/*.*/
};
const uint8_t Iron_Base[] ={
0x00,0x20,0x60,0x60,0x60,0x60,0x60,0x60,0x90,0x90,0x90,0x90,
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x60,0x60,
0x60,0x60,0x60,0x60,0x60,0x70,0xF8,0x88,0x84,0x82,0x82,0x83,
0x83,0x83,0x83,0x83,0x83,0x82,0x82,0x82,0x82,0x83,0x83,0x83,
0x83,0x83,0x83,0x82,0x82,0x82,0x82,0x82,0x86,0x84,0x84,0x84,
0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,
0x84,0x84,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,
};
//The top pixel row for left arrow / on hint
const uint8_t Iron_LeftArrow_UP[] = {
0x00,0x7C,0x82,0x82,0x82,0x7C,0x00,0xFE,0x08,0x10,0x20,0xFE,//ON
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,
0x98,0xBF,0xBF,0x98,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
const uint8_t Iron_LeftArrow_DOWN[] = {
0x00,0x7C,0x82,0x82,0x82,0x7C,0x00,0xFE,0x08,0x10,0x20,0xFE,//ON
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,
0x30,0x7E,0x7E,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,
};
//The top pixel row for both arrows /
const uint8_t Iron_BothArrows[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,
0x98,0xBF,0xBF,0x98,0x88,0x00,0x00,0x00,0x00,0x88,0x98,0xBF,
0xBF,0x98,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
//The top pixel row for right arrow / settings hint
const uint8_t Iron_RightArrow_UP[] = {
0x00,0x8C,0x92,0x92,0x92,0x62,0x00,0xFE,0x92,0x92,0x92,0x82,//SE
0x00,0x02,0x02,0xFE,0x02,0x02,0x00,0x02,0x02,0xFE,0x02,0x02,//TT
0x00,0x00,0x82,0xFE,0x82,0x00,0x00,0xFE,0x08,0x10,0x20,0xFE,//IN
0x00,0x7C,0x82,0x82,0xA2,0x62,0x00,0x8C,0x92,0x92,0x92,0x62,//GS
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x98,0xBF,
0xBF,0x98,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
const uint8_t Iron_RightArrow_DOWN[] = {
0x00,0x8C,0x92,0x92,0x92,0x62,0x00,0xFE,0x92,0x92,0x92,0x82,//SE
0x00,0x02,0x02,0xFE,0x02,0x02,0x00,0x02,0x02,0xFE,0x02,0x02,//TT
0x00,0x00,0x82,0xFE,0x82,0x00,0x00,0xFE,0x08,0x10,0x20,0xFE,//IN
0x00,0x7C,0x82,0x82,0xA2,0x62,0x00,0x8C,0x92,0x92,0x92,0x62,//GS
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x30,0x7E,
0x7E,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,
};
const uint8_t SymbolTable[]={
0x0E,0x11,0x11,0x0E,0xE0,0xF8,0x0C,0x06,0x03,0x01,0x01,0x01,0x01,0x02,0x1E,0x00,
0x00,0x00,0x00,0x00,0x0F,0x3F,0x70,0xC0,0x80,0x80,0x80,0x80,0x80,0x40,0x20,0x00, // Degrees C
0x08,0x14,0x22,0x14,0x08,0x02,0x02,0xFE,0x06,0x02,0x02,0x02,0xC2,0x02,0x06,0x1E,
0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xFF,0x81,0x81,0x01,0x01,0x03,0x00,0x00,0x00, // Degrees F
0xC0,0x30,0x08,0x04,0x04,0x02,0xFA,0xAA,0xFA,0x02,0x04,0x04,0x08,0x30,0xC0,0x00,
0x07,0x18,0x20,0x40,0x58,0xA4,0xDB,0xDE,0xDB,0xA4,0x58,0x40,0x20,0x18,0x07,0x00, // Temp symbol
0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0xF0,0x00,0x00,0xFC,0xF8,0xF0,0xE0,0xC0,0x80, //Right Arrow
0x00,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x0F,0x00,0x00,0x3F,0x1F,0x0F,0x07,0x03,0x01,
0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0x00,0x00,0xF0,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00, //Left Arrow
0x01,0x03,0x07,0x0F,0x1F,0x3F,0x00,0x00,0x0F,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00,
0x11,0x33,0x66,0xCC,0x98,0x30,0x60,0xC0,0xC0,0x60,0x30,0x98,0xCC,0x66,0x33,0x11,
0x01,0x03,0x06,0x0C,0x19,0x33,0x66,0xCC,0xCC,0x66,0x33,0x19,0x0C,0x06,0x03,0x01, //Down Chevron
0x80,0xC0,0x60,0x30,0x98,0xCC,0x66,0x33,0x33,0x66,0xCC,0x98,0x30,0x60,0xC0,0x80,
0x88,0xCC,0x66,0x33,0x19,0x0C,0x06,0x03,0x03,0x06,0x0C,0x19,0x33,0x66,0xCC,0x88, //Up Chevron
0x00,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x00, // Flat Lines
0x00,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x00,
};
#endif /* FONT_H_ */

View File

@@ -1,16 +1,21 @@
/*
* I2C.h
* I2C wrapper for the stm32 hardware I2C port
*/
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. **********************
File Name : I2C.h
Version : S100 APP Ver 2.11
Description:
Author : Celery
Data: 2015/08/03
History:
2015/08/03 :
*******************************************************************************/
#ifndef __I2C_H
#define __I2C_H
#include "stm32f10x_i2c.h"
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#define I2C_TX 1
#define I2C_RX 2
void I2C_Configuration(void);
void I2C_PageWrite(u8* pbuf, u8 numbyte, u8 deviceaddr);
void I2C_PageRead(u8* pbuf, u8 numbyte, u8 deviceaddr, u8 readaddr);
void Delay_uS(u32 us);
void I2C_PageWrite(u8* pbuf, u8 numbyte,u8 deviceaddr );
void I2C_PageRead(u8* pbuf, u8 numbyte,u8 deviceaddr, u8 readaddr);
#endif
/******************************** END OF FILE *********************************/

View File

@@ -1,11 +1,34 @@
/*
* Interrupt Service Routines
* This file manages all the IRQ events that can be generated
*/
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. *******************/
/* Brief : Interrupt Service Routines Author : bure */
/******************************************************************************/
#ifndef __INTERRUPT_H
#define __INTERRUPT_H
#include <stdint.h>
/* Functions for access to data */
//See here for refernce to this block http://embedded.kleier.selfhost.me/vector.php
/*This loop is used for un assigned IRQ's so that the debugger can catch them*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void WWDG_IRQHandler(void);
void PVD_IRQHandler(void);
void TAMPER_STAMP_IRQHandler(void);
void RTC_WKUP_IRQHandler(void);
void FLASH_IRQHandler(void);
void USB_LP_CAN1_RX0_IRQHandler(void);
void I2C1_EV_IRQHandler(void);
void I2C1_ER_IRQHandler(void);
void TIM2_IRQHandler(void);
void TIM3_IRQHandler(void);
extern volatile uint32_t system_Ticks;
void delayMs(uint32_t ticks);
volatile extern uint32_t lastKeyPress;
@@ -34,30 +57,6 @@ inline uint32_t getLastMovement() {
inline uint16_t getButtons() {
return keyState;
}
/*IRQ prototypes*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void WWDG_IRQHandler(void);
void PVD_IRQHandler(void);
void TAMPER_STAMP_IRQHandler(void);
void RTC_WKUP_IRQHandler(void);
void FLASH_IRQHandler(void);
void USB_LP_CAN1_RX0_IRQHandler(void);
void I2C1_EV_IRQHandler(void);
void I2C1_ER_IRQHandler(void);
void TIM2_IRQHandler(void);
void TIM3_IRQHandler(void);
void WWDG_IRQHandler(void);
void PVD_IRQHandler(void);

View File

@@ -6,8 +6,7 @@
*
* http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8652FC.pdf
*
* EXTI Motion config setup values lifted from AN4070 from NXP
* #defines also taken from ^
* EXTI Motion config setup values lifted from AN4070from NXP
*
* Ben V. Brown - <ralim@ralimtek.com>
*/
@@ -15,7 +14,7 @@
#define __MMA8652FC__H
void StartUp_Accelerometer(uint8_t sensitivity);//This is the only function we expose
void StartUp_Acceleromter(void);//This is the only function we expose
//--------------MMA8652 Device ID----------------------------------------------//

View File

@@ -3,9 +3,6 @@
*
* Created on: 17 Sep 2016
* Author: Ralim
*
* Modes.h -> Main function for driving the application
* This processes the buttons then does the gui
*/
#ifndef MODES_H_
@@ -14,32 +11,27 @@
#include "S100V0_1.h"
#include "Oled.h"
#include "PID.h"
#include "Settings.h"
#include "Analog.h"
enum {
STARTUP, //we are sitting on the prompt to push a button
SOLDERING, //Normal operating mode
TEMP_ADJ, //Adjust the set temperature
SETTINGS, //Settings menu
SLEEP, //Iron is snoozing due to lack of use
COOLING, //Iron is cooling down -> Warning screen
UVLOWARN, //Unit tripped low voltage
THERMOMETER, //Read the tip temp
DCINDISP, //Disp the input voltage && Cal the DCin voltage divider
TEMPCAL, //Cal tip temp offset
STARTUP, //we are sitting on the prompt to push a button
SOLDERING,
TEMP_ADJ,
SETTINGS,
SLEEP,
} operatingMode;
enum {
UVCO = 0,
SLEEP_TEMP,
SLEEP_TIME,
MOTIONDETECT,
MOTIONSENSITIVITY,
TEMPDISPLAY,
LEFTY,
UVLO = 0, SLEEP_TEMP, SLEEP_TIME,
} settingsPage;
struct {
uint32_t SolderingTemp; //current setpoint for the iron
uint8_t SleepTime; //minutes to sleep
uint32_t SleepTemp; //temp to drop to in sleep
uint8_t cutoutVoltage; //X10 the voltage we cutout at for undervoltage
uint8_t movementEnabled;
} systemSettings;
void ProcessUI();
void DrawUI();
#endif /* MODES_H_ */

View File

@@ -1,33 +1,39 @@
/*
* Oled.h
* Functions for writing to the OLED screen
* Basically wraps drawing text and numbers to the OLED
* Uses font.h -> 14 pixel wide fixed width
*/
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. **********************
File Name : Oled.h
Version : S100 APP Ver 2.11
Description:
Author : Celery
Data: 2015/07/07
History:
2015/07/07 ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*******************************************************************************/
#ifndef _OLED_SSD1306_H
#define _OLED_SSD1306_H
#define DEVICEADDR_OLED 0x3c
#include "stm32f10x.h"
#include "Interrupt.h"
void Sc_Pt(u8 Co);
void Oled_DisplayOn(void);
void Oled_DisplayOff(void);
u8* Oled_DrawArea(u8 x0, u8 y0, u8 wide, u8 high, u8* ptr);
void Set_ShowPos(u8 x, u8 y);
void Oled_DisplayFlip();
u8* Show_posi(u8 posi, u8* ptr, u8 word_width);
void Clean_Char(int k, u8 wide);
void Write_Command(u8 Data);
void Write_Data(u8 Data);
void GPIO_Init_OLED(void);
void Init_Oled(uint8_t leftHanded);
void Init_Oled(void);
u8* Data_Command(u8 len, u8* ptr);
void Clear_Screen(void);//Clear the screen
/*Functions for writing to the screen*/
void Reg_Command(u8 posi, u8 flag);
void Clear_Screen(void);
void Write_InitCommand_data(u32 Com_len, u8* data);
void Display_BG(void);
void OLED_DrawString(char* string, uint8_t length);
void OLED_DrawChar(char c, uint8_t x);
void OLED_DrawTwoNumber(uint8_t in, uint8_t x);
void OLED_BlankSlot(uint8_t xStart,uint8_t width);
void OLED_DrawThreeNumber(uint16_t in, uint8_t x);
void OLED_DrawIDLELogo();
void OLED_DrawSymbol(uint8_t x,uint8_t symbol);
#endif
/******************************** END OF FILE *********************************/

View File

@@ -3,15 +3,12 @@
*
* Created on: 20 Sep 2016
* Author: ralim
*
* Functions for computing the PID for the iron temp
*/
#ifndef PID_H_
#define PID_H_
#include "Analog.h"
#include "Interrupt.h"
struct {
uint32_t kp, ki, kd; //PID values
} pidSettings;

View File

@@ -1,9 +1,14 @@
/*
* Defines for the device
* These houses the settings for the device hardware
*/
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. ********************
Brief : <20>ײ<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Author : bure
Modified by Ben V. Brown into English
*******************************************************************************/
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#define PRODUCT_INFO "TS100"
#define MCU_TYPE "STM32F103T8"
#define SCH_VER "2.46"
#define SPIx SPI1
//--------------------------- key Definitions ------------------------------//
#define KEY1_PIN GPIO_Pin_9 //PA8
#define KEY2_PIN GPIO_Pin_6 //PA6
@@ -12,24 +17,45 @@
#define KEY_B KEY2_PIN
#define BUT_A 0x01
#define BUT_B 0x02
#define BUT_AB BUT_A|BUT_B
#define KEY_1 !(GPIOA->IDR & KEY1_PIN)
#define KEY_2 !(GPIOA->IDR & KEY2_PIN)
#define KEY_DFU KEY_1
#define I2C1_DMA_CHANNEL_TX DMA1_Channel6
#define I2C1_DMA_CHANNEL_RX DMA1_Channel7
#define I2C2_DMA_CHANNEL_TX DMA1_Channel4
#define I2C2_DMA_CHANNEL_RX DMA1_Channel5
#define I2C1_DR_Address 0x40005410
#define I2C2_DR_Address 0x40005810
//--------------------------- OLED ------------------------------//
#define OLED_RST_PIN GPIO_Pin_8 //PA9
#define OLED_RST() GPIO_ResetBits(GPIOA, OLED_RST_PIN)
#define OLED_ACT() GPIO_SetBits (GPIOA, OLED_RST_PIN)
//------------------------------ Iron Heater --------------------------------//
//------------------------------ --------------------------------//
#define HEAT_PIN GPIO_Pin_4
#define HEAT_OFF() GPIOB->BRR = HEAT_PIN
#define HEAT_ON() GPIOB->BSRR = HEAT_PIN
//-----------------------Battery voltage measurement---------------------------------------//
//-----------------------VB---------------------------------------//
#define VB_PIN GPIO_Pin_1 //PB1(Ai9)
//----------------------------Accelerometer INT1,INT2--------------------------------//
//----------------------------ADX345 INT1,INT2--------------------------------//
#define INT1_PIN GPIO_Pin_5 //PB5
#define INT2_PIN GPIO_Pin_3 //PB3
//------------------------------ GPIO -------------------------------//
#define GPIOA_OUTPUT() GPIOA->ODR = 0xFFFF;
#define GPIOA_L_DEF() GPIOA->CRL = 0x08888888; /* Ai7 K2 xxx xxx xxx xxx xxx xxx */
#define GPIOA_H_DEF() GPIOA->CRH = 0x8BBBB883; /* xxx SWC SWD D+ D- xxx K1 nCR */
#define GPIOB_OUTPUT() GPIOB->ODR = 0xFFFF;
#define GPIOB_L_DEF() GPIOB->CRL = 0x44838800; /* SDA SCL It1 Po It2 xxx Ai9 Ai8 */
#define GPIOB_H_DEF() GPIOB->CRH = 0x88888888; /* xxx xxx xxx xxx xxx xxx xxx xxx */
//--------------------------------- RCC Clock Config ---------------------------------//
@@ -46,3 +72,4 @@
||+-------Bit22 = 1 USB prescaler is PLL clock
++--------Bits31~27 Reserved*/
/******************************** END OF FILE *********************************/

View File

@@ -1,39 +0,0 @@
/*
* Settings.h
*
* Created on: 29 Sep 2016
* Author: Ralim
*
* Houses the system settings and allows saving / restoring from flash
*/
#ifndef SETTINGS_H_
#define SETTINGS_H_
#include <stdint.h>
#include "stm32f10x_flash.h"
#define SETTINGSVERSION 0x04 /*Change this if you change the struct below to prevent people getting out of sync*/
#define SETTINGSOPTIONSCOUNT 6 /*Number of settings in the settings menu*/
#define MOTION_HIGH (0x00)
#define MOTION_MED (0x10)
#define MOTION_LOW (0x20)
/*
* This struct must be a multiple of 2 bytes as it is saved / restored from flash in uint16_t chunks
*/
struct {
uint32_t SolderingTemp; //current setpoint for the iron
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 cutoutVoltage:5; //The voltage we cutout at for undervoltage
uint8_t movementEnabled:1; //If movement is enabled
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 sensitivity:7; //Sensitivity of accelerometer
uint16_t tempCalibration; //Temperature calibration value
uint16_t voltageDiv; //Voltage divisor factor
} systemSettings;
void saveSettings();
void restoreSettings();
void resetSettings();
#endif /* SETTINGS_H_ */

View File

@@ -0,0 +1,85 @@
/**
******************************************************************************
* @file stm32f10x_conf.h
* @author MCD Application Team
* @version V4.0.0
* @date 21-January-2013
* @brief Library configuration file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F10x_CONF_H
#define __STM32F10x_CONF_H
/* Includes ------------------------------------------------------------------*/
/* Uncomment the line below to enable peripheral header file inclusion */
#include "stm32f10x_adc.h"
#include "stm32f10x_bkp.h"
#include "stm32f10x_can.h"
#include "stm32f10x_crc.h"
#include "stm32f10x_dac.h"
#include "stm32f10x_dbgmcu.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_flash.h"
#include "stm32f10x_fsmc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_i2c.h"
#include "stm32f10x_iwdg.h"
#include "stm32f10x_pwr.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_sdio.h"
#include "stm32f10x_spi.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_wwdg.h"
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */
/* #define USE_FULL_ASSERT 1 */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/*******************************************************************************
* Macro Name : assert_param
* Description : The assert_param macro is used for function's parameters check.
* Input : - expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* Return : None
*******************************************************************************/
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
#endif /* __STM32F10x_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -8,14 +8,12 @@
*/
#include "Analog.h"
//Reads the dc input and returns it as X10 voltage (ie 236 = 23.6V)
//Seems unstable below 9.5V input
uint16_t readDCVoltage(uint16_t divFactor) {
uint16_t readDCVoltage() {
uint16_t reading = 0;
for (u8 i = 0; i < 10; i++) {
reading += ADC_GetConversionValue(ADC2);
}
reading /= divFactor; //take the average and convert to X10 voltage
reading /= 144; //take the average and convert to X10 voltage
return reading; //return the read voltage
}
@@ -104,31 +102,16 @@ uint16_t Get_ADC1Value(uint8_t i) {
return ADC1ConvertedValue[i];
}
//This returns the calibrated temperature reading of the iron temp
//inputs : calibration value / wether to take a new reading or not
uint16_t readIronTemp(uint16_t calibration_temp, uint8_t read,
uint16_t setPointTemp) {
uint16_t readIronTemp(uint16_t calibration_temp, uint8_t read) {
static uint16_t calTemp = 0;
static uint16_t lastVal = 0;
static uint16_t lastSetTemp;
if(setPointTemp!=0xFFFF)
lastSetTemp = setPointTemp;
if (calibration_temp != 0)
calTemp = calibration_temp;
if (read) {
int16_t compensation = 80 + 150 * (lastSetTemp - 1000) / 3000;
int16_t tipTemp = readTipTemp();
int16_t ColdJTemp = readSensorTemp();
if (lastSetTemp == 1000)
compensation -= 10;
if (lastSetTemp != 0) {
if (tipTemp > (compensation + calTemp))
tipTemp -= compensation;
}
if (ColdJTemp > 400)
ColdJTemp = 400;
lastVal = (tipTemp * 1000 + 807 * ColdJTemp - calTemp * 1000) / 807;
lastVal = (readTipTemp() * 1000 + 806 * readSensorTemp()
- calTemp * 1000) / 806;
}

View File

@@ -1,11 +1,11 @@
/*
* Setup all the basic hardware in the system and handle timer3 tick
*/
#include "APP_Version.h"
#include "Bios.h"
#include "I2C.h"
/******************************************************************************/
#define ADC1_DR_Address ((u32)0x4001244C)
volatile uint32_t gHeat_cnt = 0;
@@ -58,6 +58,20 @@ void GPIO_Config(void) {
GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIOA_OUTPUT()
;
GPIOA_L_DEF()
;
GPIOA_H_DEF()
;
GPIOB_OUTPUT()
;
GPIOB_L_DEF()
;
GPIOB_H_DEF()
;
//------ PA7 TMP36 Analog input ----------------------------------------//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

View File

@@ -1,148 +1,229 @@
/*
* I2C.h hardware interface class
* Based on the STM32 app note AN2824
*/
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. **********************
File Name : I2C.c
Version : S100 APP Ver 2.11
Description:
Author : Celery
Data: 2015/07/20
History:
2015/07/07 ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2015/07/21 I2C_DELAYTIME = 2;
*******************************************************************************/
#include "stm32f10x.h"
#include "I2C.h"
#include "Bios.h"
#include "Oled.h"
#include "S100V0_1.h"
/*
* Configure the I2C port hardware
*/
void I2C_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// --------- <20><><EFBFBD><EFBFBD>I2C<32>ӿ<EFBFBD><D3BF><EFBFBD>ض<EFBFBD><D8B6><EFBFBD>-------- //
#define SDA GPIO_Pin_7
#define SCL GPIO_Pin_6
/* PB6,7 SCL and SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
#define HIGH 1
#define LOW 0
/* I2C1 configuration ------------------------------------------------------*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000; //400k
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
#define SDA_VAL GPIO_ReadInputDataBit(GPIOB, SDA)
#define SCL_VAL GPIO_ReadInputDataBit(GPIOB, SCL)
#define I2C_MORE 1
#define I2C_LAST 0
#define I2C_TIMEOUT 255
#define FAILURE 0
#define SUCCEED 1
#define I2C_DELAYTIME 2
static void Sim_I2C_Set(u8 pin, u8 status);
static void Sim_I2C_Stop(void);
static void Sim_I2C_Start(void);
static u8 Sim_I2C_RD_Byte(u8 more);
static u8 Sim_I2C_WR_Byte(u8 data);
/*******************************************************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: Delay_uS
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD>ʱ
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:us
<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>:NULL
*******************************************************************************/
void Delay_uS(u32 us)
{
while(us) us--;
}
/*******************************************************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: I2C_Configuration
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD>I2C
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:NULL
<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>:NULL
*******************************************************************************/
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
GPIO_Init_OLED();
/* PB6,7 SCL and SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* I2C1 configuration ------------------------------------------------------*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = DEVICEADDR_OLED;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000;//100k
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
/*
* Writes a page of data over I2C using the I2C1 peripheral in the stm32
*
*/
void I2C_PageWrite(u8* buf, u8 nbyte, u8 deviceaddr) {
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) {
}
// Intiate Start Sequence
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {
}
// Send Address
I2C_Send7bitAddress(I2C1, deviceaddr << 1, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
}
// Write first byte EV8_1
I2C_SendData(I2C1, *buf++);
while (--nbyte) {
// wait on BTF
while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF)) {
}
I2C_SendData(I2C1, *buf++);
}
while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF)) {
}
I2C_GenerateSTOP(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)) {
}
/*******************************************************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: I2C_Configuration
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD>I2C
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:NULL
<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>:NULL
*******************************************************************************/
void Sim_I2C_Set(u8 pin, u8 status)
{
if(status == HIGH) GPIO_SetBits (GPIOB, pin);
if(status == LOW) GPIO_ResetBits(GPIOB, pin);
}
/*******************************************************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: Sim_I2C_Start
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><>ʼ
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:NULL
<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>:NULL
*******************************************************************************/
void Sim_I2C_Start(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*
* Read Page of data using I2C1 peripheral
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // I2C_PIN_EN();
GPIO_InitStructure.GPIO_Pin = SCL | SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init (GPIOB, &GPIO_InitStructure);
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 (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) {
}
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Current);
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {
}
I2C_Send7bitAddress(I2C1, deviceaddr << 1, I2C_Direction_Receiver);
while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR)) {
}
if (nbyte == 1) {
// Clear Ack bit
I2C_AcknowledgeConfig(I2C1, DISABLE);
// EV6_1 -- must be atomic -- Clear ADDR, generate STOP
__disable_irq();
(void) I2C1->SR2;
I2C_GenerateSTOP(I2C1, ENABLE);
__enable_irq();
// Receive data EV7
while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE)) {
}
*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
__disable_irq();
(void) I2C1->SR2; // Clear ADDR flag
I2C_AcknowledgeConfig(I2C1, DISABLE); // Clear Ack bit
__enable_irq();
// EV7_3 -- Wait for BTF, program stop, read data twice
while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF)) {
}
__disable_irq();
I2C_GenerateSTOP(I2C1, ENABLE);
*buf++ = I2C1->DR;
__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)) {
}
*buf++ = I2C_ReceiveData(I2C1);
}
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)) {
}
*buf++ = I2C_ReceiveData(I2C1);
nbyte = 0;
}
// Wait for stop
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)) {
}
return;
Sim_I2C_Set(SCL, LOW); // SCL low
Sim_I2C_Set(SDA, HIGH); // SDA float, set as output high
Sim_I2C_Set(SCL, HIGH); // SCL high
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SDA, LOW); // SDA high->low while sclk high, S state occur...
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, LOW); // SCL low
}
/*******************************************************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: Sim_I2C_Stop
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ֹͣ
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:NULL
<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>:NULL
*******************************************************************************/
void Sim_I2C_Stop(void)
{
Sim_I2C_Set(SCL, LOW); // SCL low
Sim_I2C_Set(SDA, LOW); // SDA low
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, HIGH); // SCL high
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SDA, HIGH); // SDA low->high while sclk high, P state occur
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, LOW); // SCL low
Delay_uS(I2C_DELAYTIME);
}
/*******************************************************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: Sim_I2C_WR_Byte
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><>I2Cд<43><D0B4>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:dataҪд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>:NULL
*******************************************************************************/
u8 Sim_I2C_WR_Byte(u8 data)
{
u8 i = 8;
while(i--) { //send out a bit by sda line.
Sim_I2C_Set(SCL, LOW); // sclk low
if(data & 0x80) Sim_I2C_Set(SDA, HIGH); // send bit is 1
else Sim_I2C_Set(SDA, LOW); // send bit is 0
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, HIGH); // SCL high
Delay_uS(I2C_DELAYTIME);
data <<=1; // left shift 1 bit, MSB send first.
}
Sim_I2C_Set(SCL, LOW); // SCL low
Sim_I2C_Set(SDA, HIGH); // SDA set as input
for(i=I2C_TIMEOUT; i!=0; i--) { // wait for sda low to receive ack
Delay_uS(I2C_DELAYTIME);
if (!SDA_VAL) {
Sim_I2C_Set(SCL, HIGH); // SCL high
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, LOW); // SCL_LOW();
Delay_uS(I2C_DELAYTIME);
return SUCCEED;
}
}
return FAILURE;
}
/*******************************************************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: Sim_I2C_RD_Byte
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><>I2C<32><43><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:more
<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>:<3A><><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
*******************************************************************************/
u8 Sim_I2C_RD_Byte(u8 more)
{
u8 i = 8, byte = 0;
Sim_I2C_Set(SDA, HIGH); // SDA set as input
while(i--) {
Sim_I2C_Set(SCL, LOW); // SCL low
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, HIGH); // SCL high
Delay_uS(I2C_DELAYTIME);
byte <<=1; //recv a bit
if (SDA_VAL) byte |= 0x01;
}
Sim_I2C_Set(SCL, LOW);
if(!more) Sim_I2C_Set(SDA, HIGH); //last byte, send nack.
else Sim_I2C_Set(SDA, LOW); //send ack
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, HIGH); // SCL_HIGH();
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, LOW);
return byte;
}
/*******************************************************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: I2C_PageWrite
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><> <20><>ַ deviceaddr д<><D0B4>numbyte<74><65><EFBFBD>ֽڵ<D6BD><DAB5><EFBFBD><EFBFBD>ݣ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pbuf
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:pbuf д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>numbyte Ϊд<CEAA><D0B4><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>deviceaddrΪд<CEAA><D0B4>ĵ<EFBFBD>ַ
<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>:NULL
*******************************************************************************/
void I2C_PageWrite(u8* pbuf, u8 numbyte,u8 deviceaddr )
{
Sim_I2C_Start();
Sim_I2C_WR_Byte(deviceaddr<<1);
while(numbyte--) Sim_I2C_WR_Byte(*pbuf++);
Sim_I2C_Stop();
}
/*******************************************************************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: I2C_PageRead
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><>I2C<32><43><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: pbuf <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD>ŵ<EFBFBD>ַ numbyteΪ<65><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
deviceaddr<64><EFBFBD><E8B1B8>ַ readaddr<64><72>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַ
<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>:<3A><><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
*******************************************************************************/
void I2C_PageRead(u8* pbuf, u8 numbyte,u8 deviceaddr, u8 readaddr)
{
Sim_I2C_Start();
Sim_I2C_WR_Byte(deviceaddr<<1);
Sim_I2C_WR_Byte(readaddr);
Sim_I2C_Start();
Sim_I2C_WR_Byte((deviceaddr<<1)|1);
while(numbyte--) {
if(numbyte) *pbuf++ = Sim_I2C_RD_Byte(I2C_MORE);
else *pbuf++ = Sim_I2C_RD_Byte(I2C_LAST);
}
Sim_I2C_Stop();
}
/******************************** END OF FILE *********************************/

View File

@@ -53,7 +53,7 @@ void TIM3_IRQHandler(void) {
//used for buttons and movement
void EXTI9_5_IRQHandler(void) {
//we are interested in line 9 and line 6 for buttons
//Line 5 == movement
//Lien 5 == movement
if (EXTI_GetITStatus(EXTI_Line9) != RESET) {
if (GPIO_ReadInputDataBit(GPIOA, KEY_A) == SET)
keyState &= ~(BUT_A);
@@ -205,4 +205,5 @@ void USB_LP_CAN1_RX0_IRQHandler(void) {
}
/********************************* END OF FILE ******************************/

View File

@@ -20,24 +20,28 @@ void I2C_RegisterWrite(uint8_t reg, uint8_t data) {
tx_data[0] = reg;
tx_data[1] = data;
I2C_PageWrite(tx_data, 2, DEVICE_ADDR);
}
uint8_t I2C_RegisterRead(uint8_t reg) {
u8 tx_data[3];
tx_data[0] = reg;
I2C_PageRead(tx_data, 1, DEVICE_ADDR, reg);
return tx_data[0];
}
void StartUp_Accelerometer(uint8_t sensitivity) {
void StartUp_Acceleromter(void) {
I2C_RegisterWrite(CTRL_REG2, 0); //Normal mode
I2C_RegisterWrite( CTRL_REG2, 0x40); // Reset all registers to POR values
I2C_RegisterWrite( CTRL_REG2, 0x40); // Reset all registers to POR values
delayMs(2); // ~1ms delay
I2C_RegisterWrite(FF_MT_CFG_REG, 0x78); // Enable motion detection for X and Y axis, latch enabled
I2C_RegisterWrite(FF_MT_THS_REG, sensitivity|0x0F); // Set threshold
I2C_RegisterWrite(FF_MT_CFG_REG, 0x78);// Enable motion detection for X and Y axis, latch enabled
I2C_RegisterWrite(FF_MT_THS_REG, 0x0F); // Set threshold
I2C_RegisterWrite(FF_MT_COUNT_REG, 0x01); // Set debounce to 100ms
I2C_RegisterWrite( CTRL_REG4, 0x04); // Enable motion interrupt
I2C_RegisterWrite( CTRL_REG5, 0x04);// Route motion interrupts to INT1 ->PB5 ->EXTI5
I2C_RegisterWrite( CTRL_REG5, 0x04); // Route motion interrupts to INT1 ->PB5 ->EXTI
I2C_RegisterWrite( CTRL_REG1, 0x19); // ODR=100 Hz, Active mode
}

View File

@@ -1,43 +1,53 @@
/*
* Created by Ben V. Brown
*/
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. **********************
File Name : main.c
Version : S100 APP Ver 2.11
Description:
Author : Celery
Data: 2015/07/07
History:
2016/8/11 Updates by Ben V. Brown <ralim@ralimtek.com> - Cleanup and english comments
2015/07/07 ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*******************************************************************************/
#include <string.h>
#include <stdio.h>
#include "APP_Version.h"
#include "Modes.h"
#include "Bios.h"
#include "I2C.h"
#include "MMA8652FC.h"
#include "PID.h"
#include "Oled.h"
#include "Settings.h"
#include "I2C.h"
void setup();
#include "Interrupt.h"
int main(void) {
setup();/*Setup the system*/
RCC_Config(); //setup system clock
//NVIC_Config(0x4000);//this shifts the NVIC table to be offset
NVIC_Config(0x0000);
GPIO_Config(); //setup all the GPIO pins
Init_EXTI();
//Init_Timer2(); //init the timers
Init_Timer3();
I2C_Configuration(); //init the i2c bus
Adc_Init(); //init adc and dma
StartUp_Acceleromter(); //start the accelerometer
Init_Oled(); //init the OLED display
Clear_Screen(); //clear the display buffer to black
systemSettings.SleepTemp = 900;
systemSettings.SleepTime = 1;
systemSettings.SolderingTemp = 1000;
systemSettings.movementEnabled = 1; //we use movement detection
readIronTemp(239, 0); //load the default calibration value
setupPID(); //init the PID values
Start_Watchdog(3000); //start the system watchdog as 3 seconds
while (1) {
Clear_Watchdog(); //reset the Watch dog timer
Clear_Watchdog(); //reset the Watchdog
ProcessUI();
DrawUI();
delayMs(50); //Slow the system down a little bit
delayMs(50);
}
}
void setup() {
RCC_Config(); //setup system clock
NVIC_Config(0x4000); //this shifts the NVIC table to be offset, for the usb bootloader's size
GPIO_Config(); //setup all the GPIO pins
Init_EXTI(); //Init the EXTI inputs
Init_Timer3(); //Used for the soldering iron tip
Adc_Init(); //Init adc and DMA
I2C_Configuration(); //Start the I2C hardware
GPIO_Init_OLED(); //Init the GPIO ports for the OLED
restoreSettings(); //Load settings
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
OLED_DrawString("VER 1.06", 8); //
delayMs(800); //Pause to show version number
Start_Watchdog(1000); //start the system watch dog as 1 second timeout
}
/******************************** END OF FILE *********************************/

View File

@@ -5,41 +5,45 @@
* Author: Ralim <ralim@ralimtek.com>
*/
#include "Modes.h"
uint8_t CalStatus = 0;
//This does the required processing and state changes
void ProcessUI() {
uint8_t Buttons = getButtons(); //read the buttons status
static uint32_t lastModeChange = 0;
if (millis() - getLastButtonPress() < 30)
Buttons = 0;
else if (Buttons != 0) {
resetLastButtonPress();
resetButtons();
}
//rough prevention for de-bouncing and allocates settling time
if (millis() - getLastButtonPress() < 200)
Buttons = 0;
//rough prevention for debouncing and allocates settling time
//OLED_DrawThreeNumber(Buttons, 0);
switch (operatingMode) {
case STARTUP:
if (Buttons == (BUT_A | BUT_B)) {
operatingMode = THERMOMETER;
} else if (Buttons == BUT_A) {
//A key pressed so we are moving to soldering mode
operatingMode = SOLDERING;
} else if (Buttons == BUT_B) {
//B Button was pressed so we are moving to the Settings menu
operatingMode = SETTINGS;
if ((millis() - getLastButtonPress() > 1000)) {
if (Buttons & BUT_A) {
//A key pressed so we are moving to soldering mode
operatingMode = SOLDERING;
delayMs(500);
resetLastButtonPress();
resetButtons();
} else if (Buttons & BUT_B) {
//B Button was pressed so we are moving to the Settings menu
operatingMode = SETTINGS;
delayMs(500);
resetLastButtonPress();
resetButtons();
}
}
//Nothing else to check here
break;
case SOLDERING:
//We need to check the buttons if we need to jump out
if (Buttons == BUT_A || Buttons == BUT_B) {
//A or B key pressed so we are moving to temp set
if (Buttons & BUT_A) {
//A key pressed so we are moving to temp set
operatingMode = TEMP_ADJ;
} else if (Buttons == (BUT_A | BUT_B)) {
//Both buttons were pressed, exit back to the cooling screen
operatingMode = COOLING;
resetLastButtonPress();
resetButtons();
} else if (Buttons & BUT_B) {
//B Button was pressed so we are moving back to idle
operatingMode = STARTUP;
resetLastButtonPress();
resetButtons();
} else {
//We need to check the timer for movement in case we need to goto idle
if (systemSettings.movementEnabled)
@@ -51,59 +55,59 @@ void ProcessUI() {
return;
}
}
uint16_t voltage = readDCVoltage(systemSettings.voltageDiv); //get X10 voltage
if ((voltage / 10) < systemSettings.cutoutVoltage) {
operatingMode = UVLOWARN;
lastModeChange = millis();
}
//Update the PID Loop
//If no buttons pushed we need to perform the PID loop for the iron temp
int32_t newOutput = computePID(systemSettings.SolderingTemp);
setIronTimer(newOutput);
if (newOutput >= 0) {
setIronTimer(newOutput);
}
}
break;
case TEMP_ADJ:
if (Buttons == BUT_A) {
if (Buttons & BUT_A) {
//A key pressed so we are moving down in temp
resetLastButtonPress();
if (systemSettings.SolderingTemp > 1000)
systemSettings.SolderingTemp -= 100;
} else if (Buttons == BUT_B) {
} else if (Buttons & BUT_B) {
//B key pressed so we are moving up in temp
resetLastButtonPress();
if (systemSettings.SolderingTemp < 4500)
systemSettings.SolderingTemp += 100;
} else {
//we check the timeout for how long the buttons have not been pushed
//if idle for > 3 seconds then we return to soldering
//Or if both buttons pressed
if ((millis() - getLastButtonPress() > 2000)
|| Buttons == (BUT_A | BUT_B)) {
if (millis() - getLastButtonPress() > 3000)
operatingMode = SOLDERING;
saveSettings();
}
}
break;
case SETTINGS:
//Settings is the mode with the most logic
//Here we are in the menu so we need to increment through the sub menus / increase the value
if (millis() - getLastButtonPress() < 400)
return;
if (Buttons & BUT_A) {
resetLastButtonPress();
//A key iterates through the menu
if (settingsPage == SETTINGSOPTIONSCOUNT) {
if (settingsPage == 2) {
//Roll off the end
settingsPage = 0; //reset
operatingMode = STARTUP; //reset back to the startup
saveSettings(); //Save the settings
settingsPage = 0; //reset
operatingMode = STARTUP;
//TODO Save settings
} else
++settingsPage; //move to the next option
++settingsPage; //move to the next option
} else if (Buttons & BUT_B) {
resetLastButtonPress();
//B changes the value selected
switch (settingsPage) {
case UVCO:
case UVLO:
//we are incrementing the cutout voltage
systemSettings.cutoutVoltage += 1; //Go up 1V at a jump
if (systemSettings.cutoutVoltage > 24)
systemSettings.cutoutVoltage = 10;
systemSettings.cutoutVoltage = 9;
else if (systemSettings.cutoutVoltage < 9)
systemSettings.cutoutVoltage = 9; //cant set UVLO below 9V
break;
case SLEEP_TEMP:
systemSettings.SleepTemp += 100; //Go up 10c at a time
@@ -112,25 +116,9 @@ void ProcessUI() {
break;
case SLEEP_TIME:
++systemSettings.SleepTime; //Go up 1 minute at a time
if (systemSettings.SleepTime > 30)
systemSettings.SleepTime = 1; //cant set time over 30 mins
if (systemSettings.SleepTime > 60)
systemSettings.SleepTime = 2; //cant set time over an hour
//Remember that ^ is the time of no movement
break;
case MOTIONDETECT:
systemSettings.movementEnabled =
!systemSettings.movementEnabled;
break;
case TEMPDISPLAY:
systemSettings.displayTempInF = !systemSettings.displayTempInF;
break;
case LEFTY:
systemSettings.flipDisplay = !systemSettings.flipDisplay;
break;
case MOTIONSENSITIVITY:
systemSettings.sensitivity += 0x10;
if (systemSettings.sensitivity > 0x20)
systemSettings.sensitivity = 0; //reset to high on wrap
break;
default:
break;
@@ -142,10 +130,14 @@ void ProcessUI() {
if (Buttons & BUT_A) {
//A Button was pressed so we are moving back to soldering
operatingMode = SOLDERING;
resetLastButtonPress();
resetButtons();
return;
} else if (Buttons & BUT_B) {
//B Button was pressed so we are moving back to soldering
operatingMode = SOLDERING;
resetLastButtonPress();
resetButtons();
return;
} else if (systemSettings.movementEnabled)
if (millis() - getLastMovement() < 1000) {//moved in the last second
@@ -154,123 +146,16 @@ void ProcessUI() {
}
//else if nothing has been pushed we need to compute the PID to keep the iron at the sleep temp
int32_t newOutput = computePID(systemSettings.SleepTemp);
setIronTimer(newOutput);
break;
case COOLING: {
setIronTimer(0); //turn off heating
//This mode warns the user the iron is still cooling down
uint16_t temp = readIronTemp(0, 1, 0xFFFF); //take a new reading as the heater code is not taking new readings
if (temp < 400) { //if the temp is < 40C then we can go back to IDLE
operatingMode = STARTUP;
} else if (Buttons & (BUT_A | BUT_B)) { //we check if the user has pushed a button to ack
//Either button was pushed
operatingMode = STARTUP;
if (newOutput >= 0) {
setIronTimer(newOutput);
}
}
break;
case UVLOWARN:
//We are here if the DC voltage went too low
//We want to jump back to IDLE after a bit
if (millis() - lastModeChange > 3000) { //its been 3 seconds
operatingMode = STARTUP; //jump back to idle mode
}
break;
case THERMOMETER: {
//This lets the user check the tip temp without heating the iron.. And eventually calibration will be added here
if (Buttons == BUT_A) {
//Single button press, cycle over to the DC display
CalStatus = 0;
operatingMode = DCINDISP;
} else if (Buttons == BUT_B) {
CalStatus = 0;
operatingMode = TEMPCAL;
} else if (Buttons == (BUT_A | BUT_B)) {
//If the user is holding both button, exit the screen
operatingMode = STARTUP;
}
}
break;
case DCINDISP: {
//This lets the user check the input voltage
if (CalStatus == 0) {
if (Buttons == BUT_A) {
//Single button press, cycle over to the temp display
operatingMode = THERMOMETER;
} else if (Buttons == BUT_B) {
//dc cal mode
CalStatus = 1;
} else if (Buttons == (BUT_A | BUT_B)) {
//If the user is holding both button, exit the screen
operatingMode = STARTUP;
}
} else {
//User is calibrating the dc input
if (Buttons == BUT_A) {
if (!systemSettings.flipDisplay)
systemSettings.voltageDiv++;
else
systemSettings.voltageDiv--;
} else if (Buttons == BUT_B) {
if (!systemSettings.flipDisplay)
systemSettings.voltageDiv--;
else
systemSettings.voltageDiv++;
} else if (Buttons == (BUT_A | BUT_B)) {
CalStatus = 0;
saveSettings();
}
if (systemSettings.voltageDiv < 120)
systemSettings.voltageDiv = 160;
else if (systemSettings.voltageDiv > 160)
systemSettings.voltageDiv = 120;
}
}
break;
case TEMPCAL: {
if (Buttons == BUT_B) {
//Single button press, cycle over to the DC IN
operatingMode = THERMOMETER;
} else if (Buttons == BUT_A) {
//Try and calibrate
if (CalStatus == 0) {
if ((readTipTemp() < 300) && (readSensorTemp() < 300)) {
CalStatus = 1;
systemSettings.tempCalibration = readTipTemp();
saveSettings();
} else {
CalStatus = 2;
}
}
} else if (Buttons == (BUT_A | BUT_B)) {
//If the user is holding both button, exit the screen
operatingMode = STARTUP;
}
}
break;
default:
break;
}
}
/*
* Draws the temp with temp conversion if needed
*/
void drawTemp(uint16_t temp, uint8_t x) {
if (systemSettings.displayTempInF)
temp = (temp * 9 + 1600) / 5;/*Convert to F -> T*(9/5)+32*/
if (temp % 10 > 5)
temp += 10; //round up
OLED_DrawThreeNumber(temp / 10, x);
}
/*
* Performs all the OLED drawing for the current operating mode
*/
void DrawUI() {
uint16_t temp = readIronTemp(0, 0, 0xFFFF);
switch (operatingMode) {
case STARTUP:
//We are chilling in the idle mode
@@ -281,97 +166,58 @@ void DrawUI() {
Oled_DisplayOff();
} else {
Oled_DisplayOn();
OLED_DrawIDLELogo(); //Draw the icons for prompting the user
OLED_DrawString("IDLE ", 7); //write the word IDLE
}
break;
case SOLDERING:
//The user is soldering
{
drawTemp(temp, 0);
OLED_DrawChar(' ', 3);
OLED_BlankSlot(6 * 12 + 16, 24 - 16);//blank out the tail after the arrows
OLED_BlankSlot(4 * 12 + 16, 24 - 16);//blank out the tail after the temp
if (getIronTimer() == 0) {
OLED_DrawSymbol(6, 5);
uint16_t temp = readIronTemp(0, 0);
if (systemSettings.SolderingTemp + 2 < temp) {
OLED_DrawChar('C', 14 * 4);
} else {
if (getIronTimer() < 900) {
OLED_DrawSymbol(6, 7);
if (getIronTimer() < 500) {
OLED_DrawChar(' ', 14 * 4);
} else { //we are heating
//OLED_DrawChar('H', 5);
OLED_DrawSymbol(6, 6);
OLED_DrawChar('H', 14 * 4);
}
}
if (systemSettings.displayTempInF) {
OLED_DrawSymbol(4, 1);
} else {
OLED_DrawSymbol(4, 0);
}
OLED_DrawThreeNumber(temp / 10, 0);
OLED_DrawChar(' ', 14 * 3);
OLED_DrawChar(' ', 14 * 5);
OLED_DrawChar(' ', 14 * 6);
}
break;
case TEMP_ADJ:
//We are prompting the user to change the temp so we draw the current setpoint temp
//With the nifty arrows
OLED_DrawChar(' ', 0);
OLED_DrawChar('<', 1);
drawTemp(systemSettings.SolderingTemp, 2);
OLED_DrawChar(' ', 5);
OLED_DrawChar(' ', 7);
OLED_DrawChar('>', 6);
OLED_DrawThreeNumber(systemSettings.SolderingTemp / 10, 14 * 1);
OLED_DrawChar(' ', 14 * 4);
OLED_DrawChar(' ', 14 * 5);
break;
case SETTINGS:
//We are prompting the user the setting name
switch (settingsPage) {
case UVCO:
OLED_DrawString("UVCO ", 5);
OLED_DrawTwoNumber(systemSettings.cutoutVoltage, 5);
OLED_DrawChar('V', 7);
case UVLO:
OLED_DrawString("UVLO", 4);
OLED_DrawTwoNumber(systemSettings.cutoutVoltage, 14 * 4);
//OLED_DrawChar('V', 14 * 5);
break;
case SLEEP_TEMP:
OLED_DrawString("STMP ", 5);
OLED_DrawThreeNumber(systemSettings.SleepTemp / 10, 5);
OLED_DrawString("STMP", 4);
OLED_DrawThreeNumber(systemSettings.SleepTemp / 10, 14 * 4);
//OLED_DrawChar('V', 14 * 5);
break;
case SLEEP_TIME:
OLED_DrawString("STIME ", 6);
OLED_DrawTwoNumber(systemSettings.SleepTime, 6);
break;
case MOTIONDETECT:/*Toggle the mode*/
if (systemSettings.movementEnabled)
OLED_DrawString("MOTION T", 8);
else
OLED_DrawString("MOTION F", 8);
break;
case TEMPDISPLAY:/*Are we showing in C or F ?*/
if (systemSettings.displayTempInF)
OLED_DrawString("TMPUNT F", 8);
else
OLED_DrawString("TMPUNT C", 8);
break;
case LEFTY:
if (systemSettings.flipDisplay)
OLED_DrawString("FLPDSP T", 8);
else
OLED_DrawString("FLPDSP F", 8);
break;
case MOTIONSENSITIVITY:
switch (systemSettings.sensitivity) {
case MOTION_HIGH:
OLED_DrawString("SENSE H ", 8);
break;
case MOTION_MED:
OLED_DrawString("SENSE M ", 8);
break;
case MOTION_LOW:
OLED_DrawString("SENSE L ", 8);
break;
default:
OLED_DrawString("SENSE ", 8);
break;
}
OLED_DrawString("STME ", 5);
OLED_DrawTwoNumber(systemSettings.SleepTime, 14 * 5);
break;
default:
break;
@@ -381,49 +227,8 @@ void DrawUI() {
//The iron is in sleep temp mode
//Draw in temp and sleep
OLED_DrawString("SLP", 3);
drawTemp(temp, 4);
break;
case COOLING:
//We are warning the user the tip is cooling
OLED_DrawString("COOL ", 5);
drawTemp(temp, 5);
break;
case UVLOWARN:
OLED_DrawString("LOW VOLT", 8);
break;
case THERMOMETER:
temp = readIronTemp(0, 1, 0xFFFF); //Force a reading as heater is off
OLED_DrawString("TEMP ", 5);//extra one to it clears the leftover 'L' from IDLE
drawTemp(temp, 5);
break;
case DCINDISP: {
uint16_t voltage = readDCVoltage(systemSettings.voltageDiv); //get X10 voltage
if (CalStatus == 0 || ((millis() % 1000) > 500)) {
OLED_DrawString("IN", 2);
OLED_DrawChar((voltage / 100) % 10, 2);
voltage -= (voltage / 100) * 100;
OLED_DrawChar((voltage / 10) % 10, 3);
voltage -= (voltage / 10) * 10;
OLED_DrawChar('.', 4);
OLED_DrawChar(voltage % 10, 5);
OLED_DrawChar('V', 6);
OLED_DrawChar(' ', 7);
} else {
OLED_DrawString("IN ", 8);
}
}
break;
case TEMPCAL: {
if (CalStatus == 0) {
OLED_DrawString("CAL TEMP", 8);
} else if (CalStatus == 1) {
OLED_DrawString("CAL OK ", 8);
} else if (CalStatus == 2) {
OLED_DrawString("CAL FAIL", 8);
}
}
uint16_t temp = readIronTemp(0, 0);
OLED_DrawThreeNumber(temp / 10, 14 * 3);
break;
default:

View File

@@ -1,92 +1,71 @@
/*
*
* OLED.c
* Functions for working with the oled screen.
* Writes to the screen using I2C
*/
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. **********************
File Name : Oled.c
Version : S100 APP Ver 2.11
Description:
Author : Celery
Data: 2015/07/07
History:
2015/07/07 ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*******************************************************************************/
#include <stdio.h>
#include <string.h>
#include "APP_Version.h"
#include "Oled.h"
#include "Bios.h"
#include "I2C.h"
#include "Font.h"
int8_t displayOffset = 32;
/*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*/
0x80, 0xD5,/*Set display clock divide ratio / osc freq*/
0x80, 0x52,/*Unknown*/
0x80, 0xA8,/*Set Multiplex Ratio*/
0x80, 0x0F, /*16 == max brightness,39==dimmest*/
0x80, 0xC0,/*Set COM Scan direction*/
0x80, 0xD3,/*Set Display offset*/
0x80, 0x00,/*0 Offset*/
0x80, 0x40,/*Set Display start line to 0*/
0x80, 0xA0,/*Set Segment remap to normal*/
0x80, 0x8D,/*Unknown*/
0x80, 0x14,/*Unknown*/
0x80, 0xDA,/*Set VCOM Pins hardware config*/
0x80, 0x02,/*Combination 2*/
0x80, 0x81,/*Contrast*/
0x80, 0x33,/*51*/
0x80, 0xD9,/*Set pre-charge period*/
0x80, 0xF1,/**/
0x80, 0xDB,/*Adjust VCOMH regulator ouput*/
0x80, 0x30,/*Unknown*/
0x80, 0xA4,/*Enable the display GDDR*/
0x80, 0XA6,/*Normal display*/
0x80, 0xAF /*Dispaly on*/
};
/*
u8 gOled_param[46] = { 0x80, 0xAE, 0x80, 0xD5, 0x80, 0x52, 0x80, 0xA8, 0x80,
0x0f, 0x80, 0xC0, 0x80, 0xD3, 0x80, 0x00, 0x80, 0x40, 0x80, 0xA0, 0x80,
0x8D, 0x80, 0x14, 0x80, 0xDA, 0x80, 0x02, 0x80, 0x81, 0x80, 0x33, 0x80,
0xD9, 0x80, 0xF1, 0x80, 0xDB, 0x80, 0x30, 0x80, 0xA4, 0x80, 0XA6, 0x80,
0xAF };
/*******************************************************************************
*******************************************************************************/
void Sc_Pt(u8 Co) {
u8 pt[4] = { 0x80, 0x81, 0x80, Co };
I2C_PageWrite(pt, 4, DEVICEADDR_OLED);
}
/*******************************************************************************
Function: Oled_DisplayOn
Description:Turn on the Oled display
*/
*******************************************************************************/
void Oled_DisplayOn(void) {
u8 data[6] = { 0x80, 0X8D, 0x80, 0X14, 0x80, 0XAF };
I2C_PageWrite(data, 6, DEVICEADDR_OLED);
}
/*
/*******************************************************************************
Function: Oled_DisplayOff
Description:Turn off the Oled display
*/
*******************************************************************************/
void Oled_DisplayOff(void) {
u8 data[6] = { 0x80, 0X8D, 0x80, 0X10, 0x80, 0XAE };
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;
}
/*
/*******************************************************************************
Function: Data_Command
Description: write a command to the Oled display
Input: number of bytes to write, array to write
Output:
*/
u8* Data_Command(u8 length, u8* data) {
*******************************************************************************/
u8* Data_Command(u8 wide, u8* ptr) {
int i;
u8 tx_data[129];
u8 tx_data[128];
//here are are inserting the data write command at the beginning
tx_data[0] = 0x40;
length++;
for (i = 1; i < length; i++) //Loop through the array of data
tx_data[i] = *data++;
I2C_PageWrite(tx_data, length, DEVICEADDR_OLED); //write out the buffer
return data;
wide += 1;
for (i = 1; i < wide; i++) //Loop through the array of data
tx_data[i] = *ptr++;
I2C_PageWrite(tx_data, wide, DEVICEADDR_OLED); //write out the buffer
return ptr;
}
/*******************************************************************************
Function:Set_ShowPos
@@ -94,10 +73,11 @@ u8* Data_Command(u8 length, u8* data) {
Input:x,y co-ordinates
*******************************************************************************/
void Set_ShowPos(u8 x, u8 y) {
u8 pos_param[8] = { 0x80, 0xB0, 0x80, 0x21, 0x80, 0x00, 0x80, 0x7F };
//page 0, start add = x(below) through to 0x7F (aka 127)
pos_param[5] = x + displayOffset;/*Display offset ==0 for Lefty, == 32 for righty*/
u8 pos_param[8] = { 0x80, 0xB0, 0x80, 0x21, 0x80, 0x20, 0x80, 0x7F };
pos_param[5] = x + 32;
pos_param[1] += y;
I2C_PageWrite(pos_param, 8, DEVICEADDR_OLED);
}
@@ -105,7 +85,7 @@ void Set_ShowPos(u8 x, u8 y) {
Function:Oled_DrawArea
Description:
Inputs:(x,y) start point, (width,height) of enclosing rect, pointer to data
Output: pointer to the last byte written out
Output: last byte written out
*******************************************************************************/
u8* Oled_DrawArea(u8 x0, u8 y0, u8 wide, u8 high, u8* ptr) {
u8 m, n, y;
@@ -128,6 +108,20 @@ u8* Oled_DrawArea(u8 x0, u8 y0, u8 wide, u8 high, u8* ptr) {
return ptr;
}
/*******************************************************************************
Function:Clean_Char
Description:Overwries a square to off, used to overwrite a char
Inputs:(k) input X position char starts at, (wide) how many pixels wide the char is
*******************************************************************************/
void Clean_Char(int k, u8 wide) {
int i;
u8 tx_data[128];
memset(&tx_data[0], 0, wide);
for (i = 0; i < 2; i++) {
Oled_DrawArea(k, i * 8, wide, 8, tx_data);
}
}
/*******************************************************************************
Function:GPIO_Init_OLED
Description:Init the outputs as needed for the OLED (in this case the RST line)
@@ -142,22 +136,17 @@ void GPIO_Init_OLED(void) {
}
/*******************************************************************************
Function: Init_Oled
Description: Initializes the Oled screen
Description: Initalizes the Oled screen
*******************************************************************************/
void Init_Oled(uint8_t leftHanded) {
void Init_Oled(void) {
u8 param_len;
OLED_RST();
delayMs(5);
OLED_ACT(); //Toggling reset to reset the oled
delayMs(5);
delayMs(2); //reset the oled
OLED_ACT();
delayMs(2);
param_len = 46;
if (leftHanded) {
OLED_Setup_Array[11] = 0xC8;
OLED_Setup_Array[19] = 0xA1;
displayOffset = 0;
}
I2C_PageWrite((u8 *) OLED_Setup_Array, param_len, DEVICEADDR_OLED);
I2C_PageWrite((u8 *) gOled_param, param_len, DEVICEADDR_OLED);
}
/*******************************************************************************
@@ -166,103 +155,54 @@ void Init_Oled(uint8_t leftHanded) {
*******************************************************************************/
void Clear_Screen(void) {
u8 tx_data[128];
memset(tx_data, 0, 128);
memset(&tx_data[0], 0, 128);
for (u8 i = 0; i < 2; i++) {
Oled_DrawArea(0, i * 8, 128, 8, tx_data);
}
}
/*
* Draws a string onto the screen starting at the left
*/
void OLED_DrawString(char* string, uint8_t length) {
for (uint8_t i = 0; i < length; i++) {
OLED_DrawChar(string[i], i);
OLED_DrawChar(string[i], i * 14);
}
}
/*
* Draw a char onscreen at letter index x
*/
void OLED_DrawChar(char c, uint8_t x) {
if (x > 7)
return; //clipping
x *= FONT_WIDTH; //convert to a x coordinate
u8* ptr = (u8*) FONT;
if ((x) > (128 - 14))
return; //Rudimentary clipping to not draw off screen
u8* ptr;
ptr = (u8*) FONT;
if (c >= 'A' && c <= 'Z') {
ptr += (c - 'A' + 10) * (FONT_WIDTH * 2); //alpha is ofset 10 chars into the array
ptr += (c - 'A' + 10) * (14 * 2); //alpha is ofset 10 chars into the array
} else if (c >= '0' && c <= '9')
ptr += (c - '0') * (FONT_WIDTH * 2);
ptr += (c - '0') * (14 * 2);
else if (c < 10)
ptr += (c) * (FONT_WIDTH * 2);
ptr += (c) * (14 * 2);
else if (c == ' ') {
//blank on space bar
ptr += (36) * (FONT_WIDTH * 2);
} else if (c == '<') {
ptr += (37) * (FONT_WIDTH * 2);
} else if (c == '>') {
ptr += (38) * (FONT_WIDTH * 2);
} else if (c == '.') {
ptr += (39) * (FONT_WIDTH * 2);
ptr += (36) * (14 * 2);
}
Oled_DrawArea(x, 0, FONT_WIDTH, 16, (u8*) ptr);
Oled_DrawArea(x, 0, 14, 16, (u8*) ptr);
}
void OLED_BlankSlot(uint8_t xStart, uint8_t width) {
u8* ptr = (u8*) FONT;
ptr += (36) * (FONT_WIDTH * 2);
Oled_DrawArea(xStart, 0, width, 16, (u8*) ptr);
}
/*
* Draw a 2 digit number to the display at letter slot x
*/
* Draw a 2 digit number to the display
* */
void OLED_DrawTwoNumber(uint8_t in, uint8_t x) {
OLED_DrawChar((in / 10) % 10, x);
OLED_DrawChar(in % 10, x + 1);
OLED_DrawChar((in / 10)%10, x);
OLED_DrawChar(in % 10, x + 14);
}
/*
* Draw a 3 digit number to the display at letter slot x
*/
void OLED_DrawThreeNumber(uint16_t in, uint8_t x) {
OLED_DrawChar((in / 100) % 10, x);
OLED_DrawChar((in / 10) % 10, x + 1);
OLED_DrawChar(in % 10, x + 2);
OLED_DrawChar((in / 100)%10, x);
OLED_DrawChar((in / 10)%10, x + 14);
OLED_DrawChar(in % 10, x + 28);
}
/*
* Draw a 4 digit number to the display at letter slot x
*/
void OLED_DrawFourNumber(uint16_t in, uint8_t x) {
OLED_DrawChar((in / 1000) % 10, x);
OLED_DrawChar((in / 100) % 10, x + 1);
OLED_DrawChar((in / 10) % 10, x + 2);
OLED_DrawChar(in % 10, x + 3);
OLED_DrawChar((in / 1000)%10, x);
OLED_DrawChar((in / 100)%10, x+14);
OLED_DrawChar((in / 10)%10, x + 28);
OLED_DrawChar(in % 10, x + 32);
}
void OLED_DrawIDLELogo() {
static uint8_t drawAttempt = 0;
drawAttempt++;
if (drawAttempt & 0x80) {
if (drawAttempt & 0x08)
Oled_DrawArea(0, 0, 96, 8, (u8*) Iron_RightArrow_UP);
else
Oled_DrawArea(0, 0, 96, 8, (u8*) Iron_RightArrow_DOWN);
/******************************** END OF FILE *********************************/
Oled_DrawArea(0, 8, 96, 8, (u8*) Iron_Base);
} else {
if (drawAttempt & 0x08)
Oled_DrawArea(0, 0, 96, 8, (u8*) Iron_LeftArrow_UP);
else
Oled_DrawArea(0, 0, 96, 8, (u8*) Iron_LeftArrow_DOWN);
Oled_DrawArea(0, 8, 96, 8, (u8*) Iron_Base);
}
}
void OLED_DrawSymbol(uint8_t x, uint8_t symbol) {
Oled_DrawArea(x * FONT_WIDTH, 0, 16, 16, SymbolTable + (symbol * 32));
}

View File

@@ -6,35 +6,39 @@
*/
#include "PID.h"
#define MAXPIDOUTPUT 50000
//This function computes the new value for the ON time of the system
#define MAXPIDOUTPUT 500000
//This funtion computes the new value for the ON time of the system
//This is the return value from this function
int32_t computePID(uint16_t setpoint) {
int32_t ITerm = 0;
static uint32_t lastSample = 0;
int32_t ITerm = 0;
static int16_t lastReading = 0;
uint16_t currentReading = readIronTemp(0, 1,setpoint); //get the current temp of the iron
int16_t error = (int16_t) setpoint - (int16_t) currentReading; //calculate the error term
ITerm += (pidSettings.ki * error);
if (ITerm > MAXPIDOUTPUT)
ITerm = MAXPIDOUTPUT;
else if (ITerm < 0)
ITerm = 0; //cap at 0 since we cant force the iron to cool itself :)
int16_t DInput = (currentReading - lastReading); //compute the input to the D term
int32_t output = (pidSettings.kp * error) + (ITerm)
- (pidSettings.kd * DInput);
if (output > MAXPIDOUTPUT)
output = MAXPIDOUTPUT;
else if (output < 0)
output = 0;
lastReading = currentReading; //storing values for next iteration of the loop
return output;
if (millis() - lastSample > 25) {
//only sample every 50 milliseconds
uint16_t currentReading = readIronTemp(0,1); //get the current temp of the iron
int16_t error = (int16_t)setpoint - (int16_t)currentReading; //calculate the error term
ITerm += (pidSettings.ki * error);
if (ITerm > MAXPIDOUTPUT)
ITerm = MAXPIDOUTPUT;
else if (ITerm < 0)
ITerm = 0; //cap at 0 since we cant force the iron to cool itself :)
int16_t DInput = (currentReading - lastReading); //compute the input to the D term
int32_t output = (pidSettings.kp * error) + (ITerm)
- (pidSettings.kd * DInput);
if (output > MAXPIDOUTPUT)
output = MAXPIDOUTPUT;
else if (output < 0)
output = 0;
lastSample = millis();
lastReading = currentReading; //storing values for next iteration of the loop
return output;
}
return -1; //called too fast
}
/*Sets up the pid values*/
void setupPID(void) {
pidSettings.kp = 25;
pidSettings.kp = 22;
pidSettings.ki = 7;
pidSettings.kd = 2;

View File

@@ -1,56 +0,0 @@
/*
* Settings.c
*
* Created on: 29 Sep 2016
* Author: Ralim
*
* This file holds the users settings and saves / restores them to the devices flash
*/
#include "Settings.h"
#define FLASH_ADDR (0x8000000|48896)/*Flash start OR'ed with the maximum amount of flash - 256 bytes*/
void saveSettings() {
//First we erase the flash
FLASH_Unlock(); //unlock flash writing
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
while (FLASH_ErasePage(FLASH_ADDR) != FLASH_COMPLETE)
; //wait for it
//erased the chunk
//now we program it
uint16_t *data = (uint16_t*) &systemSettings;
for (uint8_t i = 0; i < (sizeof(systemSettings) / 2); i++) {
FLASH_ProgramHalfWord(FLASH_ADDR + (i * 2), data[i]);
}
}
void restoreSettings() {
//We read the flash
uint16_t *data = (uint16_t*) &systemSettings;
for (uint8_t i = 0; i < (sizeof(systemSettings) / 2); i++) {
data[i] = *(uint16_t *) (FLASH_ADDR + (i * 2));
}
//if the version is correct were done
//if not we reset and save
if (systemSettings.version != SETTINGSVERSION) {
//probably not setup
resetSettings();
saveSettings();
}
}
void resetSettings() {
systemSettings.SleepTemp = 1500; //Temperature the iron sleeps at - default 150.0 C
systemSettings.SleepTime = 1; //How many minutes we wait until going to sleep - default 1 min
systemSettings.SolderingTemp = 3200; //Default soldering temp is 320.0 C
systemSettings.movementEnabled = 1; //we use movement detection by default
systemSettings.cutoutVoltage = 10; //10V is the minium cutout voltage as the unit V measurement is unstable below 9.5V
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.sensitivity=0x00; //Default high sensitivity
systemSettings.tempCalibration=239; //Default to their calibration value
systemSettings.voltageDiv=144; //Default divider from schematic
}