Changeset - b5b1fc08b294
[Not reviewed]
cortex-f0
0 5 0
Ethan Zonca - 10 years ago 2015-03-29 20:58:14
ez@ethanzonca.com
Added virtual serial port periodic transmission of temperature. Trying out bootloader code, but still doesn't work.
5 files changed with 53 insertions and 23 deletions:
0 comments (0 inline, 0 general)
config.h
Show inline comments
 
#ifndef CONFIG_H
 
#define CONFIG_H
 

	
 

	
 
#define VCP_TX_FREQ 1000
 
#define SSR_PERIOD 200
 

	
 
#define LED_POWER GPIOF,GPIO_PIN_0
 

	
 
#define MAX_CS GPIOA,GPIO_PIN_15
 

	
 
#define SW_BTN  GPIOB, GPIO_PIN_4
 
#define SW_UP   GPIOB, GPIO_PIN_7
 
#define SW_DOWN GPIOB, GPIO_PIN_3
 
#define SW_LEFT GPIOB, GPIO_PIN_5
 
#define SW_RIGHT GPIOB, GPIO_PIN_6
 

	
 
#define SSR_PIN GPIOA, GPIO_PIN_1
 

	
 
#endif
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
flash.sh
Show inline comments
 
#!/bin/bash
 
cd build
 
st-flash write main.bin 0x8000000
 
cd ..
 

	
 

	
 
# USB DFU:
 
# sudo  dfu-util -a 0 -d 0483:df11 -s 0x08000000:leave -D build/main.bin
main.c
Show inline comments
 
@@ -210,62 +210,48 @@ void update_temp() {
 
 
        if(sign) {
 
            signint = -1;
 
        }
 
        else {
 
            signint = 1;
 
        }
 
 
        // Convert to Fahrenheit
 
        if(temp_units == TEMP_UNITS_FAHRENHEIT)
 
        {
 
            temp = signint * ((temp_pre*100) + temp_frac);
 
            temp = temp * 1.8;
 
            temp += 3200;
 
            temp_frac = temp % 100;
 
            temp /= 100;
 
        }
 
 
        // Use Celsius values
 
        else
 
        {
 
            temp = temp_pre * signint;
 
        }
 
    }
 
 
    // Print temp to cdc
 
/*
 
    CDC_Transmit_FS("Temp: ", 6);
 
    char tempstr[6];
 
    zitoa(temp, tempstr);
 
    CDC_Transmit_FS(tempstr, sizeof(tempstr));
 
 
    CDC_Transmit_FS("\r\n", 2);
 
    CDC_Transmit_FS("\r\n", 2);
 
    CDC_Transmit_FS("\r\n", 2);
 
    CDC_Transmit_FS("\r\n", 2);
 
    CDC_Transmit_FS("\r\n", 2);
 
*/
 
}
 
 
 
// PID implementation
 
// TODO: Make struct that has the last_temp and i_state in it, pass by ref. Make struct that has other input values maybe.
 
int16_t last_pid_temp = 0;
 
uint8_t last_pid_temp_frac = 0;
 
int16_t i_state = 0;
 
 
int16_t update_pid(uint16_t k_p, uint16_t k_i, uint16_t k_d, int16_t temp, uint8_t temp_frac, int16_t setpoint) 
 
