From a860bd27a0950e4dd8ae530f9095a91ced7436a3 Mon Sep 17 00:00:00 2001 From: jaseg Date: Mon, 15 Apr 2019 01:25:05 +0900 Subject: driver/fw: Temp sensor working modulo some brownout condition --- driver_fw/Makefile | 8 +++---- driver_fw/base.c | 28 +++++++++++++++++++++++ driver_fw/i2c.h | 39 ------------------------------- driver_fw/main.c | 39 +++++++++++++++++++++++++++++-- driver_fw/mcp9801.c | 42 ++++++++++++++++++++++++++++++++++ driver_fw/mcp9801.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ driver_fw/serial.c | 2 +- 7 files changed, 178 insertions(+), 46 deletions(-) create mode 100644 driver_fw/base.c create mode 100644 driver_fw/mcp9801.c create mode 100644 driver_fw/mcp9801.h (limited to 'driver_fw') diff --git a/driver_fw/Makefile b/driver_fw/Makefile index cfbe654..1fb1865 100644 --- a/driver_fw/Makefile +++ b/driver_fw/Makefile @@ -41,16 +41,16 @@ cmsis_exports.c: $(CMSIS_DEV_PATH)/Include/stm32f030x6.h $(CMSIS_PATH)/Include/c %.o: %.c $(CC) -c $(CFLAGS) -o $@ $^ - $(CC) -E $(CFLAGS) -o $(@:.o=.pp) $^ +# $(CC) -E $(CFLAGS) -o $(@:.o=.pp) $^ %.o: %.s $(CC) -c $(CFLAGS) -o $@ $^ - $(CC) -E $(CFLAGS) -o $(@:.o=.pp) $^ +# $(CC) -E $(CFLAGS) -o $(@:.o=.pp) $^ %.dot: %.elf r2 -a arm -qc 'aa;agC' $< 2>/dev/null >$@ -main.elf: main.o startup_stm32f030x6.o system_stm32f0xx.o $(HAL_PATH)/Src/stm32f0xx_ll_utils.o cmsis_exports.o ../common/8b10b.o serial.o mac.o i2c.o lcd1602.o +main.elf: main.o startup_stm32f030x6.o system_stm32f0xx.o $(HAL_PATH)/Src/stm32f0xx_ll_utils.o cmsis_exports.o ../common/8b10b.o serial.o mac.o i2c.o lcd1602.o mcp9801.o base.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(OBJCOPY) -O ihex $@ $(@:.elf=.hex) $(OBJCOPY) -O binary $@ $(@:.elf=.bin) @@ -61,7 +61,7 @@ program: main.elf openocd.cfg openocd -f openocd.cfg -c "program $< verify reset exit" clean: - rm -f **.o + rm -f **.o **.pp rm -f main.elf main.hex main.bin main.map main.lst rm -f **.expand diff --git a/driver_fw/base.c b/driver_fw/base.c new file mode 100644 index 0000000..75befcb --- /dev/null +++ b/driver_fw/base.c @@ -0,0 +1,28 @@ + +#include + +int __errno = 0; +void *_impure_ptr = NULL; + +void __sinit(void) { +} + +void *memset(void *s, int c, size_t n) { + char *end = (char *)s + n; + for (char *p = (char *)s; p < end; p++) + *p = (char)c; + return s; +} + +size_t strlen(const char *s) { + const char *start = s; + while (*s++); + return s - start - 1; +} + +char *strcpy(char *dst, const char *src) { + char *p = dst; + while (*src) + *p++ = *src++; + return dst; +} diff --git a/driver_fw/i2c.h b/driver_fw/i2c.h index ac4674d..4df7750 100644 --- a/driver_fw/i2c.h +++ b/driver_fw/i2c.h @@ -3,45 +3,6 @@ #include "global.h" -// I2C HAL - -// I2C1 -// SCL [PB6, PB8] -#define I2C1_SCL_GPIO_PERIPH RCC_AHB2ENR_GPIOBEN -#define I2C1_SCL_GPIO_PORT GPIOB -#define I2C1_SCL_GPIO_PIN GPIO_PIN_8 -#define I2C1_SCL_GPIO_SRC GPIO_PinSource8 -// SDA [PB7, PB9] -#define I2C1_SDA_GPIO_PERIPH RCC_AHB2ENR_GPIOBEN -#define I2C1_SDA_GPIO_PORT GPIOB -#define I2C1_SDA_GPIO_PIN GPIO_PIN_9 -#define I2C1_SDA_GPIO_SRC GPIO_PinSource9 - -// I2C2 -// SCL [PB10, PB13] -#define I2C2_SCL_GPIO_PERIPH RCC_AHB2ENR_GPIOBEN -#define I2C2_SCL_GPIO_PORT GPIOB -#define I2C2_SCL_GPIO_PIN GPIO_PIN_10 -#define I2C2_SCL_GPIO_SRC GPIO_PinSource10 -// SDA [PB11, PB14] -#define I2C2_SDA_GPIO_PERIPH RCC_AHB2ENR_GPIOBEN -#define I2C2_SDA_GPIO_PORT GPIOB -#define I2C2_SDA_GPIO_PIN GPIO_PIN_11 -#define I2C2_SDA_GPIO_SRC GPIO_PinSource11 - -// I2C3 -// SCL [PC0] -#define I2C3_SCL_GPIO_PERIPH RCC_AHB2ENR_GPIOCEN -#define I2C3_SCL_GPIO_PORT GPIOC -#define I2C3_SCL_GPIO_PIN GPIO_PIN_0 -#define I2C3_SCL_GPIO_SRC GPIO_PinSource0 -// SDA [PC1] -#define I2C3_SDA_GPIO_PERIPH RCC_AHB2ENR_GPIOCEN -#define I2C3_SDA_GPIO_PORT GPIOC -#define I2C3_SDA_GPIO_PIN GPIO_PIN_1 -#define I2C3_SDA_GPIO_SRC GPIO_PinSource1 - - // Definitions of I2C analog filter state #define I2C_AF_ENABLE ((uint32_t)0x00000000U) // Analog filter is enabled #define I2C_AF_DISABLE I2C_CR1_ANFOFF // Analog filter is disabled diff --git a/driver_fw/main.c b/driver_fw/main.c index 8551d83..5960e23 100644 --- a/driver_fw/main.c +++ b/driver_fw/main.c @@ -1,15 +1,33 @@ +/* 8seg LED display driver firmware + * Copyright (C) 2018 Sebastian Götte + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include "global.h" #include "serial.h" #include "i2c.h" #include "lcd1602.h" +#include "mcp9801.h" #include <8b10b.h> /* Part number: STM32F030F4C6 */ volatile unsigned int comm_led_ctr, err_led_ctr; -volatile unsigned int sys_time_tick; +volatile unsigned int sys_time_tick = 0; volatile unsigned int sys_time_ms; volatile unsigned int sys_time_s; unsigned int frame_duration_us; @@ -143,7 +161,8 @@ int main(void) { using a Java(TM) GUI. */ i2c_enable(I2C1); lcd1602_init(); - lcd_write_str(0, 0, "Hello World!"); + /* The MCP9801 temperature sensor is initialized below in the SysTick ISR since it needs a few milliseconds to + * powerup. */ /* TIM3 is used to generate the MOSFET driver control signals */ /* TIM3 running off 48MHz APB1 clk, T=20.833ns */ @@ -161,6 +180,9 @@ int main(void) { txstate.current_symbol = txstate.next_symbol = xfr_8b10b_encode(&txstate.st, K28_1) | 1<<10; TIM3->EGR |= TIM_EGR_UG; + lcd_write_str(0, 0, "8seg driver"); + lcd_write_str(0, 1, "initialized \xbc"); + NVIC_EnableIRQ(TIM3_IRQn); NVIC_SetPriority(TIM3_IRQn, 2<<4); @@ -238,6 +260,19 @@ void SysTick_Handler(void) { if (sys_time_ms++ == 1000) { sys_time_ms = 0; sys_time_s++; + + int32_t temp = mcp9801_read_mdegC(); + temp /= 100; + char buf[17] = { 0 }; + strcpy(buf, "Temp: +XXX.X\xdf""C"" "); + buf[6] = temp >= 0 ? '+' : '-'; + buf[7] = temp/1000 + '0'; + buf[8] = (temp%1000)/100 + '0'; + buf[9] = (temp%100)/10 + '0'; + buf[11] = temp%10 + '0'; + lcd_write_str(0, 0, buf); + lcd_write_str(0, 1, " "" "" "" "); + mcp9801_init(); } /* This is a hack. We could use the SPI interrupt here if that didn't fire at the start instead of end of transmission.... -.- */ diff --git a/driver_fw/mcp9801.c b/driver_fw/mcp9801.c new file mode 100644 index 0000000..76aac1e --- /dev/null +++ b/driver_fw/mcp9801.c @@ -0,0 +1,42 @@ +/* 8seg LED display driver firmware + * Copyright (C) 2018 Sebastian Götte + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "global.h" +#include "i2c.h" +#include "mcp9801.h" + +void mcp9801_init() +{ + uint8_t config = MCP9801_ONESHOT_OFF | MCP9801_RES_12BIT | MCP9801_FAULT_QUEUE_1 | MCP9801_ALERT_LOW | \ + MCP9801_MODE_COMP | MCP9801_SHUTDOWN_OFF; + uint8_t buf[2] = { MCP9801_REG_CONFIG, config }; + i2c_transmit(MCP9801_I2C_PERIPH, buf, sizeof(buf), MCP9801_I2C_ADDR, I2C_GENSTOP_YES); + + /* Address device here */ + uint8_t buf2[1] = { MCP9801_REG_TEMP }; + i2c_transmit(MCP9801_I2C_PERIPH, buf2, sizeof(buf2), MCP9801_I2C_ADDR, I2C_GENSTOP_NO); +} + +int32_t mcp9801_read_mdegC() +{ + uint8_t rx[2]; + i2c_receive(MCP9801_I2C_PERIPH, rx, sizeof(rx), MCP9801_I2C_ADDR); + + /* Fixup endianness, sign-extend */ + int32_t temp = (int16_t)((rx[0]<<8) | rx[1]); + return (temp * 1000) /256; +} diff --git a/driver_fw/mcp9801.h b/driver_fw/mcp9801.h new file mode 100644 index 0000000..6060c98 --- /dev/null +++ b/driver_fw/mcp9801.h @@ -0,0 +1,66 @@ +/* 8seg LED display driver firmware + * Copyright (C) 2018 Sebastian Götte + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __MCP9801_H__ +#define __MCP9801_H__ + +#define MCP9801_I2C_ADDR 0x90 +#define MCP9801_I2C_PERIPH I2C1 + +#include + +enum mcp9801_regmap { + MCP9801_REG_TEMP = 0, + MCP9801_REG_CONFIG = 1, + MCP9801_REG_HYST = 2, + MCP9801_REG_LIMIT = 3 +}; + +enum mcp9801_config { + MCP9801_ONESHOT_ON = 1<<7, + MCP9801_ONESHOT_OFF = 0<<7, + MCP9801_ONESHOT_Msk = 1<<7, + + MCP9801_RES_9BIT = 0<<5, + MCP9801_RES_10BIT = 1<<5, + MCP9801_RES_11BIT = 2<<5, + MCP9801_RES_12BIT = 3<<5, + MCP9801_RES_Msk = 3<<5, + + MCP9801_FAULT_QUEUE_1 = 0<<3, + MCP9801_FAULT_QUEUE_2 = 1<<3, + MCP9801_FAULT_QUEUE_4 = 2<<3, + MCP9801_FAULT_QUEUE_6 = 3<<3, + MCP9801_FAULT_QUEUE_Msk = 3<<3, + + MCP9801_ALERT_HIGH = 1<<2, + MCP9801_ALERT_LOW = 0<<2, + MCP9801_ALERT_Msk = 1<<2, + + MCP9801_MODE_INT = 1<<1, + MCP9801_MODE_COMP = 0<<1, + MCP9801_MODE_Msk = 1<<1, + + MCP9801_SHUTDOWN_ON = 1<<0, + MCP9801_SHUTDOWN_OFF = 0<<0, + MCP9801_SHUTDOWN_Msk = 1<<0, +}; + +void mcp9801_init(void); +int32_t mcp9801_read_mdegC(void); + +#endif /* __MCP9801_H__ */ diff --git a/driver_fw/serial.c b/driver_fw/serial.c index efbcb95..1b25d7e 100644 --- a/driver_fw/serial.c +++ b/driver_fw/serial.c @@ -1,4 +1,4 @@ -/* Megumin LED display firmware +/* 8seg LED display driver firmware * Copyright (C) 2018 Sebastian Götte * * This program is free software: you can redistribute it and/or modify -- cgit