From 83c0b52938c9d66c384ed03fe7acda4ac3663d7c Mon Sep 17 00:00:00 2001 From: agsler Date: Mon, 15 Jan 2024 18:05:29 +0100 Subject: [PATCH] first implementation of production --- code/Makefile | 6 +- code/i2c_peter/i2cmaster.h | 178 +++++++++++++++++++++++++++++++++++++++ code/i2c_peter/twimaster.c | 202 +++++++++++++++++++++++++++++++++++++++++++++ code/main.c | 144 ++++++++++++++++++++++++++++---- 4 files changed, 509 insertions(+), 21 deletions(-) create mode 100644 code/i2c_peter/i2cmaster.h create mode 100644 code/i2c_peter/twimaster.c diff --git a/code/Makefile b/code/Makefile index 8050431..631d740 100644 --- a/code/Makefile +++ b/code/Makefile @@ -5,15 +5,15 @@ MCU = atmega328p PROGC = m328p CC = avr-gcc #TOOL = stk500 -P /dev/ttyUSB0 -TOOL = atmelice_isp -#TOOL = avrispmkii +#TOOL = atmelice_isp +TOOL = avrispmkii #TOOL = usbasp-clone BUILDDIR = Builds DEFINES = -DF_CPU=2000000UL -DLCD_PORT=PORTD -DLCD_DDR=DDRD -CFLAGS =-mmcu=$(MCU) -O2 -Wall -Wpedantic $(DEFINES) -std=c99 -ffunction-sections -fdata-sections +CFLAGS =-mmcu=$(MCU) -O2 -Wall -Wpedantic $(DEFINES) -std=c99 -ffunction-sections -fdata-sections -Ii2c_peter LDFLAGS =-mmcu=$(MCU) -Wl,--gc-sections LDFILES = $(foreach FILE,$(FILES),$(BUILDDIR)/$(FILE).o) diff --git a/code/i2c_peter/i2cmaster.h b/code/i2c_peter/i2cmaster.h new file mode 100644 index 0000000..7c39cef --- /dev/null +++ b/code/i2c_peter/i2cmaster.h @@ -0,0 +1,178 @@ +#ifndef _I2CMASTER_H +#define _I2CMASTER_H +/************************************************************************* +* Title: C include file for the I2C master interface +* (i2cmaster.S or twimaster.c) +* Author: Peter Fleury +* File: $Id: i2cmaster.h,v 1.12 2015/09/16 09:27:58 peter Exp $ +* Software: AVR-GCC 4.x +* Target: any AVR device +* Usage: see Doxygen manual +**************************************************************************/ + +/** + @file + @defgroup pfleury_ic2master I2C Master library + @code #include @endcode + + @brief I2C (TWI) Master Software Library + + Basic routines for communicating with I2C slave devices. This single master + implementation is limited to one bus master on the I2C bus. + + This I2c library is implemented as a compact assembler software implementation of the I2C protocol + which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c). + Since the API for these two implementations is exactly the same, an application can be linked either against the + software I2C implementation or the hardware I2C implementation. + + Use 4.7k pull-up resistor on the SDA and SCL pin. + + Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module + i2cmaster.S to your target when using the software I2C implementation ! + + Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion. + + @note + The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted + to GNU assembler and AVR-GCC C call interface. + Replaced the incorrect quarter period delays found in AVR300 with + half period delays. + + @author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury + @copyright (C) 2015 Peter Fleury, GNU General Public License Version 3 + + @par API Usage Example + The following code shows typical usage of this library, see example test_i2cmaster.c + + @code + + #include + + + #define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet + + int main(void) + { + unsigned char ret; + + i2c_init(); // initialize I2C library + + // write 0x75 to EEPROM address 5 (Byte Write) + i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode + i2c_write(0x05); // write address = 5 + i2c_write(0x75); // write value 0x75 to EEPROM + i2c_stop(); // set stop conditon = release bus + + + // read previously written value back from EEPROM address 5 + i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode + + i2c_write(0x05); // write address = 5 + i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode + + ret = i2c_readNak(); // read one byte from EEPROM + i2c_stop(); + + for(;;); + } + @endcode + +*/ + + +/**@{*/ + +#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304 +#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !" +#endif + +#include + +/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */ +#define I2C_READ 1 + +/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */ +#define I2C_WRITE 0 + + +/** + @brief initialize the I2C master interace. Need to be called only once + @return none + */ +extern void i2c_init(void); + + +/** + @brief Terminates the data transfer and releases the I2C bus + @return none + */ +extern void i2c_stop(void); + + +/** + @brief Issues a start condition and sends address and transfer direction + + @param addr address and transfer direction of I2C device + @retval 0 device accessible + @retval 1 failed to access device + */ +extern unsigned char i2c_start(unsigned char addr); + + +/** + @brief Issues a repeated start condition and sends address and transfer direction + + @param addr address and transfer direction of I2C device + @retval 0 device accessible + @retval 1 failed to access device + */ +extern unsigned char i2c_rep_start(unsigned char addr); + + +/** + @brief Issues a start condition and sends address and transfer direction + + If device is busy, use ack polling to wait until device ready + @param addr address and transfer direction of I2C device + @return none + */ +extern void i2c_start_wait(unsigned char addr); + + +/** + @brief Send one byte to I2C device + @param data byte to be transfered + @retval 0 write successful + @retval 1 write failed + */ +extern unsigned char i2c_write(unsigned char data); + + +/** + @brief read one byte from the I2C device, request more data from device + @return byte read from I2C device + */ +extern unsigned char i2c_readAck(void); + +/** + @brief read one byte from the I2C device, read is followed by a stop condition + @return byte read from I2C device + */ +extern unsigned char i2c_readNak(void); + +/** + @brief read one byte from the I2C device + + Implemented as a macro, which calls either @ref i2c_readAck or @ref i2c_readNak + + @param ack 1 send ack, request more data from device
+ 0 send nak, read is followed by a stop condition + @return byte read from I2C device + */ +extern unsigned char i2c_read(unsigned char ack); +#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); + + + +/**@}*/ +#endif diff --git a/code/i2c_peter/twimaster.c b/code/i2c_peter/twimaster.c new file mode 100644 index 0000000..3fc2ddd --- /dev/null +++ b/code/i2c_peter/twimaster.c @@ -0,0 +1,202 @@ +/************************************************************************* +* Title: I2C master library using hardware TWI interface +* Author: Peter Fleury http://jump.to/fleury +* File: $Id: twimaster.c,v 1.4 2015/01/17 12:16:05 peter Exp $ +* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 +* Target: any AVR device with hardware TWI +* Usage: API compatible with I2C Software Library i2cmaster.h +**************************************************************************/ +#include +#include + +#include + + +/* define CPU frequency in hz here if not defined in Makefile */ +#ifndef F_CPU +#define F_CPU 4000000UL +#endif + +/* I2C clock in Hz */ +#define SCL_CLOCK 100000L + + +/************************************************************************* + Initialization of the I2C bus interface. Need to be called only once +*************************************************************************/ +void i2c_init(void) +{ + /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ + + TWSR = 0; /* no prescaler */ + TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */ + +}/* i2c_init */ + + +/************************************************************************* + Issues a start condition and sends address and transfer direction. + return 0 = device accessible, 1= failed to access device +*************************************************************************/ +unsigned char i2c_start(unsigned char address) +{ + uint8_t twst; + + // send START condition + TWCR = (1< #include #include "avr-hd44780/lcd.h" +#include "i2c_peter/i2cmaster.h" +#include "sdi_shield.h" -volatile uint8_t counter = 0; +volatile uint8_t cam = 0; +volatile uint8_t pgm = 0; +volatile uint8_t pvw = 0; +volatile uint8_t valid = 0; + +#define SDI_SHIELD_ADDR 0x84 + +#define VF_BACK_PVW_TALLY_PIN 0 +#define VF_BACK_PGM_TALLY_PIN 1 +#define LENS_PGM_TALLY_PIN 2 +#define VF_FRONT_PGM_TALLY_PIN 3 + +volatile uint8_t pvw_enabled = 1; +volatile uint8_t front_enabled = 1; void enc_init(){ PORTC |= (1<<2) | (1 << 3); @@ -12,26 +27,120 @@ void enc_init(){ } int main(void){ - DDRC |= 1<<0; - DDRC |= 1<<1; - DDRD |= 1<<7; + DDRB |= 1<