{
 
  // Calculate instantaneous error
 
  int16_t error = (int16_t)setpoint - (int16_t)temp; // TODO: Use fixed point fraction
 
 
  // Proportional component
 
  int16_t p_term = k_p * error;
 
 
  // Error accumulator (integrator)
 
  i_state += error;
 
 
  // to prevent the iTerm getting huge despite lots of 
 
  //  error, we use a "windup guard" 
 
  // (this happens when the machine is first turned on and
 
  // it cant help be cold despite its best efforts)
 
@@ -280,48 +266,49 @@ int16_t update_pid(uint16_t k_p, uint16_
 
    i_state = -windup_guard_res;
 
  int16_t i_term = k_i * i_state;
 
 
  // Calculate differential term (slope since last iteration)
 
  int16_t d_term = (k_d * (temp - last_pid_temp));
 
 
  // Save temperature for next iteration
 
  last_pid_temp = temp;
 
  last_pid_temp_frac = temp_frac;
 
 
  int16_t result = p_term + i_term - d_term;
 
 
  // Put out tenths of percent, 0-1000. 
 
  if(result > 1000)
 
    result = 1000;
 
  else if(result < -1000)
 
    result = -1000;
 
 
  // Return feedback
 
  return result;
 
}
 
 
 
uint32_t last_ssr_on = 0;
 
uint32_t last_vcp_tx = 0;
 
uint32_t last_led = 0;
 
int32_t setpoint = 0;
 
int16_t ssr_output = 0; // Duty cycle of ssr, 0 to SSR_PERIOD 
 
uint8_t pid_enabled = 0;
 
 
// Process things
 
void process()
 
{
 
    update_temp(); // Read MAX31855
 
 
    // TODO: Add calibration offset (linear)
 
    uint32_t ticks = HAL_GetTick();
 
 
    if(ticks - last_led > 400) 
 
    {
 
        HAL_GPIO_TogglePin(LED_POWER);
 
        last_led = ticks;
 
    }
 
 
    // Every 200ms, set the SSR on unless output is 0
 
    if((ticks - last_ssr_on > SSR_PERIOD))
 
    {
 
        if(pid_enabled) 
 
        {
 
@@ -331,48 +318,60 @@ void process()
 
            ssr_output = power_percent; //(((uint32_t)SSR_PERIOD * (uint32_t)10 * (uint32_t)100) * power_percent) / (uint32_t)1000000;
 
        }
 
        else 
 
        {
 
            ssr_output = 0;
 
        }
 
 
        // Only support heating (ssr_output > 0) right now
 
        if(ssr_output > 0) {
 
 
            char tempstr[6];
 
            itoa(ssr_output, tempstr, 10);
 
            ssd1306_DrawString(tempstr, 0, 90);
 
 
            HAL_GPIO_WritePin(SSR_PIN, 1);
 
            last_ssr_on = ticks;
 
        }
 
    }
 
    
 
    // Kill SSR after elapsed period less than SSR_PERIOD 
 
    if(ticks - last_ssr_on > ssr_output || ssr_output == 0)
 
    {
 
        HAL_GPIO_WritePin(SSR_PIN, 0);
 
    }
 
 
    if(ticks - last_vcp_tx > VCP_TX_FREQ)
 
    {
 
        // Print temp to cdc
 
        char tempstr[6];
 
        itoa_fp(temp, temp_frac, tempstr);
 
 
        while(CDC_Transmit_FS(tempstr, sizeof(tempstr)) == USBD_BUSY);
 
        while(CDC_Transmit_FS("\r\n", 2) == USBD_BUSY);
 
 
        last_vcp_tx = ticks;
 
    }
 
}
 
 
 
uint8_t goto_mode = 2;
 
 
// State machine
 
uint8_t sw_btn_last = 0;
 
uint8_t sw_up_last = 0;
 
uint8_t sw_down_last = 0;
 
uint8_t sw_left_last = 0;
 
uint8_t sw_right_last = 0;
 
 
#define SW_BTN_PRESSED (sw_btn_last == 0 && sw_btn == 1) // rising edge on buttonpress
 
#define SW_UP_PRESSED (sw_up_last == 0 && sw_up == 1)
 
#define SW_DOWN_PRESSED (sw_down_last == 0 && sw_down == 1)
 
#define SW_LEFT_PRESSED (sw_left_last == 0 && sw_left == 1)
 
#define SW_RIGHT_PRESSED (sw_right_last == 0 && sw_right == 1)
 
 
void save_settings()
 
{
 
/*
 
   Minimal_EEPROM_Unlock();
 
    // Try programming a word at an address divisible by 4
 
    Minimal_EEPROM_ProgramWord(EEPROM_BASE_ADDR + EEPROM_ADDR_BOOTTOBREW, boottobrew);
 
@@ -515,49 +514,55 @@ void machine()
 
                {
 
                    ssd1306_DrawString("-> setup    ", 1, 40);
 
                } break;
 
 
                case 0:
 
                {
 
                    ssd1306_DrawString("-> reset    ", 1, 40);
 
                } break;
 
            }
 
 
            // Button handler
 
            if(SW_BTN_PRESSED) {
 
                switch(goto_mode) {
 
                    case 2:
 
                        state = STATE_PREHEAT_BREW;
 
                        break;
 
                    case 1:
 
                        state = STATE_SETP;
 
                        break;
 
                    case 0:
 
                    {
 
                        ssd1306_clearscreen();
 
                        ssd1306_DrawString("Entering Bootloader", 1, 0);
 
                        ssd1306_DrawString("(hopefully)", 2, 0);
 
                        HAL_Delay(1000);
 
                        //HAL_Delay(1000);
 
                        HAL_RCC_DeInit();
 
                        SysTick->CTRL = 0;
 
                        SysTick->LOAD = 0;
 
                        SysTick->VAL = 0;
 
                        __set_PRIMASK(1);
 
                        __set_MSP(0x200010000);
 
                        *((unsigned long *)0x200017F0) = 0xDEADBEEF; // 6KB STM32F042
 
                        NVIC_SystemReset();
 
 
                        state = STATE_IDLE;
 
                    } break;
 
 
                    default:
 
                        state = STATE_PREHEAT_BREW;
 
                }
 
            }
 
            else if(SW_UP_PRESSED && goto_mode < 2) {
 
                goto_mode++;
 
            }
 
            else if(SW_DOWN_PRESSED && goto_mode > 0) {
 
                goto_mode--;
 
            }
 
 
 
            // Event Handler
 
            // N/A
 
 
        } break;
 
 
        case STATE_SETP:
startup_stm32f042x6.s
Show inline comments
 
@@ -63,57 +63,75 @@ defined in linker script */
 
  .section .text.Reset_Handler
 
  .weak Reset_Handler
 
  .type Reset_Handler, %function
 
Reset_Handler:
 
 
  /* Bootloader jumping */
 
  ldr r0, =0x200017F0 /* address of magic token, is addr within memory range? */
 
  ldr r1, =0xDEADBEEF /* magical beef token */
 
  ldr r2, [r0, #0] /* load data from magic address */
 
  str r0, [r0, #0] /* zero data at magic address so we don't bootloop */ 
 
  cmp r2, r1 /* compare data at magic address to magic token */
 
  beq Reboot_Loader /* jump to bootloader if token match */
 
  /* End bootloader jumping */
 
 
 
  ldr   r0, =_estack
 
  mov   sp, r0          /* set stack pointer */
 
 
/* Copy the data segment initializers from flash to SRAM */
 
  movs r1, #0
 
  b LoopCopyDataInit
 
 
/* Boot into bootloader */
 
Reboot_Loader:
 
  ldr r0, =0x1FFFF6A6 /* Address of bootloader on f042 from CD00167594 pg 15 table 3 */
 
  /* This replaces ldr sp, [r0, #0] which doesn't work on m0 */
 
  // Set stack pointer
 
  ldr r1, [r0, #0]
 
  mov sp, r1
 
  LDR     R0, =0x40021018 // RCC_APB2ENR (+0x18)
 
  LDR     R1, =0x00000001 // ENABLE SYSCFG CLOCK
 
  STR     R1, [R0, #0]
 
  LDR     R0, =0x40010000 // SYSCFG_CFGR1 (+0x00)
 
  LDR     R1, =0x00000001 // MAP ROM AT ZERO
 
  STR     R1, [R0, #0]
 
  //                LDR     R0, =0x1FFFEC00 ; ROM BASE (STM32F03x)
 
  LDR     R0, =0x1FFFC400 // ROM BASE (STM32F04x)
 
  //                LDR     R0, =0x1FFFEC00 ; ROM BASE (STM32F05x)
 
  //                LDR     R0, =0x1FFFC800 ; ROM BASE (STM32F07x)
 
  //                LDR     R0, =0x1FFFD800 ; ROM BASE (STM32F09x)
 
  LDR     R1, [R0, #0]    // SP @ +0
 
  MOV     SP, R1
 
  LDR     R0, [R0, #4]    // PC @ +4
 
  BX      R0
 
 
 
  // On reset, SP=value at address 0x0
 
//  ldr r0, =0x00000000
 
//  ldr r0, [r0, #0]
 
//  mov sp, r0
 
 
//  ldr r0, =0x1FFFC800 /* Address of bootloader on f042 from CD00167594 pg 15 table 3 */
 
 
  // Branch to bootloader
 
  ldr r0, [r0, #4]
 
  bx r0
 
//  ldr r0, [r0, #4]
 
//  bx r0
 
 
 
CopyDataInit:
 
  ldr r3, =_sidata
 
  ldr r3, [r3, r1]
 
  str r3, [r0, r1]
 
  adds r1, r1, #4
 
 
LoopCopyDataInit:
 
  ldr r0, =_sdata
 
  ldr r3, =_edata
 
  adds r2, r0, r1
 
  cmp r2, r3
 
  bcc CopyDataInit
 
  ldr r2, =_sbss
 
  b LoopFillZerobss
 
/* Zero fill the bss segment. */
 
FillZerobss:
 
  movs r3, #0
 
  str  r3, [r2]
 
  adds r2, r2, #4
 
 
 
LoopFillZerobss:
usbd_cdc_if.c
Show inline comments
 
@@ -269,52 +269,55 @@ static int8_t CDC_Receive_FS (uint8_t* B
 
    //USBD_CDC_SetRxBuffer(hUsbDevice_0, UserRxBufferFS);
 
    USBD_CDC_ReceivePacket(hUsbDevice_0);
 
 
    return (USBD_OK);
 
    /* USER CODE END 7 */
 
}
 
 
/**
 
 * @brief  CDC_Transmit_FS
 
 *         Data send over USB IN endpoint are sent over CDC interface
 
 *         through this function.
 
 *         @note
 
 *
 
 *
 
 * @param  Buf: Buffer of data to be send
 
 * @param  Len: Number of data to be send (in bytes)
 
 * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
 
 */
 
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
 
{
 
    uint8_t result = USBD_OK;
 
    /* USER CODE BEGIN 8 */
 
    uint16_t i;
 
 
 
    // Zero out user TX buffer (EMZ FIXME: why bother?)
 
    for (i=0; i < sizeof(UserTxBufferFS); i++) {
 
	UserTxBufferFS[i] = 0;
 
    }
 
 
    // Copy input buff to user TX buffer
 
    for (i=0; i < Len; i++) {
 
	UserTxBufferFS[i] = Buf[i];
 
    }
 
 
    USBD_CDC_SetTxBuffer(hUsbDevice_0, UserTxBufferFS, Len);
 
    result = USBD_CDC_TransmitPacket(hUsbDevice_0);
 
 
/*
 
    for (i = 0; i < 1 + (Len/8); i++) {
 
	USBD_CDC_SetTxBuffer(hUsbDevice_0, UserTxBufferFS + (8*i), 8);
 
	do {
 
	    result = USBD_CDC_TransmitPacket(hUsbDevice_0);
 
	} while (result != HAL_BUSY);
 
    }
 
*/
 
    /* USER CODE END 8 */
 
    return result;
 
}
 
 
/**
 
 * @}
 
 */
 
 
/**
0 comments (0 inline, 0 general)