Changeset - 255811a3e69c
[Not reviewed]
default
0 1 0
Ethan Zonca - 10 years ago 2014-08-23 22:28:17
ez@ethanzonca.com
Get fractional part
1 file changed with 6 insertions and 0 deletions:
main.c
6
0 comments (0 inline, 0 general)
main.c
Show inline comments
 
#include "main.h"
 
#include "stm32l100c_discovery.h"
 
#include "ssd1306.h"
 
 
// USB includes
 
#include "hw_config.h"
 
#include "usb_lib.h"
 
#include "usb_desc.h"
 
#include "usb_pwr.h"
 
 
#define LED_POWER GPIOB,GPIO_Pin_9
 
#define LED_STAT  GPIOA,GPIO_Pin_15
 
 
#define MAX_CS GPIOB,GPIO_Pin_12
 
 
// TODO: Grab buttonpresses with interrupts
 
#define SW_BTN  GPIOB, GPIO_Pin_3
 
#define SW_UP   GPIOB, GPIO_Pin_7
 
#define SW_DOWN GPIOB, GPIO_Pin_6
 
#define SW_LEFT GPIOB, GPIO_Pin_5
 
#define SW_RIGHT GPIOB, GPIO_Pin_4
 
 
// USB Supporting Vars
 
extern __IO uint8_t Receive_Buffer[64];
 
extern __IO  uint32_t Receive_length ;
 
extern __IO  uint32_t length ;
 
uint8_t Send_Buffer[64];
 
uint32_t packet_sent=1;
 
uint32_t packet_receive=1;
 
 
 
char* itoa(int16_t i, char b[]){
 
    char const digit[] = "0123456789";
 
    char* p = b;
 
    if(i<0){
 
        *p++ = '-';
 
        i *= -1;
 
    }
 
    uint16_t shifter = i;
 
    do{ //Move to where representation ends
 
        ++p;
 
        shifter = shifter/10;
 
    }while(shifter);
 
    *p = '\0';
 
    do{ //Move back, inserting digits as you go
 
        *--p = digit[i%10];
 
        i = i/10;
 
    }while(i);
 
    return b;
 
}
 
 
 
int32_t round(double x) {
 
    if (x >= 0)
 
        return (long) (x+0.5);
 
    return (long) (x-0.5);
 
}
 
 
static __IO uint32_t TimingDelay;
 
 
// Move to header file
 
void init_gpio();
 
void init_spi();
 
void process();
 
void machine();
 
 
int main(void)
 
{
 
 
    // Init clocks
 
    SystemInit();
 
 
    init_gpio();
 
 
    // Init USB
 
    //Set_USBClock();
 
    //USB_Interrupts_Config();
 
    //USB_Init();
 
 
    GPIO_SetBits(LED_POWER);
 
 
    RCC_ClocksTypeDef RCC_Clocks;
 
 
    // SysTick end of count event each 1ms
 
    RCC_GetClocksFreq(&RCC_Clocks);
 
    SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
 
 
    GPIO_ResetBits(LED_STAT);
 
    Delay(100);
 
    GPIO_SetBits(LED_POWER);
 
    Delay(500);
 
    GPIO_ResetBits(LED_POWER);
 
 
    init_spi();
 
 
    ssd1306_Init();
 
    ssd1306_block_write();
 
    ssd1306_DrawString("therm 0.1", 0, 40);
 
    ssd1306_DrawString("Status: Idle", 2, 40);
 
  //  ssd1306_block_write();
 
    ssd1306_test();
 
 
    uint8_t toggle = 0;
 
 
    int16_t temp = -231;
 
 
    while(1)
 
    {
 
        //ssd1306_block_write();
 
 
        // Process sensor inputs [TODO: 5hz?]
 
        process();
 
 
        // Run state machine [TODO: 50hz?]
 
        machine(); 
 
        // probably just passed the actual port
 
 
        // TODO: Grab buttonpresses with interrupts
 
        uint8_t sw_btn = GPIO_ReadInputDataBit(SW_BTN);
 
        //uint8_t sw_up = GPIO_ReadInputDataBit(SW_UP);
 
        //uint8_t sw_down = GPIO_ReadInputDataBit(SW_DOWN);
 
        //uint8_t sw_left = GPIO_ReadInputDataBit(SW_LEFT);
 
        //uint8_t sw_right = GPIO_ReadInputDataBit(SW_RIGHT);
 
 
        if(!sw_btn) {
 
            GPIO_ToggleBits(LED_STAT);
 
            if(!toggle) {
 
                GPIO_SetBits(GPIOB, GPIO_Pin_13);
 
                toggle = ! toggle;
 
            }
 
            else  {
 
                GPIO_ResetBits(GPIOB, GPIO_Pin_13);
 
                toggle = ! toggle;
 
            }    
 
        }
 
 
        GPIO_SetBits(LED_POWER);
 
        Delay(50);
 
        GPIO_ResetBits(LED_POWER);
 
        Delay(50);
 
    }
 
}
 
 
int32_t temp = 0;
 
int32_t setpoint = 0;
 
int32_t p = 1;
 
int32_t i = 1;
 
int32_t d = 1;
 
 
 
// Process things
 
void process()
 
