From b02a188a3ffba33cfbee010ab36208e688fe570d Mon Sep 17 00:00:00 2001 From: "Ishan S. Patel" Date: Fri, 17 Sep 2021 13:38:33 -0400 Subject: [PATCH] yacwc --- .../1a8b631988403d72167c8d6baec2a73bac7faf7 | 1 + .../2adc7fbb2135c78f19d1a1b2028996567fb9053 | 1 + .../41672a6e402df6011c74e1ae975d7490093855fc | 1 + .../5580302ab4be68f0bc49bf4b1ff420d2f7107178 | 1 + .../687cfc15b1583ba4f8b41f2e61825e1ceba0a3f8 | 1 + .../76643e2f2dd3e91a2db2be5bb80d347d7acaddab | 1 + .../8682dd81be42c9dbff6320a6e76b466c66323e74 | 1 + .../8ed3d0c329f6d5902874651213f7016c3a965cfa | 1 + .../a8f3fbb525877d0d30c84aaf9893fa33f8b025c5 | 1 + .../dd22591090474e37abeef990af4d577cd8e2ffd0 | 1 + .../f5b4f3c1b2460fb4f304c807ea4f51f1d7479b5e | 37 + Makefile | 113 +++ compiler.h | 80 ++ helpers_i2c.c | 32 + helpers_i2c.h | 23 + helpers_uart.c | 94 +++ helpers_uart.h | 68 ++ interrupt_avr8.h | 100 +++ main.c | 432 +++++++++++ ... ispatel@live.com 2021-09-15-19-01-48).xml | 266 +++++++ nbproject/configurations.xml | 266 +++++++ ... ispatel@live.com 2021-09-15-19-01-48).xml | 31 + nbproject/project.xml | 31 + twi0_master.c | 706 ++++++++++++++++++ twi0_master.h | 220 ++++++ twi0_master_example.c | 173 +++++ twi0_master_example.h | 50 ++ 27 files changed, 2732 insertions(+) create mode 100644 .generated_files/flags/default/1a8b631988403d72167c8d6baec2a73bac7faf7 create mode 100644 .generated_files/flags/default/2adc7fbb2135c78f19d1a1b2028996567fb9053 create mode 100644 .generated_files/flags/default/41672a6e402df6011c74e1ae975d7490093855fc create mode 100644 .generated_files/flags/default/5580302ab4be68f0bc49bf4b1ff420d2f7107178 create mode 100644 .generated_files/flags/default/687cfc15b1583ba4f8b41f2e61825e1ceba0a3f8 create mode 100644 .generated_files/flags/default/76643e2f2dd3e91a2db2be5bb80d347d7acaddab create mode 100644 .generated_files/flags/default/8682dd81be42c9dbff6320a6e76b466c66323e74 create mode 100644 .generated_files/flags/default/8ed3d0c329f6d5902874651213f7016c3a965cfa create mode 100644 .generated_files/flags/default/a8f3fbb525877d0d30c84aaf9893fa33f8b025c5 create mode 100644 .generated_files/flags/default/dd22591090474e37abeef990af4d577cd8e2ffd0 create mode 100644 .generated_files/flags/default/f5b4f3c1b2460fb4f304c807ea4f51f1d7479b5e create mode 100644 Makefile create mode 100644 compiler.h create mode 100644 helpers_i2c.c create mode 100644 helpers_i2c.h create mode 100644 helpers_uart.c create mode 100644 helpers_uart.h create mode 100644 interrupt_avr8.h create mode 100644 main.c create mode 100644 nbproject/configurations (SFConflict ispatel@live.com 2021-09-15-19-01-48).xml create mode 100644 nbproject/configurations.xml create mode 100644 nbproject/project (SFConflict ispatel@live.com 2021-09-15-19-01-48).xml create mode 100644 nbproject/project.xml create mode 100644 twi0_master.c create mode 100644 twi0_master.h create mode 100644 twi0_master_example.c create mode 100644 twi0_master_example.h diff --git a/.generated_files/flags/default/1a8b631988403d72167c8d6baec2a73bac7faf7 b/.generated_files/flags/default/1a8b631988403d72167c8d6baec2a73bac7faf7 new file mode 100644 index 0000000..c3421eb --- /dev/null +++ b/.generated_files/flags/default/1a8b631988403d72167c8d6baec2a73bac7faf7 @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/birdptz.X/helpers_uart.c \ No newline at end of file diff --git a/.generated_files/flags/default/2adc7fbb2135c78f19d1a1b2028996567fb9053 b/.generated_files/flags/default/2adc7fbb2135c78f19d1a1b2028996567fb9053 new file mode 100644 index 0000000..dd4938f --- /dev/null +++ b/.generated_files/flags/default/2adc7fbb2135c78f19d1a1b2028996567fb9053 @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/camera_ptz.X/mcc_generated_files/examples/twi0_master_example.c \ No newline at end of file diff --git a/.generated_files/flags/default/41672a6e402df6011c74e1ae975d7490093855fc b/.generated_files/flags/default/41672a6e402df6011c74e1ae975d7490093855fc new file mode 100644 index 0000000..6979274 --- /dev/null +++ b/.generated_files/flags/default/41672a6e402df6011c74e1ae975d7490093855fc @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/birdptz.X/helpers_i2c.c \ No newline at end of file diff --git a/.generated_files/flags/default/5580302ab4be68f0bc49bf4b1ff420d2f7107178 b/.generated_files/flags/default/5580302ab4be68f0bc49bf4b1ff420d2f7107178 new file mode 100644 index 0000000..8974f83 --- /dev/null +++ b/.generated_files/flags/default/5580302ab4be68f0bc49bf4b1ff420d2f7107178 @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/birdptz.X/helpers_uart.c \ No newline at end of file diff --git a/.generated_files/flags/default/687cfc15b1583ba4f8b41f2e61825e1ceba0a3f8 b/.generated_files/flags/default/687cfc15b1583ba4f8b41f2e61825e1ceba0a3f8 new file mode 100644 index 0000000..668fc0c --- /dev/null +++ b/.generated_files/flags/default/687cfc15b1583ba4f8b41f2e61825e1ceba0a3f8 @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/birdptz.X/main.c \ No newline at end of file diff --git a/.generated_files/flags/default/76643e2f2dd3e91a2db2be5bb80d347d7acaddab b/.generated_files/flags/default/76643e2f2dd3e91a2db2be5bb80d347d7acaddab new file mode 100644 index 0000000..862b462 --- /dev/null +++ b/.generated_files/flags/default/76643e2f2dd3e91a2db2be5bb80d347d7acaddab @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/birdptz.X/main.c \ No newline at end of file diff --git a/.generated_files/flags/default/8682dd81be42c9dbff6320a6e76b466c66323e74 b/.generated_files/flags/default/8682dd81be42c9dbff6320a6e76b466c66323e74 new file mode 100644 index 0000000..8289fc1 --- /dev/null +++ b/.generated_files/flags/default/8682dd81be42c9dbff6320a6e76b466c66323e74 @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/birdptz.X/helpers_i2c.c \ No newline at end of file diff --git a/.generated_files/flags/default/8ed3d0c329f6d5902874651213f7016c3a965cfa b/.generated_files/flags/default/8ed3d0c329f6d5902874651213f7016c3a965cfa new file mode 100644 index 0000000..6fedea5 --- /dev/null +++ b/.generated_files/flags/default/8ed3d0c329f6d5902874651213f7016c3a965cfa @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/camera_ptz.X/mcc_generated_files/examples/twi0_master_example.c \ No newline at end of file diff --git a/.generated_files/flags/default/a8f3fbb525877d0d30c84aaf9893fa33f8b025c5 b/.generated_files/flags/default/a8f3fbb525877d0d30c84aaf9893fa33f8b025c5 new file mode 100644 index 0000000..0a36e5e --- /dev/null +++ b/.generated_files/flags/default/a8f3fbb525877d0d30c84aaf9893fa33f8b025c5 @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/camera_ptz.X/mcc_generated_files/src/twi0_master.c \ No newline at end of file diff --git a/.generated_files/flags/default/dd22591090474e37abeef990af4d577cd8e2ffd0 b/.generated_files/flags/default/dd22591090474e37abeef990af4d577cd8e2ffd0 new file mode 100644 index 0000000..d3743d5 --- /dev/null +++ b/.generated_files/flags/default/dd22591090474e37abeef990af4d577cd8e2ffd0 @@ -0,0 +1 @@ + $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -g -DDEBUG -gdwarf-2 -x c -D__$(MP_PROCESSOR_OPTION)__ -mdfp="${DFP_DIR}/xc8" -Wl,--gc-sections -O1 -ffunction-sections -fdata-sections -fshort-enums -funsigned-char -funsigned-bitfields -Wall -DXPRJ_default=$(CND_CONF) $(COMPARISON_BUILD) -gdwarf-3 /home/thebears/Seafile/Designs/AVR/camera_ptz.X/mcc_generated_files/src/twi0_master.c \ No newline at end of file diff --git a/.generated_files/flags/default/f5b4f3c1b2460fb4f304c807ea4f51f1d7479b5e b/.generated_files/flags/default/f5b4f3c1b2460fb4f304c807ea4f51f1d7479b5e new file mode 100644 index 0000000..150f3b1 --- /dev/null +++ b/.generated_files/flags/default/f5b4f3c1b2460fb4f304c807ea4f51f1d7479b5e @@ -0,0 +1,37 @@ +# +# Generated Makefile - do not edit! +# +# +# This file contains information about the location of compilers and other tools. +# If you commmit this file into your revision control server, you will be able to +# to checkout the project and build it from the command line with make. However, +# if more than one person works on the same project, then this file might show +# conflicts since different users are bound to have compilers in different places. +# In that case you might choose to not commit this file and let MPLAB X recreate this file +# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at +# least once so the file gets created and the project can be built. Finally, you can also +# avoid using this file at all if you are only building from the command line with make. +# You can invoke make with the values of the macros: +# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ... +# +PATH_TO_IDE_BIN=/opt/microchip/mplabx/v5.50/mplab_platform/platform/../mplab_ide/modules/../../bin/ +# Adding MPLAB X bin directory to path. +PATH:=/opt/microchip/mplabx/v5.50/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH) +# Path to java used to run MPLAB X when this makefile was created +MP_JAVA_PATH="/opt/microchip/mplabx/v5.50/sys/java/zulu8.40.0.25-ca-fx-jre8.0.222-linux_x64/bin/" +OS_CURRENT="$(shell uname -s)" +MP_CC="/opt/microchip/xc8/v2.32/bin/xc8-cc" +# MP_CPPC is not defined +# MP_BC is not defined +MP_AS="/opt/microchip/xc8/v2.32/bin/xc8-cc" +MP_LD="/opt/microchip/xc8/v2.32/bin/xc8-cc" +MP_AR="/opt/microchip/xc8/v2.32/bin/xc8-ar" +DEP_GEN=${MP_JAVA_PATH}java -jar "/opt/microchip/mplabx/v5.50/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar" +MP_CC_DIR="/opt/microchip/xc8/v2.32/bin" +# MP_CPPC_DIR is not defined +# MP_BC_DIR is not defined +MP_AS_DIR="/opt/microchip/xc8/v2.32/bin" +MP_LD_DIR="/opt/microchip/xc8/v2.32/bin" +MP_AR_DIR="/opt/microchip/xc8/v2.32/bin" +# MP_BC_DIR is not defined +DFP_DIR=/opt/microchip/mplabx/v5.50/packs/Microchip/ATmega_DFP/2.3.126 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fca8e2c --- /dev/null +++ b/Makefile @@ -0,0 +1,113 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin +RANLIB=ranlib + + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... +# WARNING: the IDE does not call this target since it takes a long time to +# simply run make. Instead, the IDE removes the configuration directories +# under build and dist directly without calling make. +# This target is left here so people can do a clean when running a clean +# outside the IDE. + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/compiler.h b/compiler.h new file mode 100644 index 0000000..a2c4d17 --- /dev/null +++ b/compiler.h @@ -0,0 +1,80 @@ +/** + @Company + Microchip Technology Inc. + + @Description + This Source file provides APIs. + Generation Information : + Driver Version : 1.0.0 +*/ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + + +#ifndef UTILS_COMPILER_H +#define UTILS_COMPILER_H + +/** + * \defgroup doc_driver_utils_compiler Compiler abstraction + * \ingroup doc_driver_utils + * + * Compiler abstraction layer and code utilities for 8-bit AVR. + * This module provides various abstraction layers and utilities + * to make code compatible between different compilers. + * + * \{ + */ + +#if defined(__GNUC__) +#include +#include +#elif defined(__ICCAVR__) +#define ENABLE_BIT_DEFINITIONS 1 +#include +#include + +#ifndef CCP_IOREG_gc +#define CCP_IOREG_gc 0xD8 /* CPU_CCP_IOREG_gc */ +#endif +#ifndef CCP_SPM_gc +#define CCP_SPM_gc 0x9D /* CPU_CCP_SPM_gc */ +#endif + +#else +#error Unsupported compiler. +#endif + +#include +#include +#include +#include + +#include "interrupt_avr8.h" + +/** + * \def UNUSED + * \brief Marking \a v as a unused parameter or value. + */ +#define UNUSED(v) (void)(v) + +#endif /* UTILS_COMPILER_H */ diff --git a/helpers_i2c.c b/helpers_i2c.c new file mode 100644 index 0000000..ce18318 --- /dev/null +++ b/helpers_i2c.c @@ -0,0 +1,32 @@ + +#define TWI0_BAUD(F_SCL, T_RISE) \ + ((((((float)10000000 / (float)F_SCL)) - 10 - ((float)10000000 * T_RISE / 1000000))) / 2) + +#include "helpers_i2c.h" + +void i2c_init(void) { + PORTMUX.TWISPIROUTEA = 0x23; + TWI0.CTRLA = 0x14; + + //Debug Run + TWI0.DBGCTRL = 0x00; + + //Master Baud Rate Control + TWI0.MBAUD = (uint8_t)TWI0_BAUD(100000, 0); + + //RIEN disabled; WIEN disabled; QCEN disabled; TIMEOUT DISABLED; SMEN disabled; ENABLE enabled; + TWI0.MCTRLA = 0x01; + + //RIF disabled; WIF disabled; CLKHOLD disabled; ARBLOST disabled; BUSERR disabled; BUSSTATE UNKNOWN; + TWI0.MSTATUS = 0x00; + + //Master Address + TWI0.MADDR = 0x00; + + //FLUSH disabled; ACKACT ACK; MCMD NOACT; + TWI0.MCTRLB = 0x00; + + //Master Data + TWI0.MDATA = 0x00; + +}; \ No newline at end of file diff --git a/helpers_i2c.h b/helpers_i2c.h new file mode 100644 index 0000000..90484a0 --- /dev/null +++ b/helpers_i2c.h @@ -0,0 +1,23 @@ +// more than once. +#ifndef HELPER_I2C_H +#define HELPER_I2C_H + +#include // include processor files - each processor file is guarded. +#include + + +void i2c_init(void); + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + // TODO If C++ is being used, regular C code needs function names to have C + // linkage so the functions can be used by the c code. + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XC_HEADER_TEMPLATE_H */ + diff --git a/helpers_uart.c b/helpers_uart.c new file mode 100644 index 0000000..39e0f81 --- /dev/null +++ b/helpers_uart.c @@ -0,0 +1,94 @@ +#include "helpers_uart.h" + + + +void USART0_init(void) { + PORTA.DIR &= ~PIN1_bm; + PORTA.DIR |= PIN0_bm; + + USART0.BAUD = (uint16_t) USART0_BAUD_RATE(9600); + USART0.CTRLB |= USART_TXEN_bm; +} + +void USART0_sendChar(char c) { + while (!(USART0.STATUS & USART_DREIF_bm)) { + ; + } + USART0.TXDATAL = c; +} + + + + +void USART0_sendString(const char *str) { + for (size_t i = 0; i < strlen(str); i++) { + USART0_sendChar(str[i]); + } +} + +void uart_print_uint16(uint16_t meas, const char* buf) { + + sprintf(array, "%u", meas); + USART0_sendString(" "); + USART0_sendString(array); + USART0_sendString(" "); + USART0_sendString(buf); + +} + +void uart_print_float(float meas, const char* buf) { + dtostrf(meas, 3, 4, array); + USART0_sendString(" "); + USART0_sendString(array); + USART0_sendString(" "); + USART0_sendString(buf); + +} + + +void uart_print_bool(bool din, const char* buf) +{ + USART0_sendString(" "); + if (din) + { + USART0_sendString("TRUE "); + } else + { + USART0_sendString("FALSE"); + } + USART0_sendString(" "); + USART0_sendString(buf); + +} + +void uart_print_binary(unsigned char vin, const char* buf) { + + USART0_sendString(" "); + + int binary[9]; + for (int n = 0; n < 8; n++) + binary[7 - n] = (vin >> n) & 1; + + + char str[1]; + for (int n = 0; n < 8; n++) { + sprintf(str, "%d", binary[n]); + USART0_sendString(str); + } + + USART0_sendString(" "); + USART0_sendString(buf); + +} + +void uart_print_uint8(uint8_t vin, const char* buf) { + + USART0_sendString(" "); + sprintf(array, "%u", vin); + + USART0_sendString(array); + USART0_sendString(" "); + USART0_sendString(buf); + +} + diff --git a/helpers_uart.h b/helpers_uart.h new file mode 100644 index 0000000..e697542 --- /dev/null +++ b/helpers_uart.h @@ -0,0 +1,68 @@ +/* Microchip Technology Inc. and its subsidiaries. You may use this software + * and any derivatives exclusively with Microchip products. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION + * WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. + * + * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS + * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE + * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS + * IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF + * ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + * MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE + * TERMS. + */ + +/* + * File: + * Author: + * Comments: + * Revision history: + */ + +// This is a guard condition so that contents of this file are not included +// more than once. +#ifndef HELPER_UART_H +#define HELPER_UART_H + +#include // include processor files - each processor file is guarded. + + +char array[16]; +#include +#include +#include +#include +#include +#define USART0_BAUD_RATE(BAUD_RATE) ((float)(3333333 * 64 / (16 * (float)BAUD_RATE)) + 0.5) + +void USART0_init(void); +void USART0_sendChar(char c); +void USART0_sendString(const char *str); +void uart_print_uint16(uint16_t meas, const char* buf); +void uart_print_float(float meas, const char* buf); +void uart_print_binary(unsigned char vin, const char* buf); +void uart_print_uint8(uint8_t vin, const char* buf); +void uart_print_bool(bool din, const char* buf); + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + // TODO If C++ is being used, regular C code needs function names to have C + // linkage so the functions can be used by the c code. + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XC_HEADER_TEMPLATE_H */ + diff --git a/interrupt_avr8.h b/interrupt_avr8.h new file mode 100644 index 0000000..b7e08f9 --- /dev/null +++ b/interrupt_avr8.h @@ -0,0 +1,100 @@ +/** + @Company + Microchip Technology Inc. + + @Description + This Source file provides APIs. + Generation Information : + Driver Version : 1.0.0 +*/ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + + +/** + * \defgroup doc_driver_utils_interrupts ISR abstraction + * \ingroup doc_driver_utils + * + * Interrupt-related functionality. + * + * \{ + */ + +#ifndef UTILS_INTERRUPT_AVR8_H +#define UTILS_INTERRUPT_AVR8_H + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +#include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + ISR(FOO_vect) + { + ... + } +\endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +#define ISR(vect) +#elif defined(__GNUC__) +#include +#elif defined(__ICCAVR__) +#define __ISR(x) _Pragma(#x) +#define ISR(vect) __ISR(vector = vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#ifdef __GNUC__ +#define cpu_irq_enable() sei() +#define cpu_irq_disable() cli() +#else +#define cpu_irq_enable() __enable_interrupt() +#define cpu_irq_disable() __disable_interrupt() +#endif + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_AVR8_H */ diff --git a/main.c b/main.c new file mode 100644 index 0000000..69e6a41 --- /dev/null +++ b/main.c @@ -0,0 +1,432 @@ +/* + * File: main.c + * Author: thebears + * + * Created on September 13, 2021, 3:12 PM + */ + +#define F_CPU 3333333 +#define USART0_BAUD_RATE(BAUD_RATE) ((float)(3333333 * 64 / (16 * (float)BAUD_RATE)) + 0.5) +#include +#include +#include +#include +#include +#include +#include "helpers_uart.h" +//#include "helpers_i2c.h" +#include +#include +#include "twi0_master_example.h" +uint16_t adcVal; +uint8_t val; +void ADC0_init(void); +uint16_t ADC0_read_a(void); +uint16_t ADC0_read_b(void); +bool limit_zoom = false; +bool limit_focus = false; + + +uint16_t step_n_zoom = 0; +uint16_t step_n_focus = 0; +uint16_t step_n_iris = 0; + + +#define max_zoom_steps 2994 +#define max_focus_steps 5180 +#define max_iris_steps 77 +uint8_t phase; + +int8_t last_dir_zoom = 0; +int8_t last_dir_focus = 0; + +bool focus_iris_max; +bool focus_iris_min; +bool focus_zoom_max; +bool focus_zoom_min; +bool focus_past_max; +bool focus_past_min; +// Zoom +#define m1_p1 2 +#define m1_p2 3 +#define m1_p3 4 +#define m1_p4 5 +#define deltime1 750 + +// Focus +#define m2_p1 5 +#define m2_p2 4 +#define m2_p3 1 +#define m2_p4 0 +#define deltime2 750 + +// P-Iris +#define m3_p1 4 +#define m3_p2 5 +#define m3_p3 6 +#define m3_p4 7 +#define deltime3 2500 + +#define delay_time 100 + + +void step_phased(struct PORT_struct * p1, struct PORT_struct * p2, struct PORT_struct * p3, struct PORT_struct * p4, uint8_t m1, uint8_t m2, uint8_t m3, uint8_t m4, uint8_t phase) { + + + if (phase == 0) { + p1->OUTSET = _BV(m1); + p2->OUTCLR = _BV(m2); + p3->OUTSET = _BV(m3); + p4->OUTCLR = _BV(m4); + } else if (phase == 1) { + p1->OUTCLR = _BV(m1); + p2->OUTSET = _BV(m2); + p3->OUTSET = _BV(m3); + p4->OUTCLR = _BV(m4); + } else if (phase == 2) { + p1->OUTCLR = _BV(m1); + p2->OUTSET = _BV(m2); + p3->OUTCLR = _BV(m3); + p4->OUTSET = _BV(m4); + } else if (phase == 3) { + p1->OUTSET = _BV(m1); + p2->OUTCLR = _BV(m2); + p3->OUTCLR = _BV(m3); + p4->OUTSET = _BV(m4); + } + +} + +void step_iris_phased(int steps) { + + + + for (int i = 0; i < abs(steps); i++) { + phase = abs(step_n_iris % 4); + focus_iris_max = (step_n_iris >= max_iris_steps) && (steps > 0); + focus_iris_min = (step_n_iris <= 0) && (steps < 0); + + if (focus_iris_max || focus_iris_min) { + return; + } + + step_phased(&PORTC, &PORTC, &PORTC, &PORTC, m3_p1, m3_p2, m3_p3, m3_p4, phase); + _delay_us(deltime3); + if (steps > 0) { + step_n_iris++; + } else if (steps < 0) { + step_n_iris--; + } + } +} + +void step_zoom_phased(int steps) { + + + for (int i = 0; i < abs(steps); i++) { + phase = abs(step_n_zoom % 4); + focus_zoom_max = (step_n_zoom >= max_zoom_steps) && (steps > 0); + focus_zoom_min = (step_n_zoom <= 0) && (steps < 0); + if (focus_zoom_max || focus_zoom_min) { + return; + } + + step_phased(&PORTA, &PORTA, &PORTA, &PORTA, m1_p1, m1_p2, m1_p3, m1_p4, phase); + _delay_us(deltime1); + if (steps > 0) { + step_n_zoom++; + } else if (steps < 0) { + step_n_zoom--; + } + + + } + +} + +void step_focus_phased(int steps) { + for (int i = 0; i < abs(steps); i++) { + focus_past_max = (step_n_focus >= max_focus_steps) && (steps > 0); + focus_past_min = (step_n_focus <= 0) && (steps < 0); + if (focus_past_max || focus_past_min) { + return; + } + + phase = abs(step_n_focus % 4); + step_phased(&PORTB, &PORTB, &PORTC, &PORTC, m2_p1, m2_p2, m2_p3, m2_p4, phase); + _delay_us(deltime2); + if (steps > 0) { + step_n_focus++; + } else if (steps < 0) { + step_n_focus--; + } + } + +} + +bool update_zoom_limit() { + if (PORTD.IN & PIN0_bm) { + limit_zoom = false; + } else { + limit_zoom = true; + } + return limit_zoom; +} + +bool update_focus_limit() { + + if (PORTD.IN & PIN1_bm) { + limit_focus = false; + } else { + limit_focus = true; + } + return limit_focus; +} + +void ir_filter_on() { + PORTB.OUTCLR = _BV(2); + PORTB.OUTSET = _BV(3); + _delay_ms(100); + PORTB.OUTCLR = _BV(3); +} + +void ir_filter_off() { + PORTB.OUTCLR = _BV(3); + PORTB.OUTSET = _BV(2); + _delay_ms(100); + PORTB.OUTCLR = _BV(2); +} + +void home_focus() { + step_n_focus = max_focus_steps + 200; + step_focus_phased(-100); + for (int i = 0; i < max_focus_steps; i++) { + step_focus_phased(-1); + if (update_focus_limit()) { + break; + } + } + step_n_focus = 0; +} + +void home_zoom() { + step_n_zoom = max_zoom_steps + 200; + step_zoom_phased(-100); + for (int i = 0; i < max_zoom_steps; i++) { + step_zoom_phased(-1); + if (update_zoom_limit()) { + break; + } + } + step_n_zoom = 0; +} + +void home_iris() { + step_n_iris = max_iris_steps + 200; + step_iris_phased(-100); + step_n_iris = 0; + +} + +ISR(PORTD_PORT_vect) { + + if (PORTD.INTFLAGS & PIN1_bm) { + update_focus_limit(); + PORTD.INTFLAGS &= PIN1_bm; + } else if (PORTD.INTFLAGS & PIN0_bm) { + update_zoom_limit(); + PORTD.INTFLAGS &= PIN0_bm; + + }; +} + +int main(void) { + + + PORTA.OUTSET = _BV(6); + + + PORTD.DIRCLR = PIN0_bm; + PORTD.DIRCLR = PIN1_bm; + + PORTD.PIN0CTRL |= PORT_ISC_BOTHEDGES_gc; + PORTD.PIN1CTRL |= PORT_ISC_BOTHEDGES_gc; + + // Turn on 3.3V relay + PORTA.DIRSET = _BV(6); + + + // Zoom + PORTA.DIRSET = _BV(m1_p1); + PORTA.DIRSET = _BV(m1_p4); + PORTA.DIRSET = _BV(m1_p2); + PORTA.DIRSET = _BV(m1_p3); + + // Focus + PORTB.DIRSET = _BV(m2_p1); + PORTB.DIRSET = _BV(m2_p2); + PORTC.DIRSET = _BV(m2_p3); + PORTC.DIRSET = _BV(m2_p4); + + // Iris motor + PORTC.DIRSET = _BV(m3_p1); + PORTC.DIRSET = _BV(m3_p2); + PORTC.DIRSET = _BV(m3_p3); + PORTC.DIRSET = _BV(m3_p4); + + // IR Filter + PORTB.DIRSET = _BV(2); + PORTB.DIRSET = _BV(3); + + + + + + + + // sei(); + PORTMUX.TWISPIROUTEA = 0x23; + + _delay_ms(250); + I2C0_Initialize(); + I2C0_example_write1ByteRegister(32, 0x00, 0x00); + I2C0_example_write1ByteRegister(32, 0x09, 0xFF); + USART0_init(); + USART0_sendString("Started\n"); + + _delay_ms(250); + I2C0_example_write1ByteRegister(32, 0x09, 0x00); + _delay_ms(250); + I2C0_example_write1ByteRegister(32, 0x09, 0xFF); + + USART0_sendString("focus->"); + home_focus(); + USART0_sendString("\niris->"); + home_iris(); + USART0_sendString("\nhome->"); + home_zoom(); +USART0_sendString("\n"); + + while (1) { + step_zoom_phased(6000); + step_iris_phased(100); + step_focus_phased(2000); + + + step_zoom_phased(-6000); +// + step_iris_phased(-100); + step_focus_phased(-2000); + + + + _delay_ms(250); + + // ir_filter_off(); + // step_iris_phased(76); + // step_iris_phased(-76); + // _delay_ms(25); + // ir_filter_on(); + // step_iris(19); + //_delay_ms(250); + + // _delay_ms(500); + + // _delay_ms(500); + // + // step_focus(1000); + // step_focus(-1000); + // limit_focus = false; + // step_focus(-1000); + // limit_focus = false; + // step_zoom(1000); + // limit_zoom = false; + // step_zoom(-1000); + // limit_zoom = false; + + // step_focus(1000); + // if (limit_focus) + // { + // limit_focus = false; + // step_focus(-1000); + // } + + // step(1000); + // step2(1000); + + // _delay_ms(100); + USART0_sendString("-"); + + // uart_print_uint8(PORTD.IN & PIN0_bm,"p0 "); + // uart_print_uint8(PORTD.IN & PIN1_bm,"p1 \n ") + // step2(1000); + // PORTA.OUTSET = _BV(m1_p1); + // PORTA.OUTSET = _BV(m1_p2); + // PORTA.OUTSET = _BV(m1_p3); + // PORTA.OUTSET = _BV(m1_p4); + // + // PORTB.OUTSET = _BV(m2_p1); + // PORTB.OUTSET = _BV(m2_p2); + // PORTC.OUTSET = _BV(m2_p3); + // PORTC.OUTSET = _BV(m2_p4); + + // uart_print_binary(val, " \n"); + // adcVal = ADC0_read_a(); + // uart_print_uint8(adcVal, " "); + // adcVal = ADC0_read_b(); + // uart_print_uint8(adcVal, " "); + + // step(); + // step2(); + // USART0_sendString("---\n"); + } + + return 0; +} + +void ADC0_init(void) { + + PORTD.PIN0CTRL &= ~PORT_ISC_gm; + PORTD.PIN0CTRL |= PORT_ISC_INPUT_DISABLE_gc; + PORTD.PIN0CTRL &= ~PORT_PULLUPEN_bm; + + PORTD.PIN1CTRL &= ~PORT_ISC_gm; + PORTD.PIN1CTRL |= PORT_ISC_INPUT_DISABLE_gc; + PORTD.PIN1CTRL &= ~PORT_PULLUPEN_bm; + + ADC0.CTRLC = ADC_PRESC_DIV4_gc + | ADC_REFSEL_VDDREF_gc; + ADC0.CTRLA = ADC_ENABLE_bm /* ADC Enable: enabled */ + | ADC_RESSEL_10BIT_gc; /* 10-bit mode */ + /* Select ADC channel */ + +} + +uint16_t ADC0_read_a(void) { + /* Start ADC conversion */ + /* Start ADC conversion */ + ADC0.MUXPOS = ADC_MUXPOS_AIN0_gc; + ADC0.COMMAND = ADC_STCONV_bm; + /* Wait until ADC conversion done */ + while (!(ADC0.INTFLAGS & ADC_RESRDY_bm)) { + ; + } + /* Clear the interrupt flag by writing 1: */ + ADC0.INTFLAGS = ADC_RESRDY_bm; + return ADC0.RES; +} + +uint16_t ADC0_read_b(void) { + /* Start ADC conversion */ + /* Start ADC conversion */ + ADC0.MUXPOS = ADC_MUXPOS_AIN1_gc; + ADC0.COMMAND = ADC_STCONV_bm; + /* Wait until ADC conversion done */ + while (!(ADC0.INTFLAGS & ADC_RESRDY_bm)) { + ; + } + /* Clear the interrupt flag by writing 1: */ + ADC0.INTFLAGS = ADC_RESRDY_bm; + return ADC0.RES; +} + diff --git a/nbproject/configurations (SFConflict ispatel@live.com 2021-09-15-19-01-48).xml b/nbproject/configurations (SFConflict ispatel@live.com 2021-09-15-19-01-48).xml new file mode 100644 index 0000000..d90164b --- /dev/null +++ b/nbproject/configurations (SFConflict ispatel@live.com 2021-09-15-19-01-48).xml @@ -0,0 +1,266 @@ + + + + + helpers_uart.h + helpers_i2c.h + + + + + helpers_uart.c + helpers_i2c.c + + + Makefile + + main.c + ../camera_ptz.X/mcc_generated_files/src/twi0_master.c + ../camera_ptz.X/mcc_generated_files/include/twi0_master.h + ../camera_ptz.X/mcc_generated_files/examples/twi0_master_example.c + ../camera_ptz.X/mcc_generated_files/examples/twi0_master_example.h + + + ../camera_ptz.X/mcc_generated_files/src + ../camera_ptz.X/mcc_generated_files/include + ../camera_ptz.X/mcc_generated_files/examples + + Makefile + + + + localhost + ATmega4809 + + + AtmelIceTool + XC8 + 2.32 + 2 + + + + + + + + + + + + + + + false + false + + + + + + + false + false + + false + + false + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml new file mode 100644 index 0000000..bdc6044 --- /dev/null +++ b/nbproject/configurations.xml @@ -0,0 +1,266 @@ + + + + + helpers_uart.h + helpers_i2c.h + ../camera_ptz.X/mcc_generated_files/include/twi0_master.h + ../camera_ptz.X/mcc_generated_files/examples/twi0_master_example.h + + + + + helpers_uart.c + helpers_i2c.c + ../camera_ptz.X/mcc_generated_files/src/twi0_master.c + ../camera_ptz.X/mcc_generated_files/examples/twi0_master_example.c + + + Makefile + + main.c + + + ../camera_ptz.X/mcc_generated_files/src + ../camera_ptz.X/mcc_generated_files/include + ../camera_ptz.X/mcc_generated_files/examples + + Makefile + + + + localhost + ATmega4809 + + + AtmelIceTool + XC8 + 2.32 + 2 + + + + + + + + + + + + + + + false + false + + + + + + + false + false + + false + + false + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/project (SFConflict ispatel@live.com 2021-09-15-19-01-48).xml b/nbproject/project (SFConflict ispatel@live.com 2021-09-15-19-01-48).xml new file mode 100644 index 0000000..64f1611 --- /dev/null +++ b/nbproject/project (SFConflict ispatel@live.com 2021-09-15-19-01-48).xml @@ -0,0 +1,31 @@ + + + com.microchip.mplab.nbide.embedded.makeproject + + + birdptz + e85c39d7-f632-41a5-8f48-d9660cba8332 + 0 + c + + h + + ISO-8859-1 + + + ../camera_ptz.X/mcc_generated_files/src + ../camera_ptz.X/mcc_generated_files/include + ../camera_ptz.X/mcc_generated_files/examples + + + + default + 2 + + + + false + + + + diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..64f1611 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,31 @@ + + + com.microchip.mplab.nbide.embedded.makeproject + + + birdptz + e85c39d7-f632-41a5-8f48-d9660cba8332 + 0 + c + + h + + ISO-8859-1 + + + ../camera_ptz.X/mcc_generated_files/src + ../camera_ptz.X/mcc_generated_files/include + ../camera_ptz.X/mcc_generated_files/examples + + + + default + 2 + + + + false + + + + diff --git a/twi0_master.c b/twi0_master.c new file mode 100644 index 0000000..8744938 --- /dev/null +++ b/twi0_master.c @@ -0,0 +1,706 @@ +/** + @Company + Microchip Technology Inc. + + @Description + This Source file provides APIs. + Generation Information : + Driver Version : 1.0.0 +*/ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + + +#include "../include/twi0_master.h" +#include +#include + +/***************************************************************************/ +// I2C STATES +typedef enum { + I2C0_IDLE = 0, + I2C0_SEND_ADR_READ, + I2C0_SEND_ADR_WRITE, + I2C0_TX, + I2C0_RX, + I2C0_TX_EMPTY, + I2C0_SEND_RESTART_READ, + I2C0_SEND_RESTART_WRITE, + I2C0_SEND_RESTART, + I2C0_SEND_STOP, + I2C0_RX_DO_ACK, + I2C0_TX_DO_ACK, + I2C0_RX_DO_RX_NACK_STOP, + I2C0_RX_DO_NACK_RESTART, + I2C0_RESET, + I2C0_ADDRESS_NACK, + I2C0_BUS_COLLISION, + I2C0_BUS_ERROR +} twi0_fsm_states_t; + +// I2C Event Callback List +typedef enum { + I2C0_DATA_COMPLETE = 0, + I2C0_WRITE_COLLISION, + I2C0_ADDRESSNACK, + I2C0_DATA_NACK, + I2C0_TIMEOUT, + I2C0_NULL +} I2C0_callbackIndex_t; + +// I2C Status Structure +typedef struct { + twi0_callback_t callbackTable[6]; + void * callbackPayload[6]; + uint16_t timeout; + uint16_t timeout_value; + twi0_address_t address; + uint8_t * data_ptr; + size_t data_length; + twi0_fsm_states_t state; + twi0_error_t error; + unsigned addressNACKCheck : 1; + unsigned busy : 1; + unsigned inUse : 1; + unsigned bufferFree : 1; + /*if timeoutDriverEnabled + timerStruct_t timeout; + */ +} I2C0_status_t; +I2C0_status_t I2C0_status = {0}; +typedef twi0_fsm_states_t(stateHandlerFunction)(void); + +/* I2C Interfaces */ +void I2C0_Poller(void); + +/* I2C Internal API's */ +/* Master */ +void I2C0_MasterOpen(void); +void I2C0_MasterClose(void); +char I2C0_MasterGetRxData(void); +void I2C0_MasterTxData(char d); +void I2C0_MasterTxAddr(char d); +void I2C0_MasterResetBus(void); +void I2C0_MasterIsRxOrTx(void); +void I2C0_MasterStop(void); +bool I2C0_MasterIsNack(void); +void I2C0_MasterSendAck(void); +void I2C0_MasterSendNack(void); +void I2C0_MasterClearBusCollision(void); +bool I2C0_MasterBusErrorOverride(); +bool I2C0_MasterArbitrationlostOverride(void); +void I2C0_MasterEnableIrq(void); +bool I2C0_MasterIsIrqEnabled(void); +void I2C0_MasterDisableIrq(void); +void I2C0_MasterClearIrq(void); +void I2C0_MasterWaitForEvent(void); +static void I2C0_set_callback(I2C0_callbackIndex_t idx, twi0_callback_t cb, void *funPtr); +static twi0_operations_t I2C0_RETURN_STOP(void *funPtr); +static twi0_operations_t I2C0_RETURN_RESET(void *funPtr); +static void I2C0_MasterIsr(void); + +/* Helper Functions */ +static twi0_fsm_states_t I2C0_DO_IDLE(void); +static twi0_fsm_states_t I2C0_DO_SEND_ADR_READ(void); +static twi0_fsm_states_t I2C0_DO_SEND_ADR_WRITE(void); +static twi0_fsm_states_t I2C0_DO_TX(void); +static twi0_fsm_states_t I2C0_DO_RX(void); +static twi0_fsm_states_t I2C0_DO_TX_EMPTY(void); +static twi0_fsm_states_t I2C0_DO_SEND_RESTART_READ(void); +static twi0_fsm_states_t I2C0_DO_SEND_RESTART_WRITE(void); +static twi0_fsm_states_t I2C0_DO_SEND_RESTART(void); +static twi0_fsm_states_t I2C0_DO_SEND_STOP(void); +static twi0_fsm_states_t I2C0_DO_RX_ACK(void); +static twi0_fsm_states_t I2C0_DO_TX_ACK(void); +static twi0_fsm_states_t I2C0_DO_RX_NACK_STOP(void); +static twi0_fsm_states_t I2C0_DO_RX_NACK_RESTART(void); +static twi0_fsm_states_t I2C0_DO_RESET(void); +static twi0_fsm_states_t I2C0_DO_ADDRESS_NACK(void); +static twi0_fsm_states_t I2C0_DO_BUS_COLLISION(void); +static twi0_fsm_states_t I2C0_DO_BUS_ERROR(void); + +typedef twi0_fsm_states_t(stateHandlerFunction)(void); +stateHandlerFunction *I2C0_fsmStateTable[] = { + I2C0_DO_IDLE, // I2C_IDLE + I2C0_DO_SEND_ADR_READ, // I2C_SEND_ADR_READ + I2C0_DO_SEND_ADR_WRITE, // I2C_SEND_ADR_WRITE + I2C0_DO_TX, // I2C_TX + I2C0_DO_RX, // I2C_RX + I2C0_DO_TX_EMPTY, // I2C_TX_EMPTY + I2C0_DO_SEND_RESTART_READ, // I2C_SEND_RESTART_READ + I2C0_DO_SEND_RESTART_WRITE, // I2C_SEND_RESTART_WRITE + I2C0_DO_SEND_RESTART, // I2C_SEND_RESTART + I2C0_DO_SEND_STOP, // I2C_SEND_STOP + I2C0_DO_RX_ACK, // I2C_RX_DO_ACK + I2C0_DO_TX_ACK, // I2C_TX_DO_ACK + I2C0_DO_RX_NACK_STOP, // I2C_RX_DO_NACK_STOP + I2C0_DO_RX_NACK_RESTART, // I2C_RX_DO_NACK_RESTART + I2C0_DO_RESET, // I2C_RESET + I2C0_DO_ADDRESS_NACK, // I2C_ADDRESS_NACK + I2C0_DO_BUS_COLLISION, // I2C_BUS_COLLISION + I2C0_DO_BUS_ERROR // I2C_BUS_ERROR +}; + +void I2C0_SetDataCompleteCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C0_DATA_COMPLETE, cb, funPtr); +} + +void I2C0_SetWriteCollisionCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C0_WRITE_COLLISION, cb, funPtr); +} + +void I2C0_SetAddressNackCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C0_ADDRESSNACK, cb, funPtr); +} + +void I2C0_SetDataNackCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C0_DATA_NACK, cb, funPtr); +} + +void I2C0_SetTimeoutCallback(twi0_callback_t cb, void *funPtr) +{ + I2C0_set_callback(I2C0_TIMEOUT, cb, funPtr); +} + +uint8_t I2C0_Initialize() +{ + //SDASETUP 8CYC; SDAHOLD 50NS; FMPEN disabled; + TWI0.CTRLA = 0x14; + + //Debug Run + TWI0.DBGCTRL = 0x00; + + //Master Baud Rate Control + TWI0.MBAUD = (uint8_t)TWI0_BAUD(100000, 0); + + //RIEN disabled; WIEN disabled; QCEN disabled; TIMEOUT DISABLED; SMEN disabled; ENABLE enabled; + TWI0.MCTRLA = 0x01; + + //RIF disabled; WIF disabled; CLKHOLD disabled; ARBLOST disabled; BUSERR disabled; BUSSTATE UNKNOWN; + TWI0.MSTATUS = 0x00; + + //Master Address + TWI0.MADDR = 0x00; + + //FLUSH disabled; ACKACT ACK; MCMD NOACT; + TWI0.MCTRLB = 0x00; + + //Master Data + TWI0.MDATA = 0x00; + + return 0; +} + +// when you call open, you supply a device address. +// if you get the bus, the function returns true +twi0_error_t I2C0_Open(twi0_address_t address) +{ + twi0_error_t ret = I2C0_BUSY; + + if (!I2C0_status.inUse) { + I2C0_status.address = address; + I2C0_status.busy = 0; + I2C0_status.inUse = 1; + I2C0_status.addressNACKCheck = 0; + I2C0_status.state = I2C0_RESET; + I2C0_status.timeout_value = 500; // MCC should determine a reasonable starting value here. + I2C0_status.bufferFree = 1; + + // set all the call backs to a default of sending stop + I2C0_status.callbackTable[I2C0_DATA_COMPLETE] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[I2C0_DATA_COMPLETE] = NULL; + I2C0_status.callbackTable[I2C0_WRITE_COLLISION] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[I2C0_WRITE_COLLISION] = NULL; + I2C0_status.callbackTable[I2C0_ADDRESSNACK] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[I2C0_ADDRESSNACK] = NULL; + I2C0_status.callbackTable[I2C0_DATA_NACK] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[I2C0_DATA_NACK] = NULL; + I2C0_status.callbackTable[I2C0_TIMEOUT] = I2C0_RETURN_RESET; + I2C0_status.callbackPayload[I2C0_TIMEOUT] = NULL; + + I2C0_MasterResetBus(); + // Reset module + I2C0_MasterClearIrq(); + + ret = I2C0_NOERR; + } + return ret; +} + +void I2C0_SetAddress(twi0_address_t address) +{ + I2C0_status.address = address; +} + +// close the bus if it is not busy +twi0_error_t I2C0_Close(void) +{ + twi0_error_t ret = I2C0_BUSY; + // Bus is in error state, reset I2C hardware and report error + if (I2C0_MasterBusErrorOverride()) { + I2C0_status.busy = false; + I2C0_status.error = I2C0_FAIL; + } + if (!I2C0_status.busy) { + I2C0_status.inUse = 0; + // close it down + I2C0_status.address = 0xff; // 8-bit address is invalid so this is FREE + I2C0_MasterClearIrq(); + I2C0_MasterDisableIrq(); + ret = I2C0_status.error; + } + return ret; +} + +void I2C0_SetTimeout(uint8_t to) +{ + I2C0_MasterDisableIrq(); + I2C0_status.timeout_value = to; + I2C0_MasterEnableIrq(); +} + +void I2C0_SetBuffer(void *buffer, size_t bufferSize) +{ + if (I2C0_status.bufferFree) { + I2C0_status.data_ptr = buffer; + I2C0_status.data_length = bufferSize; + I2C0_status.bufferFree = false; + } +} +twi0_error_t I2C0_MasterOperation(bool read) +{ + twi0_error_t ret = I2C0_BUSY; + if (!I2C0_status.busy) { + I2C0_status.busy = true; + ret = I2C0_NOERR; + + if (read) { + I2C0_status.state = I2C0_SEND_ADR_READ; + } else { + I2C0_status.state = I2C0_SEND_ADR_WRITE; + } + I2C0_MasterIsr(); + + I2C0_Poller(); + } + return ret; +} + +twi0_error_t I2C0_MasterRead(void) + +{ + return I2C0_MasterOperation(true); +} + + + +twi0_error_t I2C0_MasterWrite(void) +{ + return I2C0_MasterOperation(false); +} + +/************************************************************************/ +/* Helper Functions */ +/************************************************************************/ + +void I2C0_Poller(void) +{ + while (I2C0_status.busy) + { + I2C0_MasterWaitForEvent(); + I2C0_MasterIsr(); + } +} + +static twi0_fsm_states_t I2C0_DO_RESET(void) +{ + I2C0_MasterResetBus(); + I2C0_status.busy = false; // Bus Free + I2C0_status.error = I2C0_NOERR; + return I2C0_RESET; // park the FSM on reset +} + +static twi0_fsm_states_t I2C0_DO_IDLE(void) +{ + I2C0_status.busy = false; // Bus Free + I2C0_status.error = I2C0_NOERR; + return I2C0_IDLE; // park the FSM on IDLE +} + +static twi0_fsm_states_t I2C0_DO_SEND_RESTART_READ(void) +{ + return I2C0_DO_SEND_ADR_READ(); +} + +static twi0_fsm_states_t I2C0_DO_SEND_RESTART_WRITE(void) +{ + return I2C0_DO_SEND_ADR_WRITE(); +} + +static twi0_fsm_states_t I2C0_DO_SEND_RESTART(void) +{ + return I2C0_DO_SEND_ADR_READ(); +} + +static twi0_fsm_states_t I2C0_DO_SEND_STOP(void) +{ + I2C0_MasterStop(); + return I2C0_DO_IDLE(); +} + +// TODO: probably need 2 addressNACK's one from read and one from write. +// the do NACK before RESTART or STOP is a special case that a new state simplifies. +static twi0_fsm_states_t I2C0_DO_ADDRESS_NACK(void) +{ + I2C0_status.addressNACKCheck = 0; + I2C0_status.error = I2C0_FAIL; + switch (I2C0_status.callbackTable[I2C0_ADDRESSNACK](I2C0_status.callbackPayload[I2C0_ADDRESSNACK])) { + case I2C0_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C0_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + default: + return I2C0_DO_SEND_STOP(); + } +} + +static twi0_fsm_states_t I2C0_DO_SEND_ADR_READ(void) +{ + + I2C0_status.addressNACKCheck = 1; + I2C0_MasterTxAddr(I2C0_status.address << 1 | 1); + return I2C0_RX; +} + +static twi0_fsm_states_t I2C0_DO_SEND_ADR_WRITE(void) +{ + + I2C0_status.addressNACKCheck = 1; + I2C0_MasterTxAddr(I2C0_status.address << 1); + return I2C0_TX; +} + +static twi0_fsm_states_t I2C0_DO_RX_ACK(void) +{ + I2C0_MasterSendAck(); + return I2C0_RX; +} + +static twi0_fsm_states_t I2C0_DO_TX_ACK(void) +{ + I2C0_MasterSendAck(); + return I2C0_TX; +} + +static twi0_fsm_states_t I2C0_DO_RX_NACK_STOP(void) +{ + I2C0_MasterSendNack(); + I2C0_MasterStop(); + return I2C0_DO_IDLE(); +} + +static twi0_fsm_states_t I2C0_DO_RX_NACK_RESTART(void) +{ + I2C0_MasterSendNack(); + return I2C0_SEND_RESTART; +} + +static twi0_fsm_states_t I2C0_DO_TX(void) +{ + if (I2C0_MasterIsNack()) // Slave replied with NACK + { + switch (I2C0_status.callbackTable[I2C0_DATA_NACK](I2C0_status.callbackPayload[I2C0_DATA_NACK])) { + case I2C0_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C0_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + default: + case I2C0_CONTINUE: + case I2C0_STOP: + return I2C0_DO_SEND_STOP(); + } + } else { + I2C0_status.addressNACKCheck = 0; + I2C0_MasterTxData(*I2C0_status.data_ptr++); + return (--I2C0_status.data_length) ? I2C0_TX : I2C0_TX_EMPTY; + } +} + +static twi0_fsm_states_t I2C0_DO_RX(void) +{ + I2C0_status.addressNACKCheck = 0; + + if (I2C0_status.data_length == 1) + I2C0_MasterSendNack(); // Next byte will be last to be received, setup NACK + else + I2C0_MasterSendAck(); // More bytes to receive, setup ACK + + if (--I2C0_status.data_length) { + *I2C0_status.data_ptr = I2C0_MasterGetRxData(); + I2C0_status.data_ptr++; + I2C0_MasterIsRxOrTx(); + return I2C0_RX; + } else { + *I2C0_status.data_ptr = I2C0_MasterGetRxData(); + I2C0_status.data_ptr++; + I2C0_status.bufferFree = true; + switch (I2C0_status.callbackTable[I2C0_DATA_COMPLETE](I2C0_status.callbackPayload[I2C0_DATA_COMPLETE])) { + case I2C0_RESTART_WRITE: + case I2C0_RESTART_READ: + return I2C0_DO_RX_NACK_RESTART(); + default: + case I2C0_CONTINUE: + case I2C0_STOP: + return I2C0_DO_RX_NACK_STOP(); + } + } +} + +static twi0_fsm_states_t I2C0_DO_TX_EMPTY(void) +{ + if (I2C0_MasterIsNack()) // Slave replied with NACK + { + switch (I2C0_status.callbackTable[I2C0_DATA_NACK](I2C0_status.callbackPayload[I2C0_DATA_NACK])) { + case I2C0_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C0_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + default: + case I2C0_CONTINUE: + case I2C0_STOP: + return I2C0_DO_SEND_STOP(); + } + } else { + I2C0_status.bufferFree = true; + switch (I2C0_status.callbackTable[I2C0_DATA_COMPLETE](I2C0_status.callbackPayload[I2C0_DATA_COMPLETE])) { + case I2C0_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C0_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + case I2C0_CONTINUE: + return I2C0_DO_TX(); + default: + case I2C0_STOP: + return I2C0_DO_SEND_STOP(); + } + } +} + +static twi0_fsm_states_t I2C0_DO_BUS_COLLISION(void) +{ + // Clear bus collision status flag + I2C0_MasterClearBusCollision(); + + I2C0_status.error = I2C0_FAIL; + switch (I2C0_status.callbackTable[I2C0_WRITE_COLLISION](I2C0_status.callbackPayload[I2C0_WRITE_COLLISION])) { + case I2C0_RESTART_READ: + return I2C0_DO_SEND_RESTART_READ(); + case I2C0_RESTART_WRITE: + return I2C0_DO_SEND_RESTART_WRITE(); + default: + return I2C0_DO_RESET(); + } +} + +static twi0_fsm_states_t I2C0_DO_BUS_ERROR(void) +{ + I2C0_MasterResetBus(); + I2C0_status.busy = false; + I2C0_status.error = I2C0_FAIL; + return I2C0_RESET; // park the FSM on reset +} + + + +void I2C0_MasterIsr(void) +{ + I2C0_MasterClearIrq(); + + // NOTE: We are ignoring the Write Collision flag. + + // Address phase received NACK from slave, override next state + if (I2C0_status.addressNACKCheck && I2C0_MasterIsNack()) { + I2C0_status.state = I2C0_ADDRESS_NACK; // State Override + } + + // Bus arbitration lost to another master, override next state + if (I2C0_MasterArbitrationlostOverride()) { + I2C0_status.state = I2C0_BUS_COLLISION; // State Override + } + + // Bus error, override next state + if (I2C0_MasterBusErrorOverride()) { + I2C0_status.state = I2C0_BUS_ERROR; // State Override + } + + I2C0_status.state = I2C0_fsmStateTable[I2C0_status.state](); +} + +/************************************************************************/ +/* Helper Functions */ +/************************************************************************/ +static twi0_operations_t I2C0_RETURN_STOP(void *p) +{ + return I2C0_STOP; +} + +static twi0_operations_t I2C0_RETURN_RESET(void *p) +{ + return I2C0_RESET_LINK; +} + +static void I2C0_set_callback(I2C0_callbackIndex_t idx, twi0_callback_t cb, void *funPtr) +{ + if (cb) { + I2C0_status.callbackTable[idx] = cb; + I2C0_status.callbackPayload[idx] = funPtr; + } else { + I2C0_status.callbackTable[idx] = I2C0_RETURN_STOP; + I2C0_status.callbackPayload[idx] = NULL; + } +} + +/* Master Definitions */ + +void I2C0_MasterOpen(void) +{ + TWI0.MCTRLA = 1 << TWI_ENABLE_bp; +} + +void I2C0_MasterClose(void) +{ + TWI0.MCTRLA = 0 << TWI_ENABLE_bp; +} + +/* Interrupt Control */ +void I2C0_MasterEnableIrq(void) +{ + TWI0.MCTRLA |= (TWI_RIEN_bm | TWI_WIEN_bm); +} + +bool I2C0_MasterIsIrqEnabled(void) +{ + return ((TWI0.MCTRLA & TWI_WIEN_bm) && (TWI0.MCTRLA & TWI_RIEN_bm)); +} + +void I2C0_MasterDisableIrq(void) +{ + TWI0.MCTRLA &= ~(TWI_RIEN_bm | TWI_WIEN_bm); +} + +void I2C0_MasterClearIrq(void) +{ + TWI0.MSTATUS |= (TWI_RIF_bm | TWI_WIF_bm); +} + +bool I2C0_MasterBusErrorOverride(void) +{ + return TWI0.MSTATUS & TWI_BUSERR_bm; +} + +bool I2C0_MasterArbitrationlostOverride(void) +{ + return TWI0.MSTATUS & TWI_ARBLOST_bm; +} + +void I2C0_MasterResetBus(void) +{ + TWI0.MCTRLB |= TWI_FLUSH_bm; + TWI0.MSTATUS |= TWI_BUSSTATE_IDLE_gc; +} + +void I2C0_MasterIsRxOrTx(void) +{ + TWI0.MCTRLB |= TWI_MCMD_RECVTRANS_gc; +} + +void I2C0_MasterClearBusCollision(void) +{ + TWI0.MSTATUS |= TWI_ARBLOST_bm; +} + +void I2C0_MasterWaitForEvent(void) +{ + while (!(TWI0.MSTATUS & TWI_RIF_bm) && !(TWI0.MSTATUS & TWI_WIF_bm)) + { + }; +} + +void I2C0_MasterStop(void) +{ + TWI0.MCTRLB |= TWI_MCMD_STOP_gc; +} + +bool I2C0_MasterIsNack(void) +{ + return TWI0.MSTATUS & TWI_RXACK_bm; +} + +char I2C0_MasterGetRxData(void) +{ + return TWI0.MDATA; +} + +void I2C0_MasterTxData(char d) +{ + TWI0.MDATA = d; +} + +void I2C0_MasterTxAddr(char d) +{ + TWI0.MADDR = d; +} + +void I2C0_MasterSendAck(void) +{ + TWI0.MCTRLB &= ~(1 << TWI_ACKACT_bp); +} + +void I2C0_MasterSendNack(void) +{ + TWI0.MCTRLB |= TWI_ACKACT_NACK_gc; +} + +twi0_operations_t I2C0_SetReturnStopCallback(void *funPtr) +{ + return I2C0_STOP; +} + +twi0_operations_t I2C0_SetReturnResetCallback(void *funPtr) +{ + return I2C0_RESET_LINK; +} + +twi0_operations_t I2C0_SetRestartWriteCallback(void *funPtr) +{ + return I2C0_RESTART_WRITE; +} + +twi0_operations_t I2C0_SetRestartReadCallback(void *funPtr) +{ + return I2C0_RESTART_READ; +} \ No newline at end of file diff --git a/twi0_master.h b/twi0_master.h new file mode 100644 index 0000000..14d035a --- /dev/null +++ b/twi0_master.h @@ -0,0 +1,220 @@ +/** + @Company + Microchip Technology Inc. + + @Description + This Source file provides APIs. + Generation Information : + Driver Version : 1.0.0 +*/ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + + +#ifndef TWI0_MASTER_H +#define TWI0_MASTER_H + +#include +#include +#include +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TWI0_BAUD(F_SCL, T_RISE) \ + ((((((float)10000000 / (float)F_SCL)) - 10 - ((float)10000000 * T_RISE / 1000000))) / 2) + + +typedef enum { + I2C0_NOERR, // The message was sent. + I2C0_BUSY, // Message was NOT sent, bus was busy. + I2C0_FAIL // Message was NOT sent, bus failure + // If you are interested in the failure reason, + // Sit on the event call-backs. +} twi0_error_t; + +typedef enum { I2C0_STOP = 1, I2C0_RESTART_READ, I2C0_RESTART_WRITE, I2C0_CONTINUE, I2C0_RESET_LINK } twi0_operations_t; + +typedef twi0_operations_t (*twi0_callback_t)(void *funPtr); + +typedef uint8_t twi0_address_t; +typedef twi0_address_t i2c_address_t; +// common callback responses +twi0_operations_t I2C0_SetReturnStopCallback(void *funPtr); +twi0_operations_t I2C0_SetReturnResetCallback(void *funPtr); +twi0_operations_t I2C0_SetRestartWriteCallback(void *funPtr); +twi0_operations_t I2C0_SetRestartReadCallback(void *funPtr); + +/** + * \brief Initialize I2C interface + * If module is configured to disabled state, the clock to the I2C is disabled + * if this is supported by the device's clock system. + * + * \return Initialization status. + * \retval 0 the init was successful + * \retval 1 the init was not successful + */ +uint8_t I2C0_Initialize(void); + +/** + * \brief Open the I2C for communication + * + * \param[in] address The slave address to use in the transfer + * + * \return Initialization status. + * \retval I2C_NOERR The I2C open was successful + * \retval I2C_BUSY The I2C open failed because the interface is busy + * \retval I2C_FAIL The I2C open failed with an error + */ +twi0_error_t I2C0_Open(twi0_address_t address); + +/** + * \brief Close the I2C interface + * + * \return Status of close operation. + * \retval I2C_NOERR The I2C open was successful + * \retval I2C_BUSY The I2C open failed because the interface is busy + * \retval I2C_FAIL The I2C open failed with an error + */ +twi0_error_t I2C0_Close(void); + +/** + * \brief Start an operation on an opened I2C interface + * + * \param[in] read Set to true for read, false for write + * + * \return Status of operation + * \retval I2C_NOERR The I2C open was successful + * \retval I2C_BUSY The I2C open failed because the interface is busy + * \retval I2C_FAIL The I2C open failed with an error + */ +twi0_error_t I2C0_MasterOperation(bool read); + +/** + * \brief Identical to I2C0_MasterOperation(false); + */ + +twi0_error_t I2C0_MasterWrite(void); // to be depreciated + + +/** + * \brief Identical to I2C0_MasterOperation(true); + */ + + +twi0_error_t I2C0_MasterRead(void); // to be depreciated + +/** + * \brief Set timeout to be used for I2C operations. Uses the Timeout driver. + * + * \param[in] to Timeout in ticks + * + * \return Nothing + */ +void I2C0_SetTimeout(uint8_t to); + +/** + * \brief Sets up the data buffer to use, and number of bytes to transfer + * + * \param[in] buffer Pointer to data buffer to use for read or write data + * \param[in] bufferSize Number of bytes to read or write from slave + * + * \return Nothing + */ +void I2C0_SetBuffer(void *buffer, size_t bufferSize); + +// Event Callback functions. + +/** + * \brief Set callback to be called when all specifed data has been transferred. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetDataCompleteCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief Set callback to be called when there has been a bus collision and arbitration was lost. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetWriteCollisionCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief Set callback to be called when the transmitted address was NACK'ed. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetAddressNackCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief Set callback to be called when the transmitted data was NACK'ed. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetDataNackCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief Set callback to be called when there was a bus timeout. + * + * \param[in] cb Pointer to callback function + * \param[in] p Pointer to the callback function's parameters + * + * \return Nothing + */ +void I2C0_SetTimeoutCallback(twi0_callback_t cb, void *funPtr); + +/** + * \brief In a polled implementation, call this function in a loop to execute the FSM + * + * \return Nothing + */ +void I2C0_Poller(void); + +/** + * \brief Set Address to be called when there was aa address reception. + * + * \param[in] address Loads the address of the master + * + * \return Nothing + */ +void I2C0_SetAddress(twi0_address_t address); + +#ifdef __cplusplus +} +#endif + +#endif /* TWI0_MASTER_H */ \ No newline at end of file diff --git a/twi0_master_example.c b/twi0_master_example.c new file mode 100644 index 0000000..5f55123 --- /dev/null +++ b/twi0_master_example.c @@ -0,0 +1,173 @@ +/** + @Company + Microchip Technology Inc. + + @Description + This Source file provides APIs. + Generation Information : + Driver Version : 1.0.0 +*/ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + + +/* + This file provides some basic blocking helper functions for common operations on the i2c API + */ + +#include "../include/twi0_master.h" +#include "twi0_master_example.h" + +/****************************************************************/ +static twi0_operations_t wr1RegCompleteHandler_example(void *ptr) +{ + I2C0_SetBuffer(ptr,1); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C0_CONTINUE; +} + +void I2C0_example_write1ByteRegister(twi0_address_t address, uint8_t reg, uint8_t data) +{ + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(wr1RegCompleteHandler_example,&data); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C0_BUSY == I2C0_Close()); // sit here until finished. +} + +void I2C0_example_writeNBytes(twi0_address_t address, void* data, size_t len) +{ + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetBuffer(data,len); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C0_BUSY == I2C0_Close()); // sit here until finished. +} + +/****************************************************************/ +static twi0_operations_t rd1RegCompleteHandler_example(void *ptr) +{ + I2C0_SetBuffer(ptr,1); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C0_RESTART_READ; +} + +uint8_t I2C0_example_read1ByteRegister(twi0_address_t address, uint8_t reg) +{ + uint8_t d2=42; + twi0_error_t e; + int x; + + for(x = 2; x != 0; x--) + { + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(rd1RegCompleteHandler_example,&d2); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C0_BUSY == (e = I2C0_Close())); // sit here until finished. + if(e==I2C0_NOERR) break; + } + + + return d2; +} + +/****************************************************************/ +static twi0_operations_t rd2RegCompleteHandler_example(void *ptr) +{ + I2C0_SetBuffer(ptr,2); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C0_RESTART_READ; +} + +uint16_t I2C0_example_read2ByteRegister(twi0_address_t address, uint8_t reg) +{ + // result is little endian + uint16_t result; + + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(rd2RegCompleteHandler_example,&result); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C0_BUSY == I2C0_Close()); // sit here until finished. + + return (result << 8 | result >> 8); +} + +/****************************************************************/ +static twi0_operations_t wr2RegCompleteHandler_example(void *ptr) +{ + I2C0_SetBuffer(ptr,2); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C0_CONTINUE; +} + +void I2C0_example_write2ByteRegister(twi0_address_t address, uint8_t reg, uint16_t data) +{ + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(wr2RegCompleteHandler_example,&data); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C0_BUSY == I2C0_Close()); // sit here until finished. +} + +/****************************************************************/ +typedef struct +{ + size_t len; + char *data; +}buf_t; + +static twi0_operations_t rdBlkRegCompleteHandler_example(void *ptr) +{ + I2C0_SetBuffer(((buf_t *)ptr)->data,((buf_t*)ptr)->len); + I2C0_SetDataCompleteCallback(NULL,NULL); + return I2C0_RESTART_READ; +} + +void I2C0_example_readDataBlock(twi0_address_t address, uint8_t reg, void *data, size_t len) +{ + // result is little endian + buf_t d; + d.data = data; + d.len = len; + + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetDataCompleteCallback(rdBlkRegCompleteHandler_example,&d); + I2C0_SetBuffer(®,1); + I2C0_SetAddressNackCallback(I2C0_SetRestartWriteCallback,NULL); //NACK polling? + I2C0_MasterWrite(); + while(I2C0_BUSY == I2C0_Close()); // sit here until finished. +} + +void I2C0_example_readNBytes(twi0_address_t address, void *data, size_t len) +{ + while(!I2C0_Open(address)); // sit here until we get the bus.. + I2C0_SetBuffer(data,len); + I2C0_MasterRead(); + while(I2C0_BUSY == I2C0_Close()); // sit here until finished. +} \ No newline at end of file diff --git a/twi0_master_example.h b/twi0_master_example.h new file mode 100644 index 0000000..7444501 --- /dev/null +++ b/twi0_master_example.h @@ -0,0 +1,50 @@ +/** + @Company + Microchip Technology Inc. + + @Description + This Source file provides APIs. + Generation Information : + Driver Version : 1.0.0 +*/ +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + + +#ifndef TWI0_MASTER_EXAMPLE_H +#define TWI0_MASTER_EXAMPLE_H + +#include +#include +#include "twi0_master.h" + +uint8_t I2C0_example_read1ByteRegister(twi0_address_t address, uint8_t reg); +uint16_t I2C0_example_read2ByteRegister(twi0_address_t address, uint8_t reg); +void I2C0_example_write1ByteRegister(twi0_address_t address, uint8_t reg, uint8_t data); +void I2C0_example_write2ByteRegister(twi0_address_t address, uint8_t reg, uint16_t data); + +void I2C0_example_writeNBytes(twi0_address_t address, void* data, size_t len); +void I2C0_example_readDataBlock(twi0_address_t address, uint8_t reg, void *data, size_t len); +void iI2C0_example_readNBytes(twi0_address_t address, void *data, size_t len); + +#endif /* TWI0_MASTER_EXAMPLE_H */ \ No newline at end of file