diff options
author | tcsullivan <tullivan99@gmail.com> | 2019-04-30 12:29:06 -0400 |
---|---|---|
committer | tcsullivan <tullivan99@gmail.com> | 2019-04-30 12:29:06 -0400 |
commit | 624576f5fa5e839469dd4454ff698b11342a39b8 (patch) | |
tree | 9c29927de6926cf5294e1e640667dc8c57df580b | |
parent | 569dbb6c2d5eb852d2032774061f84a8f16b5666 (diff) |
Made things work
-rw-r--r-- | Makefile | 27 | ||||
-rwxr-xr-x | board.c | 55 | ||||
-rwxr-xr-x | board.h | 48 | ||||
-rwxr-xr-x | delay.c | 42 | ||||
-rwxr-xr-x | delay.h | 29 | ||||
-rwxr-xr-x | i2c.c | 136 | ||||
-rwxr-xr-x | i2c.h | 26 | ||||
-rwxr-xr-x | lcd.c | 61 | ||||
-rwxr-xr-x | lcd.h | 6 | ||||
-rwxr-xr-x | main.c | 55 | ||||
-rwxr-xr-x | temp.c | 92 | ||||
-rwxr-xr-x | temp.h | 33 |
12 files changed, 610 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ea846a1 --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +CC = msp430-gcc +CFLAGS = -mmcu=msp430g2553 -std=gnu99 -Os -ggdb + +CSRC = board.c \ + delay.c \ + i2c.c \ + lcd.c \ + temp.c \ + main.c +COBJ = $(patsubst %.c, %.o, $(CSRC)) + +ELF = main.elf + +all: $(ELF) + +clean: + @echo " CLEAN" + @rm -f $(ELF) $(COBJ) + +$(ELF): $(COBJ) + @echo " CC " $@ + @$(CC) $(CFLAGS) $(COBJ) -o $(ELF) + +%.o: %.c + @echo " CC " $< + @$(CC) $(CFLAGS) -c $< -o $@ + @@ -0,0 +1,55 @@ +/** + * @file board.c + * Provides board configuration and initialization. + * + * Copyright (C) 2019 Clyne Sullivan + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#include "board.h" + +static void boardInitWatchdog(void); +static void boardInitPins(void); + +void boardInit(void) +{ + // Slow down needed for LCD + BCSCTL1 = CALBC1_1MHZ; + DCOCTL = CALDCO_1MHZ; + + boardInitWatchdog(); + boardInitPins(); +} + +void boardInitWatchdog(void) +{ + WDTCTL = WDTHOLD | WDTPW; +} + +void boardInitPins(void) +{ + // All pins are output + P1DIR = PORT1_PINS; + P2DIR = PORT2_PINS; + + // All pins should start at a low state + P1OUT = 0; + P2OUT = 0; + + // Set I2C pins to the proper mode + P1SEL |= TEMP_SDA | TEMP_SCL; + P1SEL2 |= TEMP_SDA | TEMP_SCL; +} + @@ -0,0 +1,48 @@ +/** + * @file board.h + * Provides board configuration and initialization. + * + * Copyright (C) 2019 Clyne Sullivan + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#include <msp430.h> +#include <stdint.h> + +// Port 1 pins +#define LCD_DATL (0x0F) +#define LCD_RW (1 << 4) +#define LCD_RS (1 << 5) +#define TEMP_SCL (1 << 6) +#define TEMP_SDA (1 << 7) + +#define PORT1_PINS (LCD_DATL | LCD_RW | LCD_RS | TEMP_SCL | TEMP_SDA) + +// Port 2 pins +#define LCD_DATH (0x0F) +#define LCD_E (1 << 4) + +#define PORT2_PINS (LCD_DATH | LCD_E) + +/** + * Initializes pins and core functionality. + */ +void boardInit(void); + +#endif // BOARD_H_ + @@ -0,0 +1,42 @@ +/** + * @file delay.c + * Delay support using a timer. + * + * Copyright (C) 2019 Clyne Sullivan + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#include "board.h" + +volatile unsigned int delayTicks = 0; + +void delayInit(void) +{ + TACCTL0 |= CCIE; + TACCR0 = 128; + TACTL |= TASSEL_2 | MC_1 | ID_3; +} + +void delay(unsigned int ms) +{ + unsigned int target = delayTicks + ms; + while (delayTicks < target); +} + +__attribute__((__interrupt__(TIMER0_A0_VECTOR))) +static void delayInterruptHandler(void) +{ + delayTicks++; +} @@ -0,0 +1,29 @@ +/** + * @file delay.h + * Delay support using a timer. + * + * Copyright (C) 2019 Clyne Sullivan + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#ifndef DELAY_H_ +#define DELAY_H_ + +void delayInit(void); + +void delay(unsigned int ms); + +#endif // DELAY_H_ + @@ -0,0 +1,136 @@ +/* + * i2c.h + * + * Created on: 28 de abr de 2017 + * Author: helio.capella + * + * Based on msp430g2xx3_uscib0_i2c_12.c by D. Dang + * + * Modified by tcsullivan: + * 04/29: Modified pin macros to work with project + */ + +#include <msp430.h> +#include "i2c.h" +#include "board.h" + +#define I2CSEL P1SEL +#define I2CSEL2 P1SEL2 +#define I2CSCL (TEMP_SCL) +#define I2CSDA (TEMP_SDA) + +void I2C_init(uint8_t slaveAddress){ + // Port Configuration + I2CSEL |= I2CSDA + I2CSCL; // Assign I2C pins to USCI_B0 + I2CSEL2|= I2CSDA + I2CSCL; // Assign I2C pins to USCI_B0 + +// isRx = 0; // State variable - possibly useless + + //USCI Configuration + UCB0CTL1 |= UCSWRST; // Enable SW reset + UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode + UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset + + //Set USCI Clock Speed + UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz + UCB0BR1 = 0; + + //Set Slave Address and Resume operation + UCB0I2CSA = slaveAddress; // Slave Address passed as parameter + UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation +} + + +void I2C_write(uint8_t ByteCtr, uint8_t *TxData) { + __disable_interrupt(); +// isRx = 0; + //Interrupt management + IE2 &= ~UCB0RXIE; // Disable RX interrupt +// while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent + IE2 |= UCB0TXIE; // Enable TX interrupt + + //Pointer to where data is stored to be sent + PTxData = (uint8_t *) TxData; // TX array start address + TxByteCtr = ByteCtr; // Load TX byte counter + + //Send start condition + // while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent + UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition + + __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts + while (UCB0CTL1 & UCTXSTP); +} + +void I2C_read(uint8_t ByteCtr, volatile uint8_t *RxData) { + __disable_interrupt(); +// isRx = 1; + + //Interrupt management + IE2 &= ~UCB0TXIE; // Disable TX interrupt + UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset + UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation + IE2 |= UCB0RXIE; // Enable RX interrupt + + //Pointer to where data will be stored + PRxData = (uint8_t *) RxData; // Start of RX buffer + RxByteCtr = ByteCtr; // Load RX byte counter + + //while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent + + //If only 1 byte will be read send stop signal as soon as it starts transmission + if(RxByteCtr == 1){ + UCB0CTL1 |= UCTXSTT; // I2C start condition + while (UCB0CTL1 & UCTXSTT); // Start condition sent? + UCB0CTL1 |= UCTXSTP; // I2C stop condition + __enable_interrupt(); + } else { + UCB0CTL1 |= UCTXSTT; // I2C start condition + } + + __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts + while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent +} + +#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) +#pragma vector = USCIAB0TX_VECTOR +__interrupt void USCIAB0TX_ISR(void) +#elif defined(__GNUC__) +void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void) +#else +#error Compiler not supported! +#endif +{ + if(IFG2 & UCB0RXIFG){ // Receive In + if (RxByteCtr == 1) + { + *PRxData = UCB0RXBUF; // Move final RX data to PRxData + __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 + } + else + { + *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData + if (RxByteCtr == 2) // Check whether byte is second to last to be read to send stop condition + UCB0CTL1 |= UCTXSTP; + __no_operation(); + } + RxByteCtr--; // Decrement RX byte counter + } + + else{ // Master Transmit + if (TxByteCtr) // Check TX byte counter + { + UCB0TXBUF = *PTxData; // Load TX buffer + PTxData++; + TxByteCtr--; // Decrement TX byte counter + } + else + { + UCB0CTL1 |= UCTXSTP; // I2C stop condition + IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag + __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 + } + } +} + + + @@ -0,0 +1,26 @@ +/* + * i2c.h + * + * Created on: 28 de abr de 2017 + * Author: helio.capella + */ + +#ifndef I2C_H_ +#define I2C_H_ + +#include <stdint.h> + +uint8_t *PTxData; // Pointer to TX data +uint8_t *PRxData; // Pointer to RX data + +uint8_t TxByteCtr; +uint8_t RxByteCtr; + +//uint8_t isRx; + +void I2C_init(uint8_t slaveAddress); +void I2C_write(uint8_t ByteCtr, uint8_t *TxData); +void I2C_read(uint8_t ByteCtr, volatile uint8_t *RxData); + +#endif /* I2C_H_ */ + @@ -0,0 +1,61 @@ +#include "board.h"
+#include "delay.h"
+#include "lcd.h"
+
+static void lcdPulseE(void);
+static void lcdSetDAT(uint8_t value);
+static void lcdSendCommand(uint8_t command);
+static void lcdSendData(uint8_t data);
+
+void lcdInit(void)
+{
+ // Give time for LCD to prepare itself
+ delay(100);
+ lcdSendCommand(0x38);
+ lcdSendCommand(0x10);
+ lcdSendCommand(0x0D);
+ delay(5);
+ lcdClear();
+}
+
+void lcdClear(void)
+{
+ lcdSendCommand(0x01);
+ delay(2);
+}
+
+void lcdPuts(const char *s)
+{
+ lcdSendCommand(0x06);
+ while (*s != '\0')
+ lcdSendData(*s++);
+}
+
+void lcdPulseE(void)
+{
+ P2OUT |= LCD_E;
+ delay(2);
+ P2OUT &= ~(LCD_E);
+}
+
+void lcdSetDAT(uint8_t value)
+{
+ P2OUT &= ~(LCD_DATH);
+ P2OUT |= (value >> 4) & LCD_DATH;
+ P1OUT &= ~(LCD_DATL);
+ P1OUT |= value & LCD_DATL;
+}
+
+void lcdSendCommand(uint8_t command)
+{
+ P1OUT &= ~(LCD_RS);
+ lcdSetDAT(command);
+ lcdPulseE();
+}
+
+void lcdSendData(uint8_t data)
+{
+ P1OUT |= LCD_RS;
+ lcdSetDAT(data);
+ lcdPulseE();
+}
@@ -0,0 +1,6 @@ +
+void lcdInit(void);
+
+void lcdClear(void);
+void lcdPuts(const char *s);
+
@@ -0,0 +1,55 @@ +/** + * @file main.c + * Main program entry point. + * + * Copyright (C) 2019 Clyne Sullivan + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#include "board.h" +#include "delay.h" +#include "lcd.h" +#include "temp.h" + +#include <stdio.h> + +int main(void) +{ + // Prepare processor and IO + boardInit(); + + delayInit(); + _NOP(); + __enable_interrupt(); + + lcdInit(); + + if (tempInit() != 0) { + lcdPuts("Sensor broken."); + while (1); + } + + char buf[8]; + while (1) { + lcdClear(); + int16_t temp = tempGetDieTemperature(); + sprintf(buf, "%04d", temp); + lcdPuts(buf); + delay(1000); + } + + return 0; +} + @@ -0,0 +1,92 @@ +/** + * @file temp.c + * Provides support for the TMP006 temperature sensor. + * + * Copyright (C) 2019 Clyne Sullivan + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#include "board.h" +#include "i2c.h" + +// TMP006 I2C address +#define TEMP_ADDR (0x40) + +// TMP006 registers +#define TMP006_CONFIG (0x02) +#define TMP006_VOBJ (0x00) +#define TMP006_TAMB (0x01) +#define TMP006_MANID (0xFE) +#define TMP006_DEVID (0xFF) + +// TMP006 CONFIG register parameters +#define TMP006_CFG_RESET (0x8000) +#define TMP006_CFG_MODEON (0x7000) +#define TMP006_CFG_1SAMPLE (0x0000) +#define TMP006_CFG_2SAMPLE (0x0200) +#define TMP006_CFG_4SAMPLE (0x0400) +#define TMP006_CFG_8SAMPLE (0x0600) +#define TMP006_CFG_16SAMPLE (0x0800) +#define TMP006_CFG_DRDYEN (0x0100) +#define TMP006_CFG_DRDY (0x0080) + +static void tempI2CWrite(uint8_t reg, uint16_t value); +static uint16_t tempI2CRead(uint8_t reg); + +int tempInit(void) +{ + // Prepare I2C + I2C_init(TEMP_ADDR); + + // Initialize the TMP006 sensor + tempI2CWrite(TMP006_CONFIG, TMP006_CFG_MODEON | TMP006_CFG_DRDYEN | + TMP006_CFG_16SAMPLE); + + // Check that the device is in fact the TMP006 + uint16_t manid = tempI2CRead(TMP006_MANID); + uint16_t devid = tempI2CRead(TMP006_DEVID); + if (manid != 0x5449 || devid != 0x67) + return 1; + + return 0; +} + +int16_t tempGetDieTemperature(void) +{ + int16_t raw = tempI2CRead(TMP006_TAMB); + return (raw >> 2) / 32; +} + +void tempI2CWrite(uint8_t reg, uint16_t value) +{ + uint8_t data[3] = { + reg, + value >> 8, + value & 0xFF + }; + I2C_write(3, data); +} + +uint16_t tempI2CRead(uint8_t reg) +{ + uint8_t data[2] = { + reg, + 0 + }; + I2C_write(1, data); + I2C_read(2, data); + return (data[0] << 8) | data[1]; +} + @@ -0,0 +1,33 @@ +/** + * @file temp.h + * Provides support for the TMP006 temperature sensor. + * + * Copyright (C) 2019 Clyne Sullivan + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#ifndef TEMP_H_ +#define TEMP_H_ + +/** + * Attempts to initialize the TMP006 temperature sensor. + * @return Zero on success, non-zero on failure + */ +int tempInit(void); + +int16_t tempGetDieTemperature(void); + +#endif // TEMP_H_ + |