{
 
    // Assert CS
 
    GPIO_ResetBits(MAX_CS);
 
    Delay(1);
 
 
    // This may not clock at all... might need to send 16 bits first
 
    SPI_I2S_SendData(SPI2, 0xAAAA); // send dummy data
 
    //SPI_I2S_SendData(SPI2, 0xAA); // send dummy data
 
    uint16_t temp_pre = SPI_I2S_ReceiveData(SPI2);
 
 
    if(temp_pre & 0b0000000000000010) {
 
        ssd1306_DrawString("Fatal Error", 3, 35);
 
    }
 
    else if(temp_pre & 0b0000000000000001) {
 
        ssd1306_DrawString("TC Fault", 3, 35);
 
    }
 
    else {
 
        ssd1306_DrawString("TempSense OK", 3, 35);
 
    }
 
 
    uint8_t sign = temp >> 15;// top bit is sign
 
 
 
    temp_pre = temp_pre >> 2; // Drop 2 lowest bits
 
    uint8_t frac = temp_pre & 0b11; // get fractional part
 
    frac *= 25; // each bit is .25 a degree, up to fixed point
 
    temp_pre = temp_pre >> 2; // Drop 2 fractional bits 
 
 
    int16_t temp = 0;
 
    if(sign) {
 
        temp = -temp_pre;
 
    }
 
    else {
 
        temp = temp_pre;
 
    }
 
 
 
    // Deassert CS
 
    Delay(1);
 
    GPIO_SetBits(MAX_CS);
 
 
 
    //////////////////////////
 
    // Calc internal temp   //
 
    //////////////////////////
 
/*    temp = temp >> 4; // Drop last 4 bits, no need for them
 
    float internal_temp = temp & 0x7FF // Lower 11bits are internal temp
 
    
 
    // Check internal temp sign
 
    if(temp & 0x800) {
 
        // Convert to negative value by extending sign and casting to signed type.
 
        int16_t tmp = 0xF800 | (temp & 0x7FF);
 
        internal_temp = tmp;
 
    }
 
    internal_temp *= 0.0625; // LSB = 0.0625 degrees
 
    // Now we have a good internal temp!
 
*/
 
    //////////////////////////
 
    // Calc external temp   //
 
    //////////////////////////
 
 
    if(temp > 0) {
 
        GPIO_SetBits(LED_STAT);
 
    }
 
    char tempstr[9];
 
    itoa(temp_pre, tempstr);
 
    ssd1306_DrawString("Temp: ", 1, 40);
 
    ssd1306_DrawString("    ", 1, 70);
 
    ssd1306_DrawString(tempstr, 1, 70);
 
    itoa(frac, tempstr);
 
    ssd1306_DrawString("  ", 1, 90);
 
    ssd1306_DrawString(tempstr, 1, 90);
 
 
/*
 
    if((!retval || (temp & 0x2) != 0))
 
    {
 
        ssd1306_DrawString("!TempCOMMS", 3, 35);
 
        //return; // Comms error - this is happening right now
 
    }
 
 
    else if((temp & 0x4)!= 0)
 
    {
 
        ssd1306_DrawString("!OpenThermocouple", 3, 40);
 
        //return; // Open thermocouple
 
    }
 
 
    temp = (temp & 0x7FF8) >> 5;
 
*/
 
 
    // TODO: Add calibration offset (linear)
 
 
 
    // Perform PID calculations
 
 
    // Write output to SSR
 
}
 
 
 
 
enum state {
 
    STATE_IDLE = 0,
 
    STATE_SETP,
 
    STATE_SETI,
 
    STATE_SETD,
 
 
    STATE_PREHEAT_BREW,
 
    STATE_MAINTAIN_BREW,
 
    STATE_PREHEAT_STEAM,
 
    STATE_MAINTAIN_STEAM,
 
};
 
 
 
uint8_t state = STATE_IDLE;
 
 
// State machine
 
void machine()
 
{
 
    
 
    switch(state)
 
    {
 
        // Idle state
 
        case STATE_IDLE:
 
        {
 
            // Write text to OLED
 
            // [ therm :: idle ]
 
            ssd1306_DrawString("therm :: idle ", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_SETP;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
        } break;
 
 
        case STATE_SETP:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set p ]
 
            // [ p = 12         ]
 
            ssd1306_DrawString("therm :: set p", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_SETI;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
        case STATE_SETI:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set i ]
 
            // [ i = 12         ]
 
            ssd1306_DrawString("therm :: set i", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_SETD;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
        case STATE_SETD:
 
        {
 
            // Write text to OLED
 
            // [ therm :: set d ]
 
            // [ d = 12         ]
 
            ssd1306_DrawString("therm :: set d", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
        case STATE_PREHEAT_BREW:
 
        {
 
            // Write text to OLED
 
            // [ therm : preheating brew ]
 
            // [ 30 => 120 C             ]
 
            ssd1306_DrawString("therm :: Bpreheat", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            if(temp >= setpoint) {
 
                state = STATE_MAINTAIN_BREW;
 
            }
 
 
 
        } break;
 
 
        case STATE_MAINTAIN_BREW:
 
        {
 
            // Write text to OLED
 
            // [ therm : ready to brew ]
 
            // [ 30 => 120 C           ]
 
            ssd1306_DrawString("therm :: Bready", 0, 40);
 
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
        case STATE_PREHEAT_STEAM:
 
        {
 
            // Write text to OLED
 
            // [ therm : preheating steam ]
 
            // [ 30 => 120 C           ]
 
            ssd1306_DrawString("therm :: Spreheat", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            if(temp >= setpoint) {
 
                state = STATE_MAINTAIN_STEAM;
 
            }
 
 
 
        } break;
 
 
        case STATE_MAINTAIN_STEAM:
 
        {
 
            // Write text to OLED
 
            // [ therm : ready to steam ]
 
            // [ 30 => 120 C            ]
 
            ssd1306_DrawString("therm :: Sready", 0, 40);
 
 
            // Button handler
 
            if(!GPIO_ReadInputDataBit(SW_BTN)) {
 
                state = STATE_IDLE;
 
            }
 
 
            // Event Handler
 
            // N/A
 
 
 
        } break;
 
 
 
        // Something is terribly wrong
 
        default:
0 comments (0 inline, 0 general)