Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 262 → Rev 342

/PIC Projects/PIC_27J13/nbproject/Makefile-default.mk
0,0 → 1,341
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a -pre and a -post target defined where you can add customized code.
#
# This makefile implements configuration specific macros and targets.
 
 
# Include project Makefile
ifeq "${IGNORE_LOCAL}" "TRUE"
# do not include local makefile. User is passing all local related variables already
else
include Makefile
# Include makefile containing local settings
ifeq "$(wildcard nbproject/Makefile-local-default.mk)" "nbproject/Makefile-local-default.mk"
include nbproject/Makefile-local-default.mk
endif
endif
 
# Environment
MKDIR=gnumkdir -p
RM=rm -f
MV=mv
CP=cp
 
# Macros
CND_CONF=default
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
IMAGE_TYPE=debug
OUTPUT_SUFFIX=cof
DEBUGGABLE_SUFFIX=cof
FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/PIC_27J13.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
else
IMAGE_TYPE=production
OUTPUT_SUFFIX=hex
DEBUGGABLE_SUFFIX=cof
FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/PIC_27J13.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
endif
 
# Object Directory
OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE}
 
# Distribution Directory
DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE}
 
# Object Files Quoted if spaced
OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/main.o ${OBJECTDIR}/i2c.o ${OBJECTDIR}/interrupts.o ${OBJECTDIR}/spi.o ${OBJECTDIR}/uart.o ${OBJECTDIR}/oled_ssd1306.o ${OBJECTDIR}/glcdfont.o ${OBJECTDIR}/adc.o ${OBJECTDIR}/xbee.o ${OBJECTDIR}/oled_ssd1331.o ${OBJECTDIR}/timers.o ${OBJECTDIR}/led_HT16K33.o ${OBJECTDIR}/lux_TSL2561.o ${OBJECTDIR}/nfc_PN532.o ${OBJECTDIR}/oled_NHD-0216KZW-AB5.o ${OBJECTDIR}/temp_BMP085.o
POSSIBLE_DEPFILES=${OBJECTDIR}/main.o.d ${OBJECTDIR}/i2c.o.d ${OBJECTDIR}/interrupts.o.d ${OBJECTDIR}/spi.o.d ${OBJECTDIR}/uart.o.d ${OBJECTDIR}/oled_ssd1306.o.d ${OBJECTDIR}/glcdfont.o.d ${OBJECTDIR}/adc.o.d ${OBJECTDIR}/xbee.o.d ${OBJECTDIR}/oled_ssd1331.o.d ${OBJECTDIR}/timers.o.d ${OBJECTDIR}/led_HT16K33.o.d ${OBJECTDIR}/lux_TSL2561.o.d ${OBJECTDIR}/nfc_PN532.o.d ${OBJECTDIR}/oled_NHD-0216KZW-AB5.o.d ${OBJECTDIR}/temp_BMP085.o.d
 
# Object Files
OBJECTFILES=${OBJECTDIR}/main.o ${OBJECTDIR}/i2c.o ${OBJECTDIR}/interrupts.o ${OBJECTDIR}/spi.o ${OBJECTDIR}/uart.o ${OBJECTDIR}/oled_ssd1306.o ${OBJECTDIR}/glcdfont.o ${OBJECTDIR}/adc.o ${OBJECTDIR}/xbee.o ${OBJECTDIR}/oled_ssd1331.o ${OBJECTDIR}/timers.o ${OBJECTDIR}/led_HT16K33.o ${OBJECTDIR}/lux_TSL2561.o ${OBJECTDIR}/nfc_PN532.o ${OBJECTDIR}/oled_NHD-0216KZW-AB5.o ${OBJECTDIR}/temp_BMP085.o
 
 
CFLAGS=
ASFLAGS=
LDLIBSOPTIONS=
 
############# Tool locations ##########################################
# If you copy a project from one host to another, the path where the #
# compiler is installed may be different. #
# If you open this project with MPLAB X in the new host, this #
# makefile will be regenerated and the paths will be corrected. #
#######################################################################
# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build
FIXDEPS=fixDeps
 
.build-conf: ${BUILD_SUBPROJECTS}
${MAKE} ${MAKE_OPTIONS} -f nbproject/Makefile-default.mk dist/${CND_CONF}/${IMAGE_TYPE}/PIC_27J13.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
 
MP_PROCESSOR_OPTION=18F27J13
MP_PROCESSOR_OPTION_LD=18f27j13
MP_LINKER_DEBUG_OPTION=
# ------------------------------------------------------------------------------------
# Rules for buildStep: assemble
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
else
endif
 
# ------------------------------------------------------------------------------------
# Rules for buildStep: compile
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
${OBJECTDIR}/main.o: main.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/main.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/main.o main.c
@${DEP_GEN} -d ${OBJECTDIR}/main.o
@${FIXDEPS} "${OBJECTDIR}/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/i2c.o: i2c.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/i2c.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/i2c.o i2c.c
@${DEP_GEN} -d ${OBJECTDIR}/i2c.o
@${FIXDEPS} "${OBJECTDIR}/i2c.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/interrupts.o: interrupts.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/interrupts.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/interrupts.o interrupts.c
@${DEP_GEN} -d ${OBJECTDIR}/interrupts.o
@${FIXDEPS} "${OBJECTDIR}/interrupts.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/spi.o: spi.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/spi.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/spi.o spi.c
@${DEP_GEN} -d ${OBJECTDIR}/spi.o
@${FIXDEPS} "${OBJECTDIR}/spi.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/uart.o: uart.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/uart.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/uart.o uart.c
@${DEP_GEN} -d ${OBJECTDIR}/uart.o
@${FIXDEPS} "${OBJECTDIR}/uart.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/oled_ssd1306.o: oled_ssd1306.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/oled_ssd1306.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/oled_ssd1306.o oled_ssd1306.c
@${DEP_GEN} -d ${OBJECTDIR}/oled_ssd1306.o
@${FIXDEPS} "${OBJECTDIR}/oled_ssd1306.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/glcdfont.o: glcdfont.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/glcdfont.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/glcdfont.o glcdfont.c
@${DEP_GEN} -d ${OBJECTDIR}/glcdfont.o
@${FIXDEPS} "${OBJECTDIR}/glcdfont.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/adc.o: adc.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/adc.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/adc.o adc.c
@${DEP_GEN} -d ${OBJECTDIR}/adc.o
@${FIXDEPS} "${OBJECTDIR}/adc.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/xbee.o: xbee.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/xbee.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/xbee.o xbee.c
@${DEP_GEN} -d ${OBJECTDIR}/xbee.o
@${FIXDEPS} "${OBJECTDIR}/xbee.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/oled_ssd1331.o: oled_ssd1331.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/oled_ssd1331.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/oled_ssd1331.o oled_ssd1331.c
@${DEP_GEN} -d ${OBJECTDIR}/oled_ssd1331.o
@${FIXDEPS} "${OBJECTDIR}/oled_ssd1331.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/timers.o: timers.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/timers.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/timers.o timers.c
@${DEP_GEN} -d ${OBJECTDIR}/timers.o
@${FIXDEPS} "${OBJECTDIR}/timers.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/led_HT16K33.o: led_HT16K33.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/led_HT16K33.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/led_HT16K33.o led_HT16K33.c
@${DEP_GEN} -d ${OBJECTDIR}/led_HT16K33.o
@${FIXDEPS} "${OBJECTDIR}/led_HT16K33.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/lux_TSL2561.o: lux_TSL2561.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/lux_TSL2561.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/lux_TSL2561.o lux_TSL2561.c
@${DEP_GEN} -d ${OBJECTDIR}/lux_TSL2561.o
@${FIXDEPS} "${OBJECTDIR}/lux_TSL2561.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/nfc_PN532.o: nfc_PN532.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/nfc_PN532.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/nfc_PN532.o nfc_PN532.c
@${DEP_GEN} -d ${OBJECTDIR}/nfc_PN532.o
@${FIXDEPS} "${OBJECTDIR}/nfc_PN532.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/oled_NHD-0216KZW-AB5.o: oled_NHD-0216KZW-AB5.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/oled_NHD-0216KZW-AB5.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/oled_NHD-0216KZW-AB5.o oled_NHD-0216KZW-AB5.c
@${DEP_GEN} -d ${OBJECTDIR}/oled_NHD-0216KZW-AB5.o
@${FIXDEPS} "${OBJECTDIR}/oled_NHD-0216KZW-AB5.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/temp_BMP085.o: temp_BMP085.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/temp_BMP085.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/temp_BMP085.o temp_BMP085.c
@${DEP_GEN} -d ${OBJECTDIR}/temp_BMP085.o
@${FIXDEPS} "${OBJECTDIR}/temp_BMP085.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
else
${OBJECTDIR}/main.o: main.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/main.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/main.o main.c
@${DEP_GEN} -d ${OBJECTDIR}/main.o
@${FIXDEPS} "${OBJECTDIR}/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/i2c.o: i2c.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/i2c.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/i2c.o i2c.c
@${DEP_GEN} -d ${OBJECTDIR}/i2c.o
@${FIXDEPS} "${OBJECTDIR}/i2c.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/interrupts.o: interrupts.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/interrupts.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/interrupts.o interrupts.c
@${DEP_GEN} -d ${OBJECTDIR}/interrupts.o
@${FIXDEPS} "${OBJECTDIR}/interrupts.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/spi.o: spi.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/spi.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/spi.o spi.c
@${DEP_GEN} -d ${OBJECTDIR}/spi.o
@${FIXDEPS} "${OBJECTDIR}/spi.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/uart.o: uart.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/uart.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/uart.o uart.c
@${DEP_GEN} -d ${OBJECTDIR}/uart.o
@${FIXDEPS} "${OBJECTDIR}/uart.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/oled_ssd1306.o: oled_ssd1306.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/oled_ssd1306.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/oled_ssd1306.o oled_ssd1306.c
@${DEP_GEN} -d ${OBJECTDIR}/oled_ssd1306.o
@${FIXDEPS} "${OBJECTDIR}/oled_ssd1306.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/glcdfont.o: glcdfont.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/glcdfont.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/glcdfont.o glcdfont.c
@${DEP_GEN} -d ${OBJECTDIR}/glcdfont.o
@${FIXDEPS} "${OBJECTDIR}/glcdfont.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/adc.o: adc.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/adc.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/adc.o adc.c
@${DEP_GEN} -d ${OBJECTDIR}/adc.o
@${FIXDEPS} "${OBJECTDIR}/adc.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/xbee.o: xbee.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/xbee.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/xbee.o xbee.c
@${DEP_GEN} -d ${OBJECTDIR}/xbee.o
@${FIXDEPS} "${OBJECTDIR}/xbee.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/oled_ssd1331.o: oled_ssd1331.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/oled_ssd1331.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/oled_ssd1331.o oled_ssd1331.c
@${DEP_GEN} -d ${OBJECTDIR}/oled_ssd1331.o
@${FIXDEPS} "${OBJECTDIR}/oled_ssd1331.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/timers.o: timers.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/timers.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/timers.o timers.c
@${DEP_GEN} -d ${OBJECTDIR}/timers.o
@${FIXDEPS} "${OBJECTDIR}/timers.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/led_HT16K33.o: led_HT16K33.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/led_HT16K33.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/led_HT16K33.o led_HT16K33.c
@${DEP_GEN} -d ${OBJECTDIR}/led_HT16K33.o
@${FIXDEPS} "${OBJECTDIR}/led_HT16K33.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/lux_TSL2561.o: lux_TSL2561.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/lux_TSL2561.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/lux_TSL2561.o lux_TSL2561.c
@${DEP_GEN} -d ${OBJECTDIR}/lux_TSL2561.o
@${FIXDEPS} "${OBJECTDIR}/lux_TSL2561.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/nfc_PN532.o: nfc_PN532.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/nfc_PN532.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/nfc_PN532.o nfc_PN532.c
@${DEP_GEN} -d ${OBJECTDIR}/nfc_PN532.o
@${FIXDEPS} "${OBJECTDIR}/nfc_PN532.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/oled_NHD-0216KZW-AB5.o: oled_NHD-0216KZW-AB5.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/oled_NHD-0216KZW-AB5.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/oled_NHD-0216KZW-AB5.o oled_NHD-0216KZW-AB5.c
@${DEP_GEN} -d ${OBJECTDIR}/oled_NHD-0216KZW-AB5.o
@${FIXDEPS} "${OBJECTDIR}/oled_NHD-0216KZW-AB5.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
${OBJECTDIR}/temp_BMP085.o: temp_BMP085.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/temp_BMP085.o.d
${MP_CC} $(MP_EXTRA_CC_PRE) -p$(MP_PROCESSOR_OPTION) -oi -ml -oa- -I ${MP_CC_DIR}\\..\\h -fo ${OBJECTDIR}/temp_BMP085.o temp_BMP085.c
@${DEP_GEN} -d ${OBJECTDIR}/temp_BMP085.o
@${FIXDEPS} "${OBJECTDIR}/temp_BMP085.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c18
endif
 
# ------------------------------------------------------------------------------------
# Rules for buildStep: link
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
dist/${CND_CONF}/${IMAGE_TYPE}/PIC_27J13.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk 18f27j13.lkr
@${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE}
${MP_LD} $(MP_EXTRA_LD_PRE) "18f27j13.lkr" -p$(MP_PROCESSOR_OPTION_LD) -w -x -u_DEBUG -z__MPLAB_BUILD=1 -u_CRUNTIME -z__MPLAB_DEBUG=1 -z__MPLAB_DEBUGGER_PK3=1 $(MP_LINKER_DEBUG_OPTION) -l ${MP_CC_DIR}\\..\\lib -o dist/${CND_CONF}/${IMAGE_TYPE}/PIC_27J13.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED}
else
dist/${CND_CONF}/${IMAGE_TYPE}/PIC_27J13.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk 18f27j13.lkr
@${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE}
${MP_LD} $(MP_EXTRA_LD_PRE) "18f27j13.lkr" -p$(MP_PROCESSOR_OPTION_LD) -w -z__MPLAB_BUILD=1 -u_CRUNTIME -l ${MP_CC_DIR}\\..\\lib -o dist/${CND_CONF}/${IMAGE_TYPE}/PIC_27J13.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED}
endif
 
 
# Subprojects
.build-subprojects:
 
 
# Subprojects
.clean-subprojects:
 
# Clean Targets
.clean-conf: ${CLEAN_SUBPROJECTS}
${RM} -r build/default
${RM} -r dist/default
 
# Enable dependency checking
.dep.inc: .depcheck-impl
 
DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES})
ifneq (${DEPFILES},)
include ${DEPFILES}
endif
/PIC Projects/PIC_27J13/nbproject/Makefile-genesis.properties
0,0 → 1,8
#
#Fri Dec 21 15:59:39 EST 2012
default.com-microchip-mplab-nbide-toolchainC18-C18LanguageToolchain.md5=e4cd2f1e5bba11c8ba952dafee98d887
default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\mplabc18\\v3.42\\bin
com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=d94e033fce233e60ccb9abf3a212a9b7
default.languagetoolchain.version=3.42
host.platform=windows
conf.ids=default
/PIC Projects/PIC_27J13/nbproject/configurations.xml
0,0 → 1,175
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="62">
<logicalFolder name="root" displayName="root" projectFiles="true">
<logicalFolder name="HeaderFiles"
displayName="Header Files"
projectFiles="true">
<itemPath>i2c.h</itemPath>
<itemPath>interrupts.h</itemPath>
<itemPath>spi.h</itemPath>
<itemPath>uart.h</itemPath>
<itemPath>oled_ssd1306.h</itemPath>
<itemPath>adc.h</itemPath>
<itemPath>xbee.h</itemPath>
<itemPath>oled_ssd1331.h</itemPath>
<itemPath>defines.h</itemPath>
<itemPath>timers.h</itemPath>
<itemPath>led_HT16K33.h</itemPath>
<itemPath>lux_TSL2561.h</itemPath>
<itemPath>nfc_PN532.h</itemPath>
<itemPath>oled_NHD-0216KZW-AB5.h</itemPath>
<itemPath>temp_BMP085.h</itemPath>
</logicalFolder>
<logicalFolder name="LibraryFiles"
displayName="Library Files"
projectFiles="true">
</logicalFolder>
<logicalFolder name="LinkerScript"
displayName="Linker Files"
projectFiles="true">
<itemPath>18f27j13.lkr</itemPath>
</logicalFolder>
<logicalFolder name="ObjectFiles"
displayName="Object Files"
projectFiles="true">
</logicalFolder>
<logicalFolder name="SourceFiles"
displayName="Source Files"
projectFiles="true">
<itemPath>main.c</itemPath>
<itemPath>i2c.c</itemPath>
<itemPath>interrupts.c</itemPath>
<itemPath>spi.c</itemPath>
<itemPath>uart.c</itemPath>
<itemPath>oled_ssd1306.c</itemPath>
<itemPath>glcdfont.c</itemPath>
<itemPath>adc.c</itemPath>
<itemPath>xbee.c</itemPath>
<itemPath>oled_ssd1331.c</itemPath>
<itemPath>timers.c</itemPath>
<itemPath>led_HT16K33.c</itemPath>
<itemPath>lux_TSL2561.c</itemPath>
<itemPath>nfc_PN532.c</itemPath>
<itemPath>oled_NHD-0216KZW-AB5.c</itemPath>
<itemPath>temp_BMP085.c</itemPath>
</logicalFolder>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
projectFiles="false">
<itemPath>Makefile</itemPath>
</logicalFolder>
</logicalFolder>
<projectmakefile>Makefile</projectmakefile>
<confs>
<conf name="default" type="2">
<toolsSet>
<developmentServer>localhost</developmentServer>
<targetDevice>PIC18F27J13</targetDevice>
<targetHeader></targetHeader>
<targetPluginBoard></targetPluginBoard>
<platformTool>PICkit3PlatformTool</platformTool>
<languageToolchain>C18</languageToolchain>
<languageToolchainVersion>3.42</languageToolchainVersion>
<platform>3</platform>
</toolsSet>
<compileType>
<linkerTool>
<linkerLibItems>
</linkerLibItems>
</linkerTool>
<loading>
<useAlternateLoadableFile>false</useAlternateLoadableFile>
<alternateLoadableFile></alternateLoadableFile>
</loading>
</compileType>
<makeCustomizationType>
<makeCustomizationPreStepEnabled>false</makeCustomizationPreStepEnabled>
<makeCustomizationPreStep></makeCustomizationPreStep>
<makeCustomizationPostStepEnabled>false</makeCustomizationPostStepEnabled>
<makeCustomizationPostStep></makeCustomizationPostStep>
<makeCustomizationPutChecksumInUserID>false</makeCustomizationPutChecksumInUserID>
<makeCustomizationEnableLongLines>false</makeCustomizationEnableLongLines>
<makeCustomizationNormalizeHexFile>false</makeCustomizationNormalizeHexFile>
</makeCustomizationType>
<C18>
<property key="code-model" value="ml"/>
<property key="data-model" value="oa-"/>
<property key="default-char-unsigned" value="false"/>
<property key="enable-all-optimizations" value="true"/>
<property key="enable-int-promotion" value="true"/>
<property key="enable-multi-bank-stack-model" value="false"/>
<property key="enable-ob" value="true"/>
<property key="enable-od" value="true"/>
<property key="enable-om" value="true"/>
<property key="enable-on" value="false"/>
<property key="enable-op" value="true"/>
<property key="enable-opa" value="true"/>
<property key="enable-or" value="true"/>
<property key="enable-os" value="true"/>
<property key="enable-ot" value="true"/>
<property key="enable-ou" value="true"/>
<property key="enable-ow" value="true"/>
<property key="extra-include-directories" value=""/>
<property key="optimization-master" value="Enable all"/>
<property key="preprocessor-macros" value=""/>
<property key="procedural-abstraction-passes" value="9"/>
<property key="storage-class" value="sca"/>
<property key="verbose" value="false"/>
<property key="warning-level" value="2"/>
</C18>
<C18-AS>
<property key="cross.reference.file" value=""/>
<property key="default.radix" value="HEX"/>
<property key="enable.case.sensitivity" value="true"/>
<property key="hex.output.format" value="INHX32"/>
<property key="preprocessor.macros" value=""/>
<property key="warning.level" value="0"/>
</C18-AS>
<C18-LD>
<property key="cod-file" value="false"/>
<property key="extra-lib-directories" value=""/>
<property key="hex-output-format" value="INHX32"/>
<property key="map-file" value=""/>
</C18-LD>
<C18LanguageToolchain>
<property key="extended-mode" value="false"/>
<property key="extended-mode-mcc18" value="false"/>
<property key="extended-mode-mpasm" value="false"/>
<property key="extended-mode-mplink" value="false"/>
<property key="stack-analysis" value="false"/>
<property key="stack-analysis-mcc18" value="false"/>
<property key="stack-analysis-mplink" value="false"/>
</C18LanguageToolchain>
<PICkit3PlatformTool>
<property key="AutoSelectMemRanges" value="auto"/>
<property key="Freeze Peripherals" value="true"/>
<property key="SecureSegment.SegmentProgramming" value="FullChipProgramming"/>
<property key="ToolFirmwareFilePath"
value="Press to browse for a specific firmware version"/>
<property key="ToolFirmwareOption.UseLatestFirmware" value="true"/>
<property key="hwtoolclock.frcindebug" value="false"/>
<property key="memories.aux" value="false"/>
<property key="memories.bootflash" value="false"/>
<property key="memories.configurationmemory" value="false"/>
<property key="memories.eeprom" value="false"/>
<property key="memories.flashdata" value="true"/>
<property key="memories.id" value="false"/>
<property key="memories.programmemory" value="true"/>
<property key="memories.programmemory.end" value="0x1fff7"/>
<property key="memories.programmemory.start" value="0x0"/>
<property key="poweroptions.powerenable" value="false"/>
<property key="programmertogo.imagename" value=""/>
<property key="programoptions.eraseb4program" value="true"/>
<property key="programoptions.pgmspeed" value="2"/>
<property key="programoptions.preserveeeprom" value="false"/>
<property key="programoptions.preserveprogramrange" value="false"/>
<property key="programoptions.preserveprogramrange.end" value="0x3f"/>
<property key="programoptions.preserveprogramrange.start" value="0x0"/>
<property key="programoptions.preserveuserid" value="false"/>
<property key="programoptions.usehighvoltageonmclr" value="false"/>
<property key="programoptions.uselvpprogramming" value="false"/>
<property key="voltagevalue" value="3.25"/>
</PICkit3PlatformTool>
</conf>
</confs>
</configurationDescriptor>
/PIC Projects/PIC_27J13/nbproject/Makefile-local-default.mk
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" ...
#
SHELL=cmd.exe
PATH_TO_IDE_BIN=C:/Program Files (x86)/Microchip/MPLABX/mplab_ide/mplab_ide/modules/../../bin/
# Adding MPLAB X bin directory to path.
PATH:=C:/Program Files (x86)/Microchip/MPLABX/mplab_ide/mplab_ide/modules/../../bin/:$(PATH)
# Path to java used to run MPLAB X when this makefile was created
MP_JAVA_PATH="C:\Program Files (x86)\Microchip\MPLABX\sys\java\jre1.6.0_32-windows-x64\java-windows/bin/"
OS_CURRENT="$(shell uname -s)"
MP_CC="C:\Program Files (x86)\Microchip\mplabc18\v3.42\bin\mcc18.exe"
# MP_CPPC is not defined
# MP_BC is not defined
MP_AS="C:\Program Files (x86)\Microchip\mplabc18\v3.42\bin\..\mpasm\MPASMWIN.exe"
MP_LD="C:\Program Files (x86)\Microchip\mplabc18\v3.42\bin\mplink.exe"
MP_AR="C:\Program Files (x86)\Microchip\mplabc18\v3.42\bin\mplib.exe"
DEP_GEN=${MP_JAVA_PATH}java -jar "C:/Program Files (x86)/Microchip/MPLABX/mplab_ide/mplab_ide/modules/../../bin/extractobjectdependencies.jar"
MP_CC_DIR="C:\Program Files (x86)\Microchip\mplabc18\v3.42\bin"
# MP_CPPC_DIR is not defined
# MP_BC_DIR is not defined
MP_AS_DIR="C:\Program Files (x86)\Microchip\mplabc18\v3.42\bin\..\mpasm"
MP_LD_DIR="C:\Program Files (x86)\Microchip\mplabc18\v3.42\bin"
MP_AR_DIR="C:\Program Files (x86)\Microchip\mplabc18\v3.42\bin"
# MP_BC_DIR is not defined
/PIC Projects/PIC_27J13/nbproject/Makefile-impl.mk
0,0 → 1,69
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a pre- and a post- target defined where you can add customization code.
#
# This makefile implements macros and targets common to all configurations.
#
# NOCDDL
 
 
# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
# and .clean-reqprojects-conf unless SUB has the value 'no'
SUB_no=NO
SUBPROJECTS=${SUB_${SUB}}
BUILD_SUBPROJECTS_=.build-subprojects
BUILD_SUBPROJECTS_NO=
BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
CLEAN_SUBPROJECTS_=.clean-subprojects
CLEAN_SUBPROJECTS_NO=
CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
 
 
# Project Name
PROJECTNAME=PIC_27J13
 
# Active Configuration
DEFAULTCONF=default
CONF=${DEFAULTCONF}
 
# All Configurations
ALLCONFS=default
 
 
# build
.build-impl: .build-pre
${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf
 
 
# clean
.clean-impl: .clean-pre
${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf
 
# clobber
.clobber-impl: .clobber-pre .depcheck-impl
${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=default clean
 
 
 
# all
.all-impl: .all-pre .depcheck-impl
${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=default build
 
 
 
# dependency checking support
.depcheck-impl:
# @echo "# This code depends on make tool being used" >.dep.inc
# @if [ -n "${MAKE_VERSION}" ]; then \
# echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
# echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
# echo "include \$${DEPFILES}" >>.dep.inc; \
# echo "endif" >>.dep.inc; \
# else \
# echo ".KEEP_STATE:" >>.dep.inc; \
# echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
# fi
/PIC Projects/PIC_27J13/nbproject/Makefile-variables.mk
0,0 → 1,13
#
# Generated - do not edit!
#
# NOCDDL
#
CND_BASEDIR=`pwd`
# default configuration
CND_ARTIFACT_DIR_default=dist/default/production
CND_ARTIFACT_NAME_default=PIC_27J13.production.hex
CND_ARTIFACT_PATH_default=dist/default/production/PIC_27J13.production.hex
CND_PACKAGE_DIR_default=${CND_DISTDIR}/default/package
CND_PACKAGE_NAME_default=pic27j13.tar
CND_PACKAGE_PATH_default=${CND_DISTDIR}/default/package/pic27j13.tar
/PIC Projects/PIC_27J13/nbproject/Package-default.bash
0,0 → 1,73
#!/bin/bash -x
 
#
# Generated - do not edit!
#
 
# Macros
TOP=`pwd`
CND_CONF=default
CND_DISTDIR=dist
TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging
TMPDIRNAME=tmp-packaging
OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/PIC_27J13.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
OUTPUT_BASENAME=PIC_27J13.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
PACKAGE_TOP_DIR=pic27j13/
 
# Functions
function checkReturnCode
{
rc=$?
if [ $rc != 0 ]
then
exit $rc
fi
}
function makeDirectory
# $1 directory path
# $2 permission (optional)
{
mkdir -p "$1"
checkReturnCode
if [ "$2" != "" ]
then
chmod $2 "$1"
checkReturnCode
fi
}
function copyFileToTmpDir
# $1 from-file path
# $2 to-file path
# $3 permission
{
cp "$1" "$2"
checkReturnCode
if [ "$3" != "" ]
then
chmod $3 "$2"
checkReturnCode
fi
}
 
# Setup
cd "${TOP}"
mkdir -p ${CND_DISTDIR}/${CND_CONF}/package
rm -rf ${TMPDIR}
mkdir -p ${TMPDIR}
 
# Copy files and create directories and links
cd "${TOP}"
makeDirectory ${TMPDIR}/pic27j13/bin
copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
 
 
# Generate tar file
cd "${TOP}"
rm -f ${CND_DISTDIR}/${CND_CONF}/package/pic27j13.tar
cd ${TMPDIR}
tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/pic27j13.tar *
checkReturnCode
 
# Cleanup
cd "${TOP}"
rm -rf ${TMPDIR}
/PIC Projects/PIC_27J13/nbproject/project.properties
--- nbproject/project.xml (nonexistent)
+++ nbproject/project.xml (revision 342)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>com.microchip.mplab.nbide.embedded.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>PIC_27J13</name>
+ <creation-uuid>116783ce-ce82-4f46-901c-ed02c852cd72</creation-uuid>
+ <make-project-type>0</make-project-type>
+ <c-extensions>c</c-extensions>
+ <cpp-extensions/>
+ <header-extensions>h</header-extensions>
+ <sourceEncoding>ISO-8859-1</sourceEncoding>
+ <make-dep-projects/>
+ </data>
+ </configuration>
+</project>
/PIC Projects/PIC_27J13/adc.h
0,0 → 1,48
#ifndef ADC_H
#define ADC_H
 
#define ADC_CHANNEL_AN0 0b0000
#define ADC_CHANNEL_AN1 0b0001
#define ADC_CHANNEL_AN2 0b0010
#define ADC_CHANNEL_AN3 0b0011
#define ADC_CHANNEL_AN4 0b0100
#define ADC_CHANNEL_AN5 0b0101
#define ADC_CHANNEL_AN6 0b0110
#define ADC_CHANNEL_AN7 0b0111
#define ADC_CHANNEL_AN8 0b1000
#define ADC_CHANNEL_AN9 0b1001
#define ADC_CHANNEL_AN10 0b1010
#define ADC_CHANNEL_AN11 0b1011
#define ADC_CHANNEL_AN12 0b1100
#define ADC_CHANNEL_VDDCORE 0b1110
#define ADC_CHANNEL_ABG 0b1111
 
#define ADC_TAD_20 0b111
#define ADC_TAD_16 0b110
#define ADC_TAD_12 0b101
#define ADC_TAD_8 0b100
#define ADC_TAD_6 0b011
#define ADC_TAD_4 0b010
#define ADC_TAD_2 0b001
#define ADC_TAD_0 0b000
 
#define ADC_FOSC_64 0b110
#define ADC_FOSC_32 0b010
#define ADC_FOSC_16 0b101
#define ADC_FOSC_8 0b001
#define ADC_FOSC_4 0b100
#define ADC_FOSC_2 0b000
#define ADC_FOSC_FRC 0b011
 
typedef struct __ADC_DATA {
unsigned char last_channel;
unsigned int result;
} ADC_DATA;
 
void ADC_Init(unsigned char TAD, unsigned char FOSC);
void ADC_Start(unsigned char channel);
void ADC_Stop(void);
void ADC_Interrupt_Handler(void);
char ADC_Get_Result(unsigned int *ret);
 
#endif
/PIC Projects/PIC_27J13/defines.h
0,0 → 1,123
#ifndef DEFINES_H
#define DEFINES_H
 
#include <p18f27j13.h>
#include "uart.h"
 
#define UART1_RX_TO_BUFFER
//#define UART1_RX_TO_XBEE
 
// Option to disable SPI MISO
#define SPI2_WRITE_ONLY
 
//#define _DEBUG
 
//#define _TEST_UART
//#define _TEST_I2C_MASTER
//#define _TEST_I2C_SLAVE
//#define _TEST_SPI
//#define _TEST_NFC
//#define _TEST_LED_BACKPACK
//#define _TEST_SSD1306_OLED
//#define _TEST_SSD1331_OLED
//#define _TEST_ADC
//#define _TEST_XBEE
//#define _TEST_NFC_TO_SSD1306_OLED
//#define _TEST_TIMER1_RTC
//#define _TEST_LUX
//#define _TEST_OLED_CHAR
//#define _TEST_BMP
 
// Enable or disable debug prints depending on project preprocessor (_DEBUG)
#ifdef _DEBUG
#define DBG_PRINT_MAIN(x) UART1_WriteS(x)
#define DBG_PRINT_MAIN_F(x) UART1_WriteF(x)
#define DBG_PRINT_UART(x) UART1_WriteS(x)
#define DBG_PRINT_I2C(x) UART1_WriteS(x)
#define DBG_PRINT_SPI(x) UART1_WriteS(x)
#define DBG_PRINT_XBEE(x) UART1_WriteS(x)
#define DBG_PRINT_PORTB_INT(x)
#define DBG_PRINT_INT(x)
#define DBG_PRINT_LUX(x)
#define DBG_PRINT_BMP(x)
#else
#define DBG_PRINT_MAIN(x)
#define DBG_PRINT_MAIN_F(x)
#define DBG_PRINT_UART(x)
#define DBG_PRINT_I2C(x)
#define DBG_PRINT_SPI(x)
#define DBG_PRINT_XBEE(x)
#define DBG_PRINT_PORTB_INT(x)
#define DBG_PRINT_INT(x)
#define DBG_PRINT_LUX(x)
#define DBG_PRINT_BMP(x)
#endif
 
// Pin allocations
#define LED_BLUE_TRIS TRISCbits.TRISC5
#define LED_BLUE_LAT LATCbits.LATC5
#define LED_RED_TRIS TRISCbits.TRISC2
#define LED_RED_LAT LATCbits.LATC2
 
#define ADC_AN0_TRIS TRISAbits.TRISA0
#define ADC_AN1_TRIS TRISAbits.TRISA1
#define ADC_AN2_TRIS TRISAbits.TRISA2
 
#define XBEE_CTS_TRIS TRISBbits.TRISB0
#define XBEE_CTS_LAT LATBbits.LATB0
#define XBEE_CTS_PORT PORTBbits.RB0
#define XBEE_RTS_TRIS TRISBbits.TRISB1
#define XBEE_RTS_LAT LATBbits.LATB1
 
#define SPI_MOSI_TRIS TRISBbits.TRISB0
#ifndef SPI2_WRITE_ONLY
#define SPI_MISO_TRIS TRISBbits.TRISB0
#endif
#define SPI_CLK_TRIS TRISAbits.TRISA0
#define SPI_DC_SELECT_TRIS TRISAbits.TRISA1
#define SPI_DC_SELECT_LAT LATAbits.LATA1
#define SPI_RESET_TRIS TRISAbits.TRISA2
#define SPI_RESET_LAT LATAbits.LATA2
#define SPI_SLAVE_SELECT_TRIS TRISAbits.TRISA3
#define SPI_SLAVE_SELECT_LAT LATAbits.LATA3
 
#define PARALLEL_RS_TRIS TRISBbits.TRISB7
#define PARALLEL_RS_LAT LATBbits.LATB7
#define PARALLEL_RW_TRIS TRISBbits.TRISB6
#define PARALLEL_RW_LAT LATBbits.LATB6
#define PARALLEL_EN_TRIS TRISBbits.TRISB5
#define PARALLEL_EN_LAT LATBbits.LATB5
#define PARALLEL_D4_TRIS TRISBbits.TRISB4
#define PARALLEL_D4_LAT LATBbits.LATB4
#define PARALLEL_D5_TRIS TRISBbits.TRISB3
#define PARALLEL_D5_LAT LATBbits.LATB3
#define PARALLEL_D6_TRIS TRISBbits.TRISB2
#define PARALLEL_D6_LAT LATBbits.LATB2
#define PARALLEL_D7_TRIS TRISBbits.TRISB1
#define PARALLEL_D7_LAT LATBbits.LATB1
#define PARALLEL_BUSY_TRIS TRISBbits.TRISB1
#define PARALLEL_BUSY_PORT PORTBbits.RB1
 
#define NFC_IRQ_TRIS TRISAbits.TRISA5
#define NFC_IRQ_PORT PORTAbits.RA5
//#define NFC_RESET_TRIS TRISCbits.TRISC2
//#define NFC_RESET_LAT LATCbits.LATC2
 
#define I2C_CLK_TRIS TRISCbits.TRISC3
#define I2C_DAT_TRIS TRISCbits.TRISC4
 
#define UART1_RX_TRIS TRISCbits.TRISC7
#define UART1_TX_TRIS TRISCbits.TRISC6
 
// PPS bindings (RP Pins)
#define PPS_SPI2_CLK_IN 0 // A0
#define PPS_SPI2_CLK_OUT RPOR0 // A0
#define PPS_SPI2_MOSI RPOR3 // B0
#ifndef SPI2_WRITE_ONLY
#define PPS_SPI2_MISO 3 // NA
#endif
 
//#define PPS_UART2_RX 5
//#define PPS_UART2_TX RPOR6
 
#endif
/PIC Projects/PIC_27J13/i2c.h
0,0 → 1,81
#ifndef I2C_H
#define I2C_H
 
#define MAXI2CBUF 64
 
// I2C Operating Speed
#define I2C_400KHZ 0x0
#define I2C_100KHZ 0x1
 
// Operating State
#define I2C_IDLE 0x1
#define I2C_STARTED 0x2
#define I2C_RCV_DATA 0x3
#define I2C_SEND_DATA 0x4
#define I2C_SEND_ADDR 0x5
#define I2C_SEND_ADDR_2 0x6
#define I2C_CHECK_ACK_SEND 0x7
#define I2C_CHECK_ACK_RECV 0x8
#define I2C_CHECK_ACK_RESTART 0x9
#define I2C_REQ_DATA 0xA
#define I2C_SEND_STOP 0xB
#define I2C_SEND_START 0xC
 
// Operating Mode
#define I2C_MODE_SLAVE 0x10
#define I2C_MODE_MASTER 0x11
 
// Master Status
#define I2C_MASTER_SEND 0x20
#define I2C_MASTER_RECV 0x21
#define I2C_MASTER_RESTART 0x22
#define I2C_MASTER_IDLE 0x23
 
// Return Status
#define I2C_SEND_OK 0x30
#define I2C_SEND_FAIL 0x31
#define I2C_RECV_OK 0x32
#define I2C_RECV_FAIL 0x33
#define I2C_DATA_AVAL 0x34
#define I2C_ERR_NOADDR 0x35
#define I2C_ERR_OVERRUN 0x36
#define I2C_ERR_NODATA 0x37
#define I2C_ERR_BUFFER_OVERRUN 0x38
 
typedef struct __I2C_DATA {
unsigned char buffer_in[MAXI2CBUF];
unsigned char buffer_in_len;
unsigned char buffer_in_len_tmp;
unsigned char buffer_in_read_ind;
unsigned char buffer_in_write_ind;
unsigned char buffer_out[MAXI2CBUF];
unsigned char buffer_out_len;
unsigned char buffer_out_ind;
 
unsigned char operating_mode;
unsigned char operating_state;
unsigned char return_status;
 
unsigned char master_dest_addr;
unsigned char master_status;
unsigned char slave_in_last_byte;
unsigned char slave_sending_data;
} I2C_DATA;
 
void I2C_Init(void);
void I2C_Interrupt_Handler(void);
void I2C_Interrupt_Slave(void);
void I2C_Interrupt_Master(void);
void I2C_Configure_Slave(unsigned char);
void I2C_Configure_Master(unsigned char speed);
void I2C_Master_Send(unsigned char address, unsigned char length, unsigned char *msg);
void I2C_Master_Recv(unsigned char address, unsigned char length);
void I2C_Master_Restart(unsigned char address, unsigned char msg, unsigned char length);
unsigned char I2C_Get_Status(void);
unsigned char I2C_Buffer_Len(void);
unsigned char I2C_Read_Buffer(char *buffer);
unsigned char I2C_Process_Send(unsigned char);
 
#endif
/PIC Projects/PIC_27J13/interrupts.h
0,0 → 1,18
#ifndef INTERRUPTS_H
#define INTERRUPTS_H
 
// Note: As the interrupt system is currently setup, at the end
// of each high-priority interrupt, the system will check to
// see if the processor may be put to sleep. This is done
// with the call sleep_high_interrupt_if_okay() which is defined
// in msg_queues.h -- init_queues() MUST be called prior to
// enabling interrupts if sleep_high_interrupt_if_okay() is called!
 
// Initialize the interrupts
void Interrupt_Init(void);
 
// Enable the interrupts (high and low priority)
void Interrupt_Enable(void);
void Interrupt_Disable(void);
 
#endif
/PIC Projects/PIC_27J13/pin_interrupts.h
0,0 → 1,10
#ifndef PIN_INTERRUPTS_H
#define PIN_INTERRUPTS_H
 
void intx_init(void);
void int1_interrupt_handler(void);
 
void port_b_int_init(void);
void port_b_int_interrupt_handler(void);
 
#endif
/PIC Projects/PIC_27J13/pwm.h
0,0 → 1,10
#ifndef PWM_H
#define PWM_H
 
void pwm_init(void);
void pwm_start(void);
void pwm_stop(void);
 
static char pwm_on = 0;
 
#endif
/PIC Projects/PIC_27J13/timers.h
0,0 → 1,9
#ifndef TIMERS_H
#define TIMERS_H
 
void Timer1_Init(void);
void Timer1_Enable(void);
void Timer1_Disable(void);
void Timer1_Interrupt_Handler(void);
 
#endif
/PIC Projects/PIC_27J13/uart.h
0,0 → 1,32
#ifndef UART_H
#define UART_H
 
#define MAXUARTBUF 125
 
#define UART1_BREAK_CHAR 0x0D //(CR)
 
#define UART1_RECV_BUFFER
//#define UART1_RECV_XBEE
 
typedef struct __UART_DATA {
unsigned char buffer_in[MAXUARTBUF];
unsigned char buffer_in_read_ind;
unsigned char buffer_in_write_ind;
unsigned char buffer_in_len;
unsigned char buffer_in_len_tmp;
 
unsigned char buffer_out[MAXUARTBUF];
unsigned char buffer_out_ind;
unsigned char buffer_out_len;
} UART_DATA;
 
void UART1_Init(void);
void UART1_Recv_Interrupt_Handler(void);
void UART1_Send_Interrupt_Handler(void);
void UART1_WriteS(const rom char *fmt, ...);
void UART1_WriteF(float f, unsigned char m);
void UART1_WriteB(const char *msg, unsigned char length);
void UART1_WriteC(const unsigned char c);
unsigned char UART1_Buffer_Len(void);
unsigned char UART1_Read_Buffer(unsigned char *buffer);
#endif
/PIC Projects/PIC_27J13/xbee.h
0,0 → 1,269
#ifndef XBEE_H
#define XBEE_H
 
#define XBEE_BUFFER_SIZE 227
 
// If API mode = 2 is enabled
#define XBEE_USE_ESCAPE_CHAR
 
#define XBEE_ESCAPE_VAL 0x20
#define XBEE_START_DELIMITER 0x7E
#define XBEE_ESCAPE_CHAR 0x7D
#define XBEE_XON 0x11
#define XBEE_XOFF 0x13
 
// Expected 'next' state
#define XBEE_STATE_READ_START 10
#define XBEE_STATE_READ_LENGTH_HIGH 11
#define XBEE_STATE_READ_LENGTH_LOW 12
#define XBEE_STATE_READ_FRAME_DATA 13
#define XBEE_STATE_READ_CHECKSUM 14
 
// Command Frame Type
#define XBEE_TX_AT_COMMAND 0x08
#define XBEE_TX_AT_COMMAND_QUEUE 0x09
#define XBEE_RX_AT_COMMAND_RESPONSE 0x88
 
#define XBEE_TX_DATA_PACKET 0x10
#define XBEE_RX_DATA_PACKET 0x90
#define XBEE_RX_DATA_TX_STATUS 0x8B
#define XBEE_RX_IO_DATA_SAMPLE 0x92
#define XBEE_TX_EXPLICIT_COMMAND 0x11
#define XBEE_RX_EXPLICIT_COMMAND 0x91
 
#define XBEE_TX_REMOTE_AT_COMMAND 0x17
#define XBEE_RX_REMOTE_AT_COMMAND_RESPONSE 0x97
 
#define XBEE_TX_CREATE_SOURCE_ROUTE 0x21
#define XBEE_RX_ROUTE_RECORD 0xA1
#define XBEE_RX_NODE_IDENTIFICATION 0x95
#define XBEE_RX_FRAME_MODEM_STATUS 0x8A
 
typedef struct {
union {
unsigned long long_value;
unsigned char char_value[4]; // Little Endian!!
} UPPER_32;
union {
unsigned long long_value;
unsigned char char_value[4]; // Little Endian!!
} LOWER_32;
} XBEE_ADDRESS_64;
 
typedef struct {
union {
unsigned int int_value;
unsigned char char_value[2]; // Little Endian!!
} INT_16;
} XBEE_ADDRESS_16;
 
// Unique Frame Components
typedef struct {
unsigned char frame_type;
unsigned char frame_id;
unsigned char command[2];
unsigned char data[XBEE_BUFFER_SIZE];
} XBEE_TX_AT_COMMAND_FRAME;
#define XBEE_TX_AT_COMMAND_FRAME_SIZE 4
 
typedef struct {
unsigned char frame_type;
unsigned char frame_id;
unsigned char command[2];
unsigned char data[XBEE_BUFFER_SIZE];
} XBEE_TX_AT_COMMAND_QUEUE_FRAME;
#define XBEE_TX_AT_COMMAND_QUEUE_FRAME_SIZE 4
 
typedef struct {
unsigned char frame_type;
unsigned char frame_id;
unsigned char command[2];
unsigned char command_status;
unsigned char data[XBEE_BUFFER_SIZE];
} XBEE_RX_AT_COMMAND_RESPONSE_FRAME;
#define XBEE_RX_AT_COMMAND_RESPONSE_FRAME_SIZE 5
 
typedef struct {
unsigned char frame_type;
unsigned char frame_id;
XBEE_ADDRESS_64 destination_64;
XBEE_ADDRESS_16 destination_16;
unsigned char broadcast_radius;
unsigned char options;
unsigned char data[XBEE_BUFFER_SIZE];
} XBEE_TX_DATA_PACKET_FRAME;
#define XBEE_TX_DATA_PACKET_FRAME_SIZE 14
 
typedef struct {
unsigned char frame_type;
XBEE_ADDRESS_64 source_64;
XBEE_ADDRESS_16 source_16;
unsigned char recieve_options;
unsigned char data[XBEE_BUFFER_SIZE];
} XBEE_RX_DATA_PACKET_FRAME;
#define XBEE_RX_DATA_PACKET_FRAME_SIZE 12
 
typedef struct {
unsigned char frame_type;
unsigned char frame_id;
XBEE_ADDRESS_16 destination_16;
unsigned char transmit_retry_count;
unsigned char delivery_status;
unsigned char discovery_status;
} XBEE_RX_DATA_TX_STATUS_FRAME;
#define XBEE_RX_DATA_TX_STATUS_FRAME_SIZE 7
 
typedef struct {
unsigned char frame_type;
XBEE_ADDRESS_64 source_64;
XBEE_ADDRESS_16 source_16;
unsigned char recieve_options;
unsigned char number_of_samples;
unsigned char digital_ch_mask[2];
unsigned char analog_ch_mask;
unsigned char digital_samples[2];
unsigned char analog_samples[8];
} XBEE_RX_IO_DATA_SAMPLE_FRAME;
#define XBEE_RX_IO_DATA_SAMPLE_FRAME_SIZE 26
 
typedef struct {
unsigned char frame_type;
unsigned char frame_id;
XBEE_ADDRESS_64 destination_64;
XBEE_ADDRESS_16 destination_16;
unsigned char source_endpoint;
unsigned char destination_endpoint;
unsigned char cluster_id[2];
unsigned char profile_id[2];
unsigned char broadcast_radius;
unsigned char transmit_options;
unsigned char data[XBEE_BUFFER_SIZE];
} XBEE_TX_EXPLICIT_COMMAND_FRAME;
#define XBEE_TX_EXPLICIT_COMMAND_FRAME_SIZE 20
 
typedef struct {
unsigned char frame_type;
XBEE_ADDRESS_64 source_64;
XBEE_ADDRESS_16 source_16;
unsigned char source_endpoint;
unsigned char destination_endpoint;
unsigned char cluster_id[2];
unsigned char profile_id[2];
unsigned char recieve_options;
unsigned char data[XBEE_BUFFER_SIZE];
} XBEE_RX_EXPLICIT_COMMAND_FRAME;
#define XBEE_RX_EXPLICIT_COMMAND_FRAME_SIZE 18
 
typedef struct {
unsigned char frame_type;
unsigned char frame_id;
XBEE_ADDRESS_64 destination_64;
XBEE_ADDRESS_16 destination_16;
unsigned char remote_options;
unsigned char command[2];
unsigned char data[XBEE_BUFFER_SIZE];
} XBEE_TX_REMOTE_AT_COMMAND_FRAME;
#define XBEE_TX_REMOTE_AT_COMMAND_FRAME_SIZE 15
 
typedef struct {
unsigned char frame_type;
unsigned char frame_id;
XBEE_ADDRESS_64 source_64;
XBEE_ADDRESS_16 source_16;
unsigned char command[2];
unsigned char command_status;
unsigned char command_data[4];
} XBEE_RX_REMOTE_AT_COMMAND_FRAME;
#define XBEE_RX_REMOTE_AT_COMMAND_FRAME_SIZE 19
 
typedef struct {
unsigned char frame_type;
unsigned char frame_id;
XBEE_ADDRESS_64 destination_64;
XBEE_ADDRESS_16 destination_16;
unsigned char route_options;
unsigned char num_of_addresses;
unsigned char addresses[XBEE_BUFFER_SIZE];
} XBEE_TX_CREATE_SOURCE_ROUTE_FRAME;
#define XBEE_TX_CREATE_SOURCE_ROUTE_FRAME_SIZE 14
 
typedef struct {
unsigned char frame_type;
XBEE_ADDRESS_64 source_64;
XBEE_ADDRESS_16 source_16;
unsigned char recieve_options;
unsigned char num_of_addresses;
unsigned char addresses[XBEE_BUFFER_SIZE];
} XBEE_RX_ROUTE_RECORD_FRAME;
#define XBEE_RX_ROUTE_RECORD_FRAME_SIZE 13
 
typedef struct {
unsigned char frame_type;
XBEE_ADDRESS_64 source_64;
XBEE_ADDRESS_16 source_16;
unsigned char recieve_options;
XBEE_ADDRESS_16 remote_16;
XBEE_ADDRESS_64 remote_64;
unsigned char NI_string[2];
XBEE_ADDRESS_16 parent_16;
unsigned char device_type;
unsigned char source_event;
unsigned char profile_id[2];
unsigned char manufacturer_id[2];
} XBEE_RX_NODE_IDENTIFICATION_INDICATOR_FRAME;
#define XBEE_RX_NODE_IDENTIFICATION_INDICATOR_FRAME_SIZE 32
 
typedef struct {
unsigned char frame_type;
unsigned char status;
} XBEE_RX_MODEM_STATUS_FRAME;
#define XBEE_RX_MODEM_STATUS_FRAME_SIZE 2
 
// Common Frame Components
typedef struct __XBEE_FRAME {
unsigned char start_delimiter;
XBEE_ADDRESS_16 length;
union {
XBEE_TX_AT_COMMAND_FRAME TX_AT_COMMAND;
XBEE_TX_AT_COMMAND_QUEUE_FRAME TX_AT_COMMAND_QUEUE;
XBEE_RX_AT_COMMAND_RESPONSE_FRAME RX_AT_COMMAND_RESPONSE;
XBEE_TX_DATA_PACKET_FRAME TX_DATA_PACKET;
XBEE_RX_DATA_PACKET_FRAME RX_DATA_PACKET;
XBEE_RX_DATA_TX_STATUS_FRAME RX_DATA_TX_STATUS;
XBEE_RX_IO_DATA_SAMPLE_FRAME RX_IO_DATA_SAMPLE;
XBEE_TX_EXPLICIT_COMMAND_FRAME TX_EXPLICIT_COMMAND;
XBEE_RX_EXPLICIT_COMMAND_FRAME RX_EXPLICIT_COMMAND;
XBEE_TX_REMOTE_AT_COMMAND_FRAME TX_REMOTE_AT_COMMAND;
XBEE_RX_REMOTE_AT_COMMAND_FRAME RX_REMOTE_AT_COMMAND;
XBEE_TX_CREATE_SOURCE_ROUTE_FRAME TX_CREATE_SOURCE_ROUTE;
XBEE_RX_ROUTE_RECORD_FRAME RX_ROUTE_RECORD;
XBEE_RX_NODE_IDENTIFICATION_INDICATOR_FRAME RX_NODE_IDENTIFICATION;
XBEE_RX_MODEM_STATUS_FRAME RX_MODEM_STATUS;
} FRAME;
} XBEE_FRAME;
 
// Overall Data Structure
typedef struct __xbee_data {
XBEE_FRAME rcv_frame;
unsigned int dataind;
unsigned char checksum_sum;
unsigned char read_state;
unsigned char frame_rdy;
unsigned char escape_flag;
} XBEE_DATA;
 
 
void XBee_Init(void);
void XBee_Serial_In(unsigned char);
void XBee_Process_Received_Frame(void);
void XBee_Process_Transmit_Frame(unsigned char *data, unsigned char length);
 
unsigned int XBee_Get_Received_Frame(unsigned char *frame);
 
void XBee_Set_RTS(unsigned char);
unsigned char XBee_Read_CTS(void);
 
void XBee_Convert_Endian_64(XBEE_ADDRESS_64 *src);
void XBee_Convert_Endian_16(XBEE_ADDRESS_16 *src);
 
#endif
/PIC Projects/PIC_27J13/led_HT16K33.c
0,0 → 1,137
#include "led_HT16K33.h"
#include "i2c.h"
 
static const char numbertable[] = {
0x3F /* 0 */,
0x06 /* 1 */,
0x5B /* 2 */,
0x4F /* 3 */,
0x66 /* 4 */,
0x6D /* 5 */,
0x7D, /* 6 */
0x07, /* 7 */
0x7F, /* 8 */
0x6F, /* 9 */
};
 
static const char alphatable[] = {
0x77, /* a */
0x7C, /* b */
0x39, /* C */
0x5E, /* d */
0x79, /* E */
0x71, /* F */
};
 
static LED_DATA led_data;
static LED_DATA *led_data_p = &led_data;
 
void LED_Init() {
led_data_p->i2c_address = 0x70;
}
 
void LED_Start() {
unsigned char result;
unsigned char c = 0x21; // Cmd to turn on oscillator
I2C_Master_Send(led_data_p->i2c_address, 1, &c);
result = I2C_Get_Status();
while (!result) {
result = I2C_Get_Status();
}
 
LED_Blink_Rate(HT16K33_BLINK_OFF);
LED_Set_Brightness(15); // Max brightness
LED_Clear();
LED_Write_Display();
}
 
void LED_Set_Brightness(unsigned char c) {
unsigned char result;
if (c > 15) c = 15;
c |= 0xE0;
 
I2C_Master_Send(led_data_p->i2c_address, 1, &c);
result = I2C_Get_Status();
while (!result) {
result = I2C_Get_Status();
}
}
 
void LED_Blink_Rate(unsigned char c) {
unsigned char buffer;
 
if (c > 3) c = 0;
 
buffer = HT16K33_BLINK_CMD | HT16K33_BLINK_DISPLAYON | (c << 1);
 
I2C_Master_Send(led_data_p->i2c_address, 1, &buffer);
buffer = I2C_Get_Status();
while (!buffer) {
buffer = I2C_Get_Status();
}
}
 
void LED_Write_Display() {
unsigned char result;
led_data_p->display_buffer[0] = 0x00; // Start at address 0x00
I2C_Master_Send(led_data_p->i2c_address, 17, led_data_p->display_buffer);
 
result = I2C_Get_Status();
while (!result) {
result = I2C_Get_Status();
}
}
 
void LED_Clear() {
unsigned char c;
for (c = 0; c < 17; c++) {
led_data_p->display_buffer[c] = 0;
}
}
 
void LED_Draw_Colon(unsigned char c) {
if (c) {
led_data_p->display_buffer[5] = 0xFF;
} else {
led_data_p->display_buffer[5] = 0;
}
}
 
void LED_Write_Digit_Raw(unsigned char loc, unsigned char bitmask) {
if (loc > 4) return;
led_data_p->display_buffer[(loc<<1)+1] = bitmask;
}
 
void LED_Write_Digit_Num(unsigned char loc, unsigned char num, unsigned char dot) {
if (loc > 4) return;
if (loc > 1) loc++;
LED_Write_Digit_Raw(loc, numbertable[num] | dot << 7);
}
 
void LED_Write_Digit_Alpha(unsigned char loc, unsigned char alpha, unsigned char dot) {
if (loc > 4) return;
if (loc > 1) loc++;
LED_Write_Digit_Raw(loc, alphatable[alpha] | dot << 7);
}
 
void LED_Write_Num(unsigned int i) {
LED_Write_Digit_Num(0, (i%10000)/1000, 0);
LED_Write_Digit_Num(1, (i%1000)/100, 0);
LED_Write_Digit_Num(2, (i%100)/10, 0);
LED_Write_Digit_Num(3, i%10, 0);
 
if (i < 10) {
LED_Write_Digit_Raw(0, 0);
LED_Write_Digit_Raw(1, 0);
LED_Write_Digit_Raw(3, 0);
} else if (i < 100) {
LED_Write_Digit_Raw(0, 0);
LED_Write_Digit_Raw(1, 0);
} else if (i < 1000) {
LED_Write_Digit_Raw(0, 0);
}
LED_Write_Display();
}
/PIC Projects/PIC_27J13/led_HT16K33.h
0,0 → 1,32
#ifndef LED_BACKPACK_H
#define LED_BACKPACK_H
 
#define HT16K33_BLINK_CMD 0x80
#define HT16K33_BLINK_DISPLAYON 0x01
#define HT16K33_BLINK_OFF 0
#define HT16K33_BLINK_2HZ 1
#define HT16K33_BLINK_1HZ 2
#define HT16K33_BLINK_HALFHZ 3
 
#define HT16K33_CMD_BRIGHTNESS 0x0E
 
typedef struct {
unsigned char i2c_address;
unsigned char display_buffer[17];
} LED_DATA;
 
void LED_Init(void);
void LED_Start(void);
void LED_Set_Brightness(unsigned char c);
void LED_Blink_Rate(unsigned char c);
void LED_Write_Display(void);
void LED_Clear(void);
void LED_Draw_Colon(unsigned char c);
void LED_Write_Digit_Raw(unsigned char loc, unsigned char bitmask);
void LED_Write_Digit_Num(unsigned char loc, unsigned char num, unsigned char dot);
void LED_Write_Digit_Alpha(unsigned char loc, unsigned char alpha, unsigned char dot);
void LED_Write_Num(unsigned int i);
 
 
#endif /* LED_BACKPACK_H */
 
/PIC Projects/PIC_27J13/lux_TSL2561.c
0,0 → 1,229
#include "lux_TSL2561.h"
#include "defines.h"
#include "i2c.h"
#include <delays.h>
 
static TSL2561_DATA tsl2561_data;
static TSL2561_DATA *tsl2561_data_p = &tsl2561_data;
 
void LUX_Init(unsigned char address) {
tsl2561_data_p->address = address;
tsl2561_data_p->integration = TSL2561_INTEGRATIONTIME_13MS;
tsl2561_data_p->gain = TSL2561_GAIN_16X;
}
 
void LUX_Begin(void) {
unsigned char i, result, length, buffer[10];
unsigned char toSend = TSL2561_REGISTER_ID;
DBG_PRINT_LUX("Sending %X to address %X\r\n", toSend, tsl2561_data_p->address);
I2C_Master_Send(tsl2561_data_p->address, 1, &toSend);
do {
result = I2C_Get_Status();
} while (!result);
 
I2C_Master_Recv(tsl2561_data_p->address, 1);
do {
result = I2C_Get_Status();
} while (!result);
length = I2C_Read_Buffer((char *)buffer);
DBG_PRINT_LUX("Received %d bytes: ", length);
for (i = 0; i < length; i++) {
DBG_PRINT_LUX("%c ", buffer[i]);
}
DBG_PRINT_LUX("\r\n");
 
// Set default integration time and gain
LUX_Set_Timing(tsl2561_data_p->integration);
LUX_Set_Gain(tsl2561_data_p->gain);
 
// Start the chip in power-down mode
LUX_Disable();
}
 
void LUX_Enable() {
LUX_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
}
 
void LUX_Disable() {
LUX_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
}
 
void LUX_Set_Gain(tsl2561Gain_t gain) {
LUX_Enable();
tsl2561_data_p->gain = gain;
LUX_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
tsl2561_data_p->integration | tsl2561_data_p->gain);
LUX_Disable();
}
 
void LUX_Set_Timing(tsl2561IntegrationTime_t integration) {
LUX_Enable();
tsl2561_data_p->integration = integration;
LUX_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
tsl2561_data_p->integration | tsl2561_data_p->gain);
LUX_Disable();
}
 
unsigned long LUX_Calculate_Lux(unsigned int ch0, unsigned int ch1) {
unsigned long chScale, channel0, channel1, ratio1, ratio, temp, lux;
unsigned int b, m;
 
switch (tsl2561_data_p->integration) {
case TSL2561_INTEGRATIONTIME_13MS:
chScale = TSL2561_LUX_CHSCALE_TINT0;
break;
case TSL2561_INTEGRATIONTIME_101MS:
chScale = TSL2561_LUX_CHSCALE_TINT1;
break;
default: // No scaling ... integration time = 402ms
chScale = (1 << TSL2561_LUX_CHSCALE);
break;
}
 
// Scale for gain (1x or 16x)
if (!tsl2561_data_p->gain)
chScale = chScale << 4;
 
// scale the channel values
channel0 = (ch0 * chScale) >> TSL2561_LUX_CHSCALE;
channel1 = (ch1 * chScale) >> TSL2561_LUX_CHSCALE;
 
// find the ratio of the channel values (Channel1/Channel0)
ratio1 = 0;
if (channel0 != 0)
ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
 
// round the ratio value
ratio = (ratio1 + 1) >> 1;
 
#ifdef TSL2561_PACKAGE_CS
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C)) {
b = TSL2561_LUX_B1C; m = TSL2561_LUX_M1C;
} else if (ratio <= TSL2561_LUX_K2C) {
b = TSL2561_LUX_B2C; m = TSL2561_LUX_M2C;
} else if (ratio <= TSL2561_LUX_K3C) {
b = TSL2561_LUX_B3C; m = TSL2561_LUX_M3C;
} else if (ratio <= TSL2561_LUX_K4C) {
b = TSL2561_LUX_B4C; m = TSL2561_LUX_M4C;
} else if (ratio <= TSL2561_LUX_K5C) {
b = TSL2561_LUX_B5C; m = TSL2561_LUX_M5C;
} else if (ratio <= TSL2561_LUX_K6C) {
b = TSL2561_LUX_B6C; m = TSL2561_LUX_M6C;
} else if (ratio <= TSL2561_LUX_K7C) {
b = TSL2561_LUX_B7C; m = TSL2561_LUX_M7C;
} else if (ratio > TSL2561_LUX_K8C) {
b = TSL2561_LUX_B8C; m = TSL2561_LUX_M8C;
}
#else
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T)) {
b = TSL2561_LUX_B1T; m = TSL2561_LUX_M1T;
} else if (ratio <= TSL2561_LUX_K2T) {
b = TSL2561_LUX_B2T; m = TSL2561_LUX_M2T;
} else if (ratio <= TSL2561_LUX_K3T) {
b = TSL2561_LUX_B3T; m = TSL2561_LUX_M3T;
} else if (ratio <= TSL2561_LUX_K4T) {
b = TSL2561_LUX_B4T; m = TSL2561_LUX_M4T;
} else if (ratio <= TSL2561_LUX_K5T) {
b = TSL2561_LUX_B5T; m = TSL2561_LUX_M5T;
} else if (ratio <= TSL2561_LUX_K6T) {
b = TSL2561_LUX_B6T; m = TSL2561_LUX_M6T;
} else if (ratio <= TSL2561_LUX_K7T) {
b = TSL2561_LUX_B7T; m = TSL2561_LUX_M7T;
} else if (ratio > TSL2561_LUX_K8T) {
b = TSL2561_LUX_B8T; m = TSL2561_LUX_M8T;
}
#endif
temp = ((channel0 * b) - (channel1 * m));
 
// do not allow negative lux value
if (temp < 0)
temp = 0;
 
// round lsb (2^(LUX_SCALE-1))
temp += (1 << (TSL2561_LUX_LUXSCALE-1));
 
// strip off fractional portion
lux = temp >> TSL2561_LUX_LUXSCALE;
 
return lux;
}
 
unsigned long LUX_Get_Full_Luminosity() {
unsigned long x;
 
// Enable the device by setting the control bit to 0x03
LUX_Enable();
 
// Wait x ms for ADC to complete
switch (tsl2561_data_p->integration) {
case TSL2561_INTEGRATIONTIME_13MS:
Delay10KTCYx(67);
break;
case TSL2561_INTEGRATIONTIME_101MS:
Delay10KTCYx(255);
Delay10KTCYx(230);
break;
default:
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(145);
break;
}
 
x = LUX_Read_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
x <<= 16;
x |= LUX_Read_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);
 
LUX_Disable();
 
return x;
}
 
unsigned int LUX_Get_Luminosity(unsigned char channel) {
unsigned long x = LUX_Get_Full_Luminosity();
 
if (channel == 0) {
// Reads two byte value from channel 0 (visible + infrared)
return (x & 0xFFFF);
} else if (channel == 1) {
// Reads two byte value from channel 1 (infrared)
return (x >> 16);
} else if (channel == 2) {
// Reads all and subtracts out just the visible!
return ( (x & 0xFFFF) - (x >> 16));
}
 
// Unknown channel!
return 0;
}
 
void LUX_Write_2_Bytes(unsigned char reg, unsigned char value) {
unsigned char buffer[2], result;
buffer[0] = reg;
buffer[1] = value;
I2C_Master_Send(tsl2561_data_p->address, 2, buffer);
do {
result = I2C_Get_Status();
} while (!result);
}
 
unsigned int LUX_Read_2_Bytes(unsigned char reg) {
unsigned char result, length, buffer[2];
unsigned int ret;
 
I2C_Master_Restart(tsl2561_data_p->address, reg, 2);
do {
result = I2C_Get_Status();
} while (!result);
length = I2C_Read_Buffer((char *)buffer);
ret = buffer[1] << 8;
ret |= buffer[0];
 
return ret;
}
/PIC Projects/PIC_27J13/lux_TSL2561.h
0,0 → 1,134
#ifndef LUX_TSL2561_H
#define LUX_TSL2561_H
 
#define TSL2561_VISIBLE 2 // channel 0 - channel 1
#define TSL2561_INFRARED 1 // channel 1
#define TSL2561_FULLSPECTRUM 0 // channel 0
 
// 3 i2c address options!
#define TSL2561_ADDR_LOW 0x29
#define TSL2561_ADDR_FLOAT 0x39
#define TSL2561_ADDR_HIGH 0x49
 
// Lux calculations differ slightly for CS package
//#define TSL2561_PACKAGE_CS
#define TSL2561_PACKAGE_T_FN_CL
 
#define TSL2561_READBIT (0x01)
 
#define TSL2561_COMMAND_BIT (0x80) // Must be 1
#define TSL2561_CLEAR_BIT (0x40) // Clears any pending interrupt (write 1 to clear)
#define TSL2561_WORD_BIT (0x20) // 1 = read/write word (rather than byte)
#define TSL2561_BLOCK_BIT (0x10) // 1 = using block read/write
 
#define TSL2561_CONTROL_POWERON (0x03)
#define TSL2561_CONTROL_POWEROFF (0x00)
 
#define TSL2561_LUX_LUXSCALE (14) // Scale by 2^14
#define TSL2561_LUX_RATIOSCALE (9) // Scale ratio by 2^9
#define TSL2561_LUX_CHSCALE (10) // Scale channel values by 2^10
#define TSL2561_LUX_CHSCALE_TINT0 (0x7517) // 322/11 * 2^TSL2561_LUX_CHSCALE
#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7) // 322/81 * 2^TSL2561_LUX_CHSCALE
 
// T, FN and CL package values
#define TSL2561_LUX_K1T (0x0040) // 0.125 * 2^RATIO_SCALE
#define TSL2561_LUX_B1T (0x01f2) // 0.0304 * 2^LUX_SCALE
#define TSL2561_LUX_M1T (0x01be) // 0.0272 * 2^LUX_SCALE
#define TSL2561_LUX_K2T (0x0080) // 0.250 * 2^RATIO_SCALE
#define TSL2561_LUX_B2T (0x0214) // 0.0325 * 2^LUX_SCALE
#define TSL2561_LUX_M2T (0x02d1) // 0.0440 * 2^LUX_SCALE
#define TSL2561_LUX_K3T (0x00c0) // 0.375 * 2^RATIO_SCALE
#define TSL2561_LUX_B3T (0x023f) // 0.0351 * 2^LUX_SCALE
#define TSL2561_LUX_M3T (0x037b) // 0.0544 * 2^LUX_SCALE
#define TSL2561_LUX_K4T (0x0100) // 0.50 * 2^RATIO_SCALE
#define TSL2561_LUX_B4T (0x0270) // 0.0381 * 2^LUX_SCALE
#define TSL2561_LUX_M4T (0x03fe) // 0.0624 * 2^LUX_SCALE
#define TSL2561_LUX_K5T (0x0138) // 0.61 * 2^RATIO_SCALE
#define TSL2561_LUX_B5T (0x016f) // 0.0224 * 2^LUX_SCALE
#define TSL2561_LUX_M5T (0x01fc) // 0.0310 * 2^LUX_SCALE
#define TSL2561_LUX_K6T (0x019a) // 0.80 * 2^RATIO_SCALE
#define TSL2561_LUX_B6T (0x00d2) // 0.0128 * 2^LUX_SCALE
#define TSL2561_LUX_M6T (0x00fb) // 0.0153 * 2^LUX_SCALE
#define TSL2561_LUX_K7T (0x029a) // 1.3 * 2^RATIO_SCALE
#define TSL2561_LUX_B7T (0x0018) // 0.00146 * 2^LUX_SCALE
#define TSL2561_LUX_M7T (0x0012) // 0.00112 * 2^LUX_SCALE
#define TSL2561_LUX_K8T (0x029a) // 1.3 * 2^RATIO_SCALE
#define TSL2561_LUX_B8T (0x0000) // 0.000 * 2^LUX_SCALE
#define TSL2561_LUX_M8T (0x0000) // 0.000 * 2^LUX_SCALE
 
// CS package values
#define TSL2561_LUX_K1C (0x0043) // 0.130 * 2^RATIO_SCALE
#define TSL2561_LUX_B1C (0x0204) // 0.0315 * 2^LUX_SCALE
#define TSL2561_LUX_M1C (0x01ad) // 0.0262 * 2^LUX_SCALE
#define TSL2561_LUX_K2C (0x0085) // 0.260 * 2^RATIO_SCALE
#define TSL2561_LUX_B2C (0x0228) // 0.0337 * 2^LUX_SCALE
#define TSL2561_LUX_M2C (0x02c1) // 0.0430 * 2^LUX_SCALE
#define TSL2561_LUX_K3C (0x00c8) // 0.390 * 2^RATIO_SCALE
#define TSL2561_LUX_B3C (0x0253) // 0.0363 * 2^LUX_SCALE
#define TSL2561_LUX_M3C (0x0363) // 0.0529 * 2^LUX_SCALE
#define TSL2561_LUX_K4C (0x010a) // 0.520 * 2^RATIO_SCALE
#define TSL2561_LUX_B4C (0x0282) // 0.0392 * 2^LUX_SCALE
#define TSL2561_LUX_M4C (0x03df) // 0.0605 * 2^LUX_SCALE
#define TSL2561_LUX_K5C (0x014d) // 0.65 * 2^RATIO_SCALE
#define TSL2561_LUX_B5C (0x0177) // 0.0229 * 2^LUX_SCALE
#define TSL2561_LUX_M5C (0x01dd) // 0.0291 * 2^LUX_SCALE
#define TSL2561_LUX_K6C (0x019a) // 0.80 * 2^RATIO_SCALE
#define TSL2561_LUX_B6C (0x0101) // 0.0157 * 2^LUX_SCALE
#define TSL2561_LUX_M6C (0x0127) // 0.0180 * 2^LUX_SCALE
#define TSL2561_LUX_K7C (0x029a) // 1.3 * 2^RATIO_SCALE
#define TSL2561_LUX_B7C (0x0037) // 0.00338 * 2^LUX_SCALE
#define TSL2561_LUX_M7C (0x002b) // 0.00260 * 2^LUX_SCALE
#define TSL2561_LUX_K8C (0x029a) // 1.3 * 2^RATIO_SCALE
#define TSL2561_LUX_B8C (0x0000) // 0.000 * 2^LUX_SCALE
#define TSL2561_LUX_M8C (0x0000) // 0.000 * 2^LUX_SCALE
 
enum {
TSL2561_REGISTER_CONTROL = 0x00,
TSL2561_REGISTER_TIMING = 0x01,
TSL2561_REGISTER_THRESHHOLDL_LOW = 0x02,
TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03,
TSL2561_REGISTER_THRESHHOLDH_LOW = 0x04,
TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05,
TSL2561_REGISTER_INTERRUPT = 0x06,
TSL2561_REGISTER_CRC = 0x08,
TSL2561_REGISTER_ID = 0x0A,
TSL2561_REGISTER_CHAN0_LOW = 0x0C,
TSL2561_REGISTER_CHAN0_HIGH = 0x0D,
TSL2561_REGISTER_CHAN1_LOW = 0x0E,
TSL2561_REGISTER_CHAN1_HIGH = 0x0F
};
 
typedef enum {
TSL2561_INTEGRATIONTIME_13MS = 0x00, // 13.7ms
TSL2561_INTEGRATIONTIME_101MS = 0x01, // 101ms
TSL2561_INTEGRATIONTIME_402MS = 0x02 // 402ms
}
tsl2561IntegrationTime_t;
 
typedef enum {
TSL2561_GAIN_0X = 0x00, // No gain
TSL2561_GAIN_16X = 0x10 // 16x gain
}
tsl2561Gain_t;
 
typedef struct __TSL25611_DATA {
unsigned char address;
tsl2561IntegrationTime_t integration;
tsl2561Gain_t gain;
} TSL2561_DATA;
 
void LUX_Init(unsigned char address);
void LUX_Begin(void);
void LUX_Enable(void);
void LUX_Disable(void);
void LUX_Set_Timing(tsl2561IntegrationTime_t integration);
void LUX_Set_Gain(tsl2561Gain_t gain);
unsigned long LUX_Calculate_Lux(unsigned int ch0, unsigned int ch1);
unsigned long LUX_Get_Full_Luminosity(void);
unsigned int LUX_Get_Luminosity(unsigned char channel);
 
void LUX_Write_2_Bytes(unsigned char reg, unsigned char value);
unsigned int LUX_Read_2_Bytes(unsigned char reg);
 
#endif /* LUX_TSL2561_H */
 
/PIC Projects/PIC_27J13/main.c
0,0 → 1,1216
#include "defines.h"
#include "interrupts.h"
#include "uart.h"
#include "i2c.h"
#include "spi.h"
#include "nfc_PN532.h"
#include "led_HT16K33.h"
#include "oled_ssd1306.h"
#include "oled_ssd1331.h"
#include "adc.h"
#include "xbee.h"
#include "timers.h"
#include "lux_TSL2561.h"
#include "oled_NHD-0216KZW-AB5.h"
#include "temp_BMP085.h"
#include <delays.h>
#include <string.h>
 
// <editor-fold defaultstate="collapsed" desc="Configuration Bits">
/* --------------------------- Configuration Bits --------------------------- */
/* CONFIG1L @ 0x1FFF8 */
#pragma config CFGPLLEN = ON // Enable PLL on startup
#pragma config PLLDIV = 3 // Set PPL prescaler to 3 (to get 4MHz)
#pragma config WDTEN = OFF // Turn off watchdog timer
#pragma config STVREN = OFF // Stack overflow/underflow reset disabled
#pragma config XINST = OFF // Turn off extended instruction set
 
/* CONFIG1H @ 0x1FFF9 */
#pragma config CP0 = OFF // Program memory is not code-protected
 
/* CONFIG2L @ 0x1FFFA */
#pragma config CLKOEC = OFF // CLKO output disabled on RA6 pin
#pragma config SOSCSEL = LOW // Low Power T1OSC/SOSC circuit selected
#pragma config IESO = ON // Internal external oscillator switch over disabled
#pragma config OSC = HSPLL // Use external oscillator (101)
#pragma config FCMEN = OFF // Fail-safe clock monitor disabled
 
/* CONFIG2H @ 0x1FFFB */
#pragma config WDTPS = 1 // Watchdog postscaler of 1:1
 
/* CONFIG3L @ 0x1FFFC */
#pragma config RTCOSC = T1OSCREF // RTCC uses T1OSC/T1CKI
#pragma config DSBOREN = ON // Deep sleep BOR enabled
#pragma config DSWDTPS = M2 // Deep sleep watchdog postscaler of 1:2 (36m)
#pragma config DSWDTEN = OFF // Deep sleep watchdog timer disabled
#pragma config DSWDTOSC = INTOSCREF // DSWDT clock select uses INTRC
 
/* CONFIG3H @ 0x1FFFD */
#pragma config PLLSEL = PLL96 // Use 96MHz PLL 4MHz -> 96MHz / 2 = 48MHz
#pragma config ADCSEL = BIT12 // 12-bit ADC
#pragma config MSSP7B_EN = MSK7 // 7-bit address masking mode
#pragma config IOL1WAY = OFF // IOLOCK bit can be set and cleared as needed
 
/* CONFIG4L @ 0x1FFFE */
#pragma config WPCFG = ON // Configuration words page protected
 
/* CONFIG4H @ 0x1FFFF */
#pragma config WPEND = PAGE_WPFP // Pages WPFP<6:0> through Configuration Words erase/write protected
#pragma config WPDIS = OFF // WPFP<6:0>/WPEND region ignored
/* -------------------------------------------------------------------------- */
// </editor-fold>
 
#if defined(_TEST_UART)
void main(void) {
unsigned char length = 0;
unsigned char buffer[100];
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
while (1) {
 
length = UART1_Read_Buffer((unsigned char *) buffer);
if (length != 0) {
UART1_WriteB((char *) buffer, length);
}
 
Delay10KTCYx(255);
Delay10KTCYx(255);
}
}
 
#elif defined(_TEST_I2C_MASTER)
void main(void) {
unsigned char i = 0;
unsigned char length = 0;
unsigned char result = 0;
unsigned char buffer[100];
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
I2C_Init(); // Initialize the I2C handler code
 
I2C_Configure_Master(I2C_100KHZ);
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
while (1) {
 
buffer[0] = 0x8;
 
I2C_Master_Send(0x24, 1, buffer);
do {
result = I2C_Get_Status();
} while (!result);
DBG_PRINT_MAIN("S:%X ", result);
 
I2C_Master_Recv(0x24, 2);
do {
result = I2C_Get_Status();
} while (!result);
DBG_PRINT_MAIN("S:%X ", result);
length = I2C_Read_Buffer(buffer);
DBG_PRINT_MAIN("L:%d D:", length);
for (i = 0; i < length; i++) {
DBG_PRINT_MAIN("%c ", buffer[i]);
}
 
// I2C_Master_Restart(0x30, 0xBB, 2);
// result = I2C_Get_Status();
// while (!result) {
// result = I2C_Get_Status();
// }
// DBG_PRINT_MAIN("S:%X ", result);
// length = I2C_Read_Buffer(buffer);
// DBG_PRINT_MAIN("L:%d D:", length);
// for (i = 0; i < length; i++) {
// DBG_PRINT_MAIN("%c ", buffer[i]);
// }
 
DBG_PRINT_MAIN("\r\n");
 
Delay10KTCYx(255);
Delay10KTCYx(255);
}
}
 
#elif defined(_TEST_I2C_SLAVE)
void main(void) {
unsigned char i = 0;
unsigned char length = 0;
unsigned char result = 0;
unsigned char buffer[100];
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
I2C_Init(); // Initialize the I2C handler code
 
I2C_Configure_Slave(0x24);
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
while (1) {
 
result = I2C_Get_Status();
while (!result) {
result = I2C_Get_Status();
}
DBG_PRINT_MAIN("%X ", result);
length = I2C_Read_Buffer(buffer);
DBG_PRINT_MAIN("%d ", length);
for (i = 0; i < length; i++) {
DBG_PRINT_MAIN("%X ", buffer[i]);
}
DBG_PRINT_MAIN("\r\n");
 
Delay10KTCYx(255);
Delay10KTCYx(255);
}
}
 
#elif defined(_TEST_NFC)
void main(void) {
unsigned char i, length = 0;
 
// NFC stuff
NFC_FIRMWARE_VERSION version;
NFC_TargetDataMiFare cardData[2];
NFC_TargetDataMiFare cardData_prev[2];
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
I2C_Init(); // Initialize the I2C handler code
NFC_Init(); // Initialize the NFC chip (uses I2C)
 
I2C_Configure_Master(I2C_400KHZ);
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
version = NFC_Get_Firmware_Version();
while (!version.IC) {
DBG_PRINT_MAIN("Waiting for NFC board..\r\n");
Delay10KTCYx(3);
version = NFC_Get_Firmware_Version();
}
DBG_PRINT_MAIN("Found chip PN5%X\r\n", version.IC);
DBG_PRINT_MAIN("Firmware ver. %d.%d\r\n", version.Ver, version.Rev);
NFC_SAMConfig();
 
memset(cardData, 0, 24);
 
while (1) {
 
// // This query will hang until the NFC chip replies (card detected)
// length = NFC_readPassiveTargetID(cardData);
// if (length) {
// DBG_PRINT_MAIN("Cards Found: %u\r\n", length);
// DBG_PRINT_MAIN("UID Length: %d bytes\r\n", cardData[0].NFCID_LEN);
// DBG_PRINT_MAIN("UID: ");
// for (i = 0; i < cardData[0].NFCID_LEN; i++) {
// DBG_PRINT_MAIN("%02X ", cardData[0].NFCID[i]);
// }
// DBG_PRINT_MAIN("\r\n");
// if (length == 2) {
// DBG_PRINT_MAIN("UID Length: %d bytes\r\n", cardData[1].NFCID_LEN);
// DBG_PRINT_MAIN("UID: ");
// for (i = 0; i < cardData[1].NFCID_LEN; i++) {
// DBG_PRINT_MAIN("%02X ", cardData[1].NFCID[i]);
// }
// DBG_PRINT_MAIN("\r\n");
// }
// }
 
// // This query will hang until the NFC chip replies (card detected)
// length = NFC_readPassiveTargetID(cardData);
// if (length) {
// DBG_PRINT_MAIN("Cards Found: %u\r\n", length);
// DBG_PRINT_MAIN("UID Length: %d bytes\r\n", cardData[0].NFCID_LEN);
// DBG_PRINT_MAIN("UID: ");
// for (i = 0; i < cardData[0].NFCID_LEN; i++) {
// DBG_PRINT_MAIN("%02X ", cardData[0].NFCID[i]);
// }
// DBG_PRINT_MAIN("\r\n");
// if (length == 2) {
// DBG_PRINT_MAIN("UID Length: %d bytes\r\n", cardData[1].NFCID_LEN);
// DBG_PRINT_MAIN("UID: ");
// for (i = 0; i < cardData[1].NFCID_LEN; i++) {
// DBG_PRINT_MAIN("%02X ", cardData[1].NFCID[i]);
// }
// DBG_PRINT_MAIN("\r\n");
// }
// }
 
// This query will not wait for a detection before responding
length = NFC_Poll_Targets(1, 1, cardData);
if (!length) {
memset(cardData_prev, 0, 24);
} else if (length == 1) {
if (memcmp(&cardData[0].NFCID, &cardData_prev[0].NFCID, cardData[0].NFCID_LEN) == 0) {
// Do nothing
} else if (memcmp(&cardData[0].NFCID, &cardData_prev[1].NFCID, cardData[0].NFCID_LEN) == 0) {
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
} else {
DBG_PRINT_MAIN("UID: ");
for (i = 0; i < cardData[0].NFCID_LEN; i++) {
DBG_PRINT_MAIN("%02X ", cardData[0].NFCID[i]);
}
DBG_PRINT_MAIN("\r\n");
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
}
memset(&cardData_prev[1], 0, 12);
} else if (length == 2) {
if (memcmp(&cardData[0].NFCID, &cardData_prev[0].NFCID, cardData[0].NFCID_LEN) == 0 &&
memcmp(&cardData[1].NFCID, &cardData_prev[1].NFCID, cardData[1].NFCID_LEN) == 0) {
// Do nothing
} else if (memcmp(&cardData[0].NFCID, &cardData_prev[1].NFCID, cardData[0].NFCID_LEN) == 0 &&
memcmp(&cardData[1].NFCID, &cardData_prev[0].NFCID, cardData[1].NFCID_LEN) == 0) {
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
memcpy((char *) &cardData_prev[1], (const char *) &cardData[1], 12);
} else if (memcmp(&cardData[0].NFCID, &cardData_prev[0].NFCID, cardData[0].NFCID_LEN) == 0) {
// First card matched
DBG_PRINT_MAIN("UID2: ");
for (i = 0; i < cardData[1].NFCID_LEN; i++) {
DBG_PRINT_MAIN("%02X ", cardData[1].NFCID[i]);
}
DBG_PRINT_MAIN("\r\n");
memcpy(&cardData_prev[1], (const char *) &cardData[1], 12);
} else if (memcmp(&cardData[1].NFCID, &cardData_prev[1].NFCID, cardData[1].NFCID_LEN) == 0) {
// Second card matched
DBG_PRINT_MAIN("UID1: ");
for (i = 0; i < cardData[0].NFCID_LEN; i++) {
DBG_PRINT_MAIN("%02X ", cardData[0].NFCID[i]);
}
DBG_PRINT_MAIN("\r\n");
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
} else {
// No match
DBG_PRINT_MAIN("UID1: ");
for (i = 0; i < cardData[0].NFCID_LEN; i++) {
DBG_PRINT_MAIN("%02X ", cardData[0].NFCID[i]);
}
DBG_PRINT_MAIN("\r\n");
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
DBG_PRINT_MAIN("UID2: ");
for (i = 0; i < cardData[1].NFCID_LEN; i++) {
DBG_PRINT_MAIN("%02X ", cardData[1].NFCID[i]);
}
DBG_PRINT_MAIN("\r\n");
memcpy((char *) &cardData_prev[1], (const char *) &cardData[1], 12);
}
}
}
}
 
#elif defined(_TEST_LED_BACKPACK)
void main(void) {
unsigned char i = 0;
unsigned int counter = 0;
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
I2C_Init(); // Initialize the I2C handler code
LED_Init(); // Initialize the LED backpack (uses I2C);
 
I2C_Configure_Master(I2C_400KHZ);
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
LED_Start();
LED_Write_Digit_Num(0, 1, 1);
LED_Write_Digit_Num(1, 2, 0);
LED_Write_Digit_Num(2, 3, 0);
LED_Write_Digit_Num(3, 4, 0);
LED_Write_Display();
for (i = 0; i < 15; i++) {
LED_Set_Brightness(15 - i);
Delay10KTCYx(100);
}
for (i = 0; i < 15; i++) {
LED_Set_Brightness(i);
Delay10KTCYx(100);
}
LED_Blink_Rate(HT16K33_BLINK_OFF);
 
while (1) {
LED_Write_Num(counter);
counter++;
if (counter > 9999)
counter = 0;
 
// Delay10KTCYx(255);
}
}
 
#elif defined(_TEST_SPI)
void main(void) {
unsigned char i = 0;
unsigned char length = 0;
unsigned char result = 0;
unsigned char buffer[100];
unsigned char test[8] = "ASDF123";
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
SPI2_Init(SPI2_FOSC_8); // Initialize the SPI module
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
while (1) {
 
SPI2_Write(test, 7);
while (result != 7) {
length = SPI2_Buffer_Read(buffer);
if (length) {
result += length;
}
}
result = 0;
 
for (i = 0; i < result; i++) {
DBG_PRINT_MAIN("%X ", buffer[i]);
}
DBG_PRINT_MAIN("\r\n");
 
Delay10KTCYx(255);
Delay10KTCYx(255);
}
}
 
#elif defined(_TEST_SSD1306_OLED)
void main(void) {
unsigned int i = 0;
unsigned long l = 0;
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
SPI2_Init(SPI2_FOSC_4); // Initialize the SPI module
SSD1306_Init(); // Initialize the OLED code
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
SSD1306_Begin(SSD1306_SWITCHCAPVCC);
 
SSD1306_Display(); // Show splashscreen
 
while (1) {
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Test_DrawLine();
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Test_DrawRect();
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Test_FillRect();
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Test_DrawCircle();
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Fill_Circle(SSD1306_LCDWIDTH / 2, SSD1306_LCDHEIGHT / 2, 10, SSD1306_WHITE);
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Test_DrawRoundRect();
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Test_FillRoundRect();
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Test_DrawTriangle();
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Test_FillTriangle();
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Test_DrawChar();
SSD1306_Display();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1306_Clear_Display();
SSD1306_Set_Text_Size(1);
SSD1306_Set_Text_Color(SSD1306_WHITE);
SSD1306_Set_Cursor(0, 0);
SSD1306_Write_String("Hello World!\n");
// SSD1306_Set_Text_Color_BG(BLACK, WHITE);
i = 65535;
SSD1306_Write_String("%u %d\n", i, i);
// SSD1306_Set_Text_Size(2);
// SSD1306_Set_Text_Color(WHITE);
l = 0xDEADBEEF;
SSD1306_Write_String("0x%lX", (long) l);
SSD1306_Display();
 
// SSD1306_Clear_Display();
// SSD1306_Set_Rotation(0);
// SSD1306_Set_Text_Size(1);
// SSD1306_Set_Text_Color(SSD1306_WHITE);
// SSD1306_Set_Cursor(0, 0);
// SSD1306_Write_String("%u", i);
// i++;
// SSD1306_Display();
 
}
}
 
#elif defined(_TEST_SSD1331_OLED)
void main(void) {
unsigned int i = 0;
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
SPI2_Init(SPI2_FOSC_64); // Initialize the SPI module
SSD1331_Init(); // Initialize the OLED code
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
SSD1331_Begin();
while (1) {
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1331_Set_Rotation(0);
SSD1331_Test_Pattern();
 
Delay10KTCYx(255);
Delay10KTCYx(255);
SSD1331_Clear_Display();
SSD1331_Set_Rotation(0);
SSD1331_Set_Cursor(0, 0);
SSD1331_Write_String("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabit adipiscing ante sed nibh tincidunt feugiat.");
 
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Clear_Display();
// SSD1331_Set_Rotation(3);
// SSD1331_Set_Cursor(0, 0);
// SSD1331_Write_String("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa");
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(0);
// SSD1331_Test_DrawLines(SSD1331_YELLOW);
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(3);
// SSD1331_Test_DrawLines(SSD1331_BLUE);
 
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(0);
// SSD1331_Test_DrawRect(SSD1331_GREEN);
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(1);
// SSD1331_Test_DrawRect(SSD1331_RED);
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(2);
// SSD1331_Test_DrawRect(SSD1331_BLUE);
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(3);
// SSD1331_Test_DrawRect(SSD1331_YELLOW);
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(0);
// SSD1331_Test_FillRect(SSD1331_YELLOW, SSD1331_MAGENTA);
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(3);
// SSD1331_Test_FillRect(SSD1331_BLUE, SSD1331_GREEN);
 
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(0);
// SSD1331_Clear_Display();
// SSD1331_Test_FillCircle(10, SSD1331_BLUE);
// SSD1331_Test_DrawCircle(10, SSD1331_WHITE);
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(3);
// SSD1331_Clear_Display();
// SSD1331_Test_FillCircle(10, SSD1331_MAGENTA);
// SSD1331_Test_DrawCircle(10, SSD1331_YELLOW);
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(0);
// SSD1331_Test_DrawTria();
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(3);
// SSD1331_Test_DrawTria();
 
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(0);
// SSD1331_Test_DrawRoundRect();
//
// Delay10KTCYx(255);
// Delay10KTCYx(255);
// SSD1331_Set_Rotation(3);
// SSD1331_Test_DrawRoundRect();
 
// SSD1331_Clear_Display();
// SSD1331_Set_Rotation(3);
// SSD1331_Set_Cursor(0,0);
// SSD1331_Set_Text_Color_BG(SSD1331_WHITE, SSD1331_BLACK);
// SSD1331_Write_String("%u", i);
// i++;
}
}
 
#elif defined(_TEST_ADC)
void main(void) {
unsigned int x, y, z;
unsigned char buffer[60];
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O except for AN0-AN2 (pins 2-4)
ANCON0 = 0xF8;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
SPI2_Init(SPI2_FOSC_8); // Initialize the SPI module
SSD1306_Init(); // Initialize the SSD1331 OLED display (uses SPI2)
ADC_Init(ADC_TAD_20, ADC_FOSC_64);
 
// I2C_Configure_Master(I2C_400KHZ);
SSD1306_Begin(SSD1306_SWITCHCAPVCC);
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
memset(buffer, 0, 60);
SSD1306_Clear_Display();
SSD1306_Display();
 
while (1) {
// ADC read from AN0-AN2 and prints to display
ADC_Start(ADC_CHANNEL_AN2);
// SSD1306_Fill_Rect(0, 0, SSD1306_LCDWIDTH, 8, SSD1331_BLACK);
SSD1306_Set_Cursor(0, 0);
while (!ADC_Get_Result(&x));
SSD1306_Write_String("X: %u", x);
SSD1306_Display();
 
ADC_Start(ADC_CHANNEL_AN1);
// SSD1306_Fill_Rect(0, 8, SSD1306_LCDWIDTH, 8, SSD1331_BLACK);
SSD1306_Set_Cursor(0, 8);
while (!ADC_Get_Result(&y));
SSD1306_Write_String("Y: %u", y);
SSD1306_Display();
 
ADC_Start(ADC_CHANNEL_AN0);
// SSD1306_Fill_Rect(0, 16, SSD1306_LCDWIDTH, 8, SSD1331_BLACK);
SSD1306_Set_Cursor(0, 16);
while (!ADC_Get_Result(&z));
SSD1306_Write_String("Z: %u", z);
SSD1306_Display();
}
}
 
#elif defined(_TEST_XBEE)
void main(void) {
unsigned int i, length = 0;
unsigned char buffer[100];
 
XBEE_RX_AT_COMMAND_RESPONSE_FRAME *rx_at_cmd_response_frame;
XBEE_RX_DATA_PACKET_FRAME *rx_data_frame;
XBEE_RX_DATA_TX_STATUS_FRAME *rx_tx_status_frame;
XBEE_RX_REMOTE_AT_COMMAND_FRAME *rx_remote_at_cmd_frame;
XBEE_RX_NODE_IDENTIFICATION_INDICATOR_FRAME *rx_node_ident_frame;
XBEE_RX_MODEM_STATUS_FRAME *rx_modem_status_frame;
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
UART1_Init(); // Initialize the UART handler code
XBee_Init();
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
while (1) {
 
//#define _ROUTER
#define _COORDINATOR
 
#ifdef _ROUTER
XBEE_TX_DATA_PACKET_FRAME *tx_data_frame;
tx_data_frame = (void *) buffer;
tx_data_frame->frame_type = XBEE_TX_DATA_PACKET;
tx_data_frame->frame_id = 1;
tx_data_frame->destination_64.UPPER_32.long_value = 0x00000000;
tx_data_frame->destination_64.LOWER_32.long_value = 0x00000000;
tx_data_frame->destination_16.INT_16.int_value = 0xFEFF;
tx_data_frame->broadcast_radius = 0;
tx_data_frame->options = 0;
tx_data_frame->data[0] = 0x54;
tx_data_frame->data[1] = 0x78;
tx_data_frame->data[2] = 0x32;
tx_data_frame->data[3] = 0x43;
tx_data_frame->data[4] = 0x6F;
tx_data_frame->data[5] = 0x6F;
tx_data_frame->data[6] = 0x72;
tx_data_frame->data[7] = 0x11;
XBee_Process_Transmit_Frame(buffer, XBEE_TX_DATA_PACKET_FRAME_SIZE + 8);
 
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
#endif
 
#ifdef _COORDINATOR
length = XBee_Get_Received_Frame(buffer);
if (length != 0) {
switch (*(unsigned char *) buffer) {
case XBEE_RX_AT_COMMAND_RESPONSE:
DBG_PRINT_MAIN("XBEE: parsing recieved AT command response frame\r\n");
rx_at_cmd_response_frame = (void *) buffer;
DBG_PRINT_MAIN("Frame ID: %u\r\n", rx_at_cmd_response_frame->frame_id);
DBG_PRINT_MAIN("AT Command: %c%c Status: %02X\r\n", rx_at_cmd_response_frame->command[0], \\
rx_at_cmd_response_frame->command[1], rx_at_cmd_response_frame->command_status);
if (length > XBEE_RX_AT_COMMAND_RESPONSE_FRAME_SIZE) {
DBG_PRINT_MAIN("Command Data: ");
for (i = 0; i < length - XBEE_RX_AT_COMMAND_RESPONSE_FRAME_SIZE; i++) {
DBG_PRINT_MAIN("%02X ", rx_at_cmd_response_frame->data[i]);
}
DBG_PRINT_MAIN("\r\n");
}
break;
case XBEE_RX_DATA_PACKET:
DBG_PRINT_MAIN("XBEE: parsing recieved data recieved frame\r\n");
rx_data_frame = (void *) buffer;
XBee_Convert_Endian_64(&(rx_data_frame->source_64));
XBee_Convert_Endian_16(&(rx_data_frame->source_16));
DBG_PRINT_MAIN("Source 64: %08lX %08lX Source 16: %04X Options: %02X\r\n", \\
rx_data_frame->source_64.UPPER_32.long_value, \\
rx_data_frame->source_64.LOWER_32.long_value, \\
rx_data_frame->source_16.INT_16.int_value, \\
rx_data_frame->recieve_options);
DBG_PRINT_MAIN("Data: ");
for (i = 0; i < length - XBEE_RX_DATA_PACKET_FRAME_SIZE; i++) {
DBG_PRINT_MAIN("%02X ", rx_data_frame->data[i]);
}
DBG_PRINT_MAIN("\r\n");
break;
case XBEE_RX_DATA_TX_STATUS:
DBG_PRINT_MAIN("XBEE: parsing recieved TX status frame\r\n");
rx_tx_status_frame = (void *) buffer;
XBee_Convert_Endian_16(&(rx_tx_status_frame->destination_16));
DBG_PRINT_MAIN("Frame ID: %u Destination 16: %04X\r\n", \\
rx_tx_status_frame->frame_id, rx_tx_status_frame->destination_16.INT_16.int_value);
DBG_PRINT_MAIN("Transmit Retry Count: %02X Delivery Status: %02X Discovery Status: %02X\r\n", \\
rx_tx_status_frame->transmit_retry_count, rx_tx_status_frame->delivery_status, \\
rx_tx_status_frame->discovery_status);
break;
case XBEE_RX_IO_DATA_SAMPLE:
DBG_PRINT_MAIN("XBEE: parsing recieved IO data sample frame\r\n");
break;
case XBEE_RX_EXPLICIT_COMMAND:
DBG_PRINT_MAIN("XBEE: parsing recieved explicit command frame\r\n");
break;
case XBEE_RX_REMOTE_AT_COMMAND_RESPONSE:
DBG_PRINT_MAIN("XBEE: parsing recieved remote AT command frame\r\n");
rx_remote_at_cmd_frame = (void *) buffer;
break;
case XBEE_RX_ROUTE_RECORD:
DBG_PRINT_MAIN("XBEE: parsing recieved route record frame\r\n");
break;
case XBEE_RX_NODE_IDENTIFICATION:
DBG_PRINT_MAIN("XBEE: parsing recieved node identification frame\r\n");
rx_node_ident_frame = (void *) buffer;
XBee_Convert_Endian_64(&(rx_node_ident_frame->source_64));
XBee_Convert_Endian_16(&(rx_node_ident_frame->source_16));
XBee_Convert_Endian_64(&(rx_node_ident_frame->remote_64));
XBee_Convert_Endian_16(&(rx_node_ident_frame->remote_16));
XBee_Convert_Endian_16(&(rx_node_ident_frame->parent_16));
DBG_PRINT_MAIN("Source 64: %08lX %08lX Source 16: %04X Options: %02X\r\n", \\
rx_node_ident_frame->source_64.UPPER_32.long_value, \\
rx_node_ident_frame->source_64.LOWER_32.long_value, \\
rx_node_ident_frame->source_16.INT_16.int_value, \\
rx_node_ident_frame->recieve_options);
DBG_PRINT_MAIN("Remote 64: %08lX %08lX Remote 16: %04X Parent 16: %04X\r\n", \\
rx_node_ident_frame->remote_64.UPPER_32.long_value, \\
rx_node_ident_frame->remote_64.LOWER_32.long_value, \\
rx_node_ident_frame->remote_16.INT_16.int_value, \\
rx_node_ident_frame->parent_16.INT_16.int_value);
DBG_PRINT_MAIN("Device Type: %02X Source Event: %02X\r\n", \\
rx_node_ident_frame->device_type, rx_node_ident_frame->source_event);
break;
case XBEE_RX_FRAME_MODEM_STATUS:
DBG_PRINT_MAIN("XBEE: parsing recieved modem status frame\r\n");
rx_modem_status_frame = (void *) buffer;
DBG_PRINT_MAIN("Status: %02X\r\n", rx_modem_status_frame->status);
break;
default:
DBG_PRINT_MAIN("??\r\n");
break;
}
}
#endif
 
}
}
 
#elif defined(_TEST_NFC_TO_SSD1306_OLED)
void main(void) {
unsigned char length = 0;
 
// NFC stuff
NFC_FIRMWARE_VERSION version;
NFC_TargetDataMiFare cardData[2];
NFC_TargetDataMiFare cardData_prev[2];
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O except for AN0-AN2 (pins 2-4)
ANCON0 = 0xF8;
ANCON1 = 0x1F;
 
UART1_Init();
I2C_Init();
NFC_Init();
SPI2_Init(SPI2_FOSC_4);
SSD1306_Init();
 
I2C_Configure_Master(I2C_400KHZ);
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
DBG_PRINT_MAIN("\r\nBegin Program\r\n");
 
SSD1306_Begin(SSD1306_SWITCHCAPVCC);
memset(cardData, 0, 24);
memset(cardData_prev, 0, 24);
SSD1306_Clear_Display();
SSD1306_Set_Rotation(0);
SSD1306_Set_Cursor(0, 0);
 
version = NFC_Get_Firmware_Version();
while (!version.IC) {
SSD1306_Write_String("Waiting for NFC board..\r");
SSD1306_Display();
Delay10KTCYx(3);
version = NFC_Get_Firmware_Version();
}
SSD1306_Write_String("PN5%X Ver. %d.%d\r", version.IC, version.Ver, version.Rev);
SSD1306_Display();
NFC_SAMConfig();
 
while (1) {
 
// This query will not wait for a detection before responding
length = NFC_Poll_Targets(1, 1, cardData);
if (!length) {
memset(cardData_prev, 0, 24);
} else if (length == 1) {
if (memcmp(&cardData[0].NFCID, &cardData_prev[0].NFCID, cardData[0].NFCID_LEN) == 0) {
// Do nothing
} else if (memcmp(&cardData[0].NFCID, &cardData_prev[1].NFCID, cardData[0].NFCID_LEN) == 0) {
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
} else {
SSD1306_Write_String("UID: %02X %02X %02X %02X\n", cardData[0].NFCID[0], cardData[0].NFCID[1], cardData[0].NFCID[2], cardData[0].NFCID[3]);
SSD1306_Display();
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
}
memset(&cardData_prev[1], 0, 12);
} else if (length == 2) {
if (memcmp(&cardData[0].NFCID, &cardData_prev[0].NFCID, cardData[0].NFCID_LEN) == 0 &&
memcmp(&cardData[1].NFCID, &cardData_prev[1].NFCID, cardData[1].NFCID_LEN) == 0) {
// Do nothing
} else if (memcmp(&cardData[0].NFCID, &cardData_prev[1].NFCID, cardData[0].NFCID_LEN) == 0 &&
memcmp(&cardData[1].NFCID, &cardData_prev[0].NFCID, cardData[1].NFCID_LEN) == 0) {
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
memcpy((char *) &cardData_prev[1], (const char *) &cardData[1], 12);
} else if (memcmp(&cardData[0].NFCID, &cardData_prev[0].NFCID, cardData[0].NFCID_LEN) == 0) {
// First card matched
SSD1306_Write_String("UID: %02X %02X %02X %02X\n", cardData[1].NFCID[0], cardData[1].NFCID[1], cardData[1].NFCID[2], cardData[1].NFCID[3]);
SSD1306_Display();
memcpy(&cardData_prev[1], (const char *) &cardData[1], 12);
} else if (memcmp(&cardData[1].NFCID, &cardData_prev[1].NFCID, cardData[1].NFCID_LEN) == 0) {
// Second card matched
SSD1306_Write_String("UID: %02X %02X %02X %02X\n", cardData[0].NFCID[0], cardData[0].NFCID[1], cardData[0].NFCID[2], cardData[0].NFCID[3]);
SSD1306_Display();
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
} else {
// No match
SSD1306_Write_String("UID: %02X %02X %02X %02X\n", cardData[0].NFCID[0], cardData[0].NFCID[1], cardData[0].NFCID[2], cardData[0].NFCID[3]);
SSD1306_Display();
memcpy((char *) &cardData_prev[0], (const char *) &cardData[0], 12);
SSD1306_Write_String("UID: %02X %02X %02X %02X\n", cardData[1].NFCID[0], cardData[1].NFCID[1], cardData[1].NFCID[2], cardData[1].NFCID[3]);
SSD1306_Display();
memcpy((char *) &cardData_prev[1], (const char *) &cardData[1], 12);
}
}
}
}
 
#elif defined(_TEST_TIMER1_RTC)
void main(void) {
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O except for AN0-AN2 (pins 2-4)
ANCON0 = 0xF8;
ANCON1 = 0x1F;
Timer1_Init();
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
LED_BLUE_TRIS = 0;
LED_RED_TRIS = 0;
Timer1_Enable();
 
while (1) {
 
}
}
 
#elif defined(_TEST_LUX)
void main(void) {
unsigned int ir, full;
unsigned long lum;
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O except for AN0-AN2 (pins 2-4)
ANCON0 = 0xF8;
ANCON1 = 0x1F;
 
UART1_Init();
I2C_Init();
LUX_Init(TSL2561_ADDR_FLOAT);
I2C_Configure_Master(I2C_100KHZ);
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
LUX_Begin();
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
LUX_Set_Gain(TSL2561_GAIN_0X); // set no gain (for bright situtations)
// LUX_SetGain(TSL2561_GAIN_16X); // set 16x gain (for dim situations)
 
// Changing the integration time gives you a longer time over which to sense light
// longer timelines are slower, but are good in very low light situtations!
LUX_Set_Timing(TSL2561_INTEGRATIONTIME_13MS); // shortest integration time (bright light)
// LUX_SetTiming(TSL2561_INTEGRATIONTIME_101MS); // medium integration time (medium light)
// LUX_SetTiming(TSL2561_INTEGRATIONTIME_402MS); // longest integration time (dim light)
 
while (1) {
lum = LUX_Get_Full_Luminosity();
ir = lum >> 16;
full = lum & 0xFFFF;
DBG_PRINT_LUX("IR: %d\r\n", ir);
DBG_PRINT_LUX("Visible: %d\r\n", full - ir);
DBG_PRINT_LUX("Full: %d\r\n", full);
DBG_PRINT_LUX("Lux: %ld\r\n\r\n", LUX_Calculate_Lux(full, ir));
 
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
}
}
 
#elif defined(_TEST_OLED_CHAR)
void main(void) {
int i;
unsigned char *buffer = "Test String";
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O except for AN0-AN2 (pins 2-4)
ANCON0 = 0xFF;
ANCON1 = 0x1F;
 
// UART1_Init();
NHD_Init();
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
NHD_Begin(16, 2);
NHD_Write_String("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do");
NHD_Set_Cursor(0,1);
NHD_Write_String("eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut e");
 
while (1) {
Delay10KTCYx(150);
NHD_Scroll_Display_Left();
}
}
 
#elif defined(_TEST_BMP)
void main(void) {
 
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O except for AN0-AN2 (pins 2-4)
ANCON0 = 0xF8;
ANCON1 = 0x1F;
 
UART1_Init();
I2C_Init();
BMP_Init();
I2C_Configure_Master(I2C_100KHZ);
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
BMP_Begin(BMP085_ULTRAHIGHRES);
 
while (1) {
DBG_PRINT_MAIN("Temp: ");
DBG_PRINT_MAIN_F(BMP_Read_Temperature(), 1);
DBG_PRINT_MAIN(" *C\r\n");
DBG_PRINT_MAIN("Pressure: %ld Pa\r\n", BMP_Read_Pressure());
DBG_PRINT_MAIN("Altitude: ");
DBG_PRINT_MAIN_F(BMP_Read_Altitude(101592), 1);
DBG_PRINT_MAIN(" meters\r\n");
 
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
}
}
 
#else
void main(void) {
unsigned int ir, full;
unsigned long lum;
/* --------------------- Oscillator Configuration --------------------- */
// OSCTUNEbits.PLLEN = 1; // Enable 4x PLL
OSCCONbits.IRCF = 0b111; // Set INTOSC postscaler to 8MHz
OSCCONbits.SCS = 0b00; // Use 96MHz PLL as primary clock source
/* -------------------------------------------------------------------- */
 
// Set all ports as digial I/O except for AN0-AN2 (pins 2-4)
ANCON0 = 0xF8;
ANCON1 = 0x1F;
 
// UART1_Init();
I2C_Init();
NHD_Init();
LUX_Init(TSL2561_ADDR_FLOAT);
 
I2C_Configure_Master(I2C_400KHZ);
 
Interrupt_Enable(); // Enable high-priority interrupts and low-priority interrupts
Interrupt_Init(); // Initialize the interrupt priorities
 
NHD_Begin(16, 2);
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
// LUX_SetGain(TSL2561_GAIN_0X); // set no gain (for bright situtations)
LUX_Set_Gain(TSL2561_GAIN_16X); // set 16x gain (for dim situations)
 
// Changing the integration time gives you a longer time over which to sense light
// longer timelines are slower, but are good in very low light situtations!
// LUX_SetTiming(TSL2561_INTEGRATIONTIME_13MS); // shortest integration time (bright light)
LUX_Set_Timing(TSL2561_INTEGRATIONTIME_101MS); // medium integration time (medium light)
// LUX_SetTiming(TSL2561_INTEGRATIONTIME_402MS); // longest integration time (dim light)
 
while (1) {
lum = LUX_Get_Full_Luminosity();
ir = lum >> 16;
full = lum & 0xFFFF;
NHD_Set_Cursor(0, 0);
NHD_Write_String("I: %d ", ir);
NHD_Write_String("V: %d ", full - ir);
NHD_Set_Cursor(0, 1);
NHD_Write_String("Lux: %ld ", LUX_Calculate_Lux(full, ir));
 
Delay10KTCYx(100);
}
}
#endif
/PIC Projects/PIC_27J13/nfc_PN532.c
0,0 → 1,481
#include "defines.h"
#include "nfc_PN532.h"
#include "i2c.h"
#include <string.h>
#include <delays.h>
 
static NFC_DATA nfc_data;
static NFC_DATA *nfc_data_p = &nfc_data;
 
// Const value arrays for comparison use
static char pn532response_firmwarevers[] = {0x01, 0x00, 0x00, 0xFF, 0x06, 0xFA, 0xD5, 0x03};
static char pn532ack[] = {0x01, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00};
 
void NFC_Init() {
NFC_IRQ_TRIS = 1; // IRQ Pin is RC5
 
/* NFC reset is disabled due to lack of pins */
// NFC_RESET_TRIS = 0; // Reset Pin is RC2
//
// // Reset the PN532
// NFC_RESET_LAT = 1;
// NFC_RESET_LAT = 0;
// Delay10TCYx(1);
// NFC_RESET_LAT = 1;
}
 
// Configures the SAM (Secure Access Module)
unsigned char NFC_SAMConfig() {
nfc_data_p->packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
nfc_data_p->packetbuffer[1] = 0x01; // Normal mode
nfc_data_p->packetbuffer[2] = 0x14; // Timeout 50ms * 20 = 1s
nfc_data_p->packetbuffer[3] = 0x01; // Use IRQ pin
 
if (!NFC_Send_Command_Check_Ack(nfc_data_p->packetbuffer, 4))
return 0;
 
NFC_I2C_Read_Data(nfc_data_p->packetbuffer, 8);
 
return (nfc_data_p->packetbuffer[7] == 0x15);
}
 
// Checks the firmware version of the PN5xx chip
NFC_FIRMWARE_VERSION NFC_Get_Firmware_Version(void) {
NFC_FIRMWARE_VERSION response = {0, 0, 0, 0};
 
// Create and send command
nfc_data_p->packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
 
if (!NFC_Send_Command_Check_Ack(nfc_data_p->packetbuffer, 1))
return response;
 
// Read back data from the PN532
NFC_I2C_Read_Data(nfc_data_p->packetbuffer, 12);
 
// Compare and check returned values
if (strncmp((char *) nfc_data_p->packetbuffer, (char *) pn532response_firmwarevers, 8) != 0)
return response;
 
// Save and return info
response.IC = nfc_data_p->packetbuffer[8];
response.Ver = nfc_data_p->packetbuffer[9];
response.Rev = nfc_data_p->packetbuffer[10];
response.Support = nfc_data_p->packetbuffer[11];
 
return response;
}
 
// Sends a command and waits a specified period for the ACK
unsigned char NFC_Send_Command_Check_Ack(unsigned char *cmd, unsigned char cmdlen) {
unsigned int timer = 0;
 
// Write the command
NFC_I2C_Write_Cmd(cmd, cmdlen);
 
// Wait for chip to be ready
while (NFC_I2C_Read_Status() != PN532_I2C_READY) {
if (PN532_TIMEOUT != 0) {
timer += 1;
if (timer > PN532_TIMEOUT)
return 0;
}
Delay10TCYx(1);
}
 
// Check ACK
if (!NFC_I2C_Read_ACK()) {
return 0;
}
 
return 1;
}
 
// Passive polling, waits for an ISO14443A target to enter the field
unsigned char NFC_Read_Passive_Target_ID(NFC_TargetDataMiFare *cardData) {
nfc_data_p->packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
nfc_data_p->packetbuffer[1] = 2; // Max 2 cards at once
nfc_data_p->packetbuffer[2] = PN532_MIFARE_ISO14443A; // Mifare only
 
if (!NFC_Send_Command_Check_Ack(nfc_data_p->packetbuffer, 3))
return 0;
 
// Wait for IRQ line
while (NFC_I2C_Read_Status() != PN532_I2C_READY);
 
NFC_I2C_Read_Data(nfc_data_p->packetbuffer, 35);
 
/* InListPassiveTarget response should be in the following format:
* Byte Description
* ---------- ------------------
* b0 Data ACK
* b1..7 Frame header and preamble
* b8 Tags found
* b9..N NFC_TargetDataMiFare[2]
* bN+1..N+2 Checksum + postamble
*/
 
// Check # of tags found
if (!nfc_data_p->packetbuffer[8])
return 0;
// Save data from first card
if (nfc_data_p->packetbuffer[13] == 4) {
memcpy((char *)&cardData[0], (const char *)&nfc_data_p->packetbuffer[9], 9);
} else {
memcpy((char *)&cardData[0], (const char *)&nfc_data_p->packetbuffer[9], 12);
}
 
// Save data from second card
if (nfc_data_p->packetbuffer[8] == 2) {
// Offset will vary depending on length of first card
if (nfc_data_p->packetbuffer[13] == 4) {
if (nfc_data_p->packetbuffer[22] == 4) {
memcpy((char *)&cardData[1], (const char *)&nfc_data_p->packetbuffer[18], 9);
} else {
memcpy((char *)&cardData[1], (const char *)&nfc_data_p->packetbuffer[18], 12);
}
} else { // Length of first UID is 7
if (nfc_data_p->packetbuffer[25] == 4) {
memcpy((char *)&cardData[1], (const char *)&nfc_data_p->packetbuffer[21], 9);
} else {
memcpy((char *)&cardData[1], (const char *)&nfc_data_p->packetbuffer[21], 12);
}
}
}
// Return the number of cards detected
return nfc_data_p->packetbuffer[8];
}
 
// Active polling, returns number of cards in the field
unsigned char NFC_Poll_Targets(unsigned char number, unsigned char period, NFC_TargetDataMiFare *cardData) {
nfc_data_p->packetbuffer[0] = PN532_COMMAND_INAUTOPOLL;
nfc_data_p->packetbuffer[1] = number; // Number of polling
nfc_data_p->packetbuffer[2] = period; // Polling period in units of 150ms
nfc_data_p->packetbuffer[3] = 0x10; // Check for Mifare cards only
 
if (!NFC_Send_Command_Check_Ack(nfc_data_p->packetbuffer, 4))
return 0;
 
// Wait for IRQ line
while (NFC_I2C_Read_Status() != PN532_I2C_READY);
 
NFC_I2C_Read_Data(nfc_data_p->packetbuffer, 37);
 
/* InAutoPoll response should be in the following format:
* Byte Description
* ---------- ------------------
* b0 Data ACK
* b1..7 Frame header and preamble
* b6 Tags found
* b7 Polled target type (should be 0x10 Mifare)
* b8 TargetData length (1/2)
* b9..N NFC_TargetDataMiFare[1/2]
* bN+1..N+2 Checksum + postamble
*/
 
// Check # of tags found
if (!nfc_data_p->packetbuffer[8])
return 0;
 
// Save data from first card
if (nfc_data_p->packetbuffer[15] == 4) {
memcpy((char *)&cardData[0], (const char *)&nfc_data_p->packetbuffer[11], 9);
} else {
memcpy((char *)&cardData[0], (const char *)&nfc_data_p->packetbuffer[11], 12);
}
 
// Save data from second card
if (nfc_data_p->packetbuffer[8] == 2) {
// Offset will vary depending on length of first card
if (nfc_data_p->packetbuffer[15] == 4) {
if (nfc_data_p->packetbuffer[26] == 4) {
memcpy((char *)&cardData[1], (const char *)&nfc_data_p->packetbuffer[22], 9);
} else {
memcpy((char *)&cardData[1], (const char *)&nfc_data_p->packetbuffer[22], 12);
}
} else {
if (nfc_data_p->packetbuffer[29] == 4) {
memcpy((char *)&cardData[1], (const char *)&nfc_data_p->packetbuffer[25], 9);
} else {
memcpy((char *)&cardData[1], (const char *)&nfc_data_p->packetbuffer[25], 12);
}
}
}
 
// Return the number of cards detected
return nfc_data_p->packetbuffer[8];
}
 
// Indicates whether the specified block number is the first block
// in the sector (block 0 relative to the current sector)
unsigned char NFC_mifareclassic_IsFirstBlock(unsigned long uiBlock) {
// Test if we are in the small or big sectors
if (uiBlock < 128)
return ((uiBlock) % 4 == 0);
else
return ((uiBlock) % 16 == 0);
}
 
// Indicates whether the specified block number is the sector trailer
unsigned char NFC_mifareclassic_IsTrailerBlock(unsigned long uiBlock) {
// Test if we are in the small or big sectors
if (uiBlock < 128)
return ((uiBlock + 1) % 4 == 0);
else
return ((uiBlock + 1) % 16 == 0);
}
 
// Tries to authenticate a block of memory on a MIFARE card using the INDATAEXCHANGE command
unsigned char NFC_mifareclassic_AuthenticateBlock(unsigned char *uid, unsigned char uidLen, unsigned long blockNumber, unsigned char keyNumber, unsigned char *keyData) {
// See section 7.3.8 of the PN532 User Manual
// blockNumber = The block number to authenticate. (0..63 for 1KB cards, and 0..255 for 4KB cards)\
// keyNumber = Which key type to use during authentication (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B)
// keyData = Pointer to a byte array containing the 6 byte key value
 
unsigned char i;
 
// Assemble frame data
nfc_data_p->packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */
nfc_data_p->packetbuffer[1] = 1; /* Max card numbers */
nfc_data_p->packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_A : MIFARE_CMD_AUTH_B;
nfc_data_p->packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
for (i = 0; i < 6; i++) {
nfc_data_p->packetbuffer[4 + i] = keyData[i];
}
for (i = 0; i < uidLen; i++) {
nfc_data_p->packetbuffer[10 + i] = uid[i];
}
 
// Send frame and check for ACK
if (!NFC_Send_Command_Check_Ack(nfc_data_p->packetbuffer, 10 + uidLen))
return 0;
 
// Read response from PN532
NFC_I2C_Read_Data(nfc_data_p->packetbuffer, 12);
 
return 1;
}
 
// Tries to read an entire 16-byte data block at the specified block address
unsigned char NFC_mifareclassic_ReadDataBlock(unsigned char blockNumber, unsigned char *data) {
unsigned char i;
 
// Assemble frame data
nfc_data_p->packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
nfc_data_p->packetbuffer[1] = 1; /* Card number */
nfc_data_p->packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
nfc_data_p->packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
 
// Send frame and check for ACK
if (!NFC_Send_Command_Check_Ack(nfc_data_p->packetbuffer, 4))
return 0;
 
// Read reponse
NFC_I2C_Read_Data(nfc_data_p->packetbuffer, 26);
 
// If byte 9 isnt 0x00 we probably have and error
if (nfc_data_p->packetbuffer[8] != 0x00) {
return 0;
}
 
// Copy the 16 data bytes into the data buffer
// Block contents starts at byte 10 of a valid response
for (i = 0; i < 16; i++) {
data[i] = nfc_data_p->packetbuffer[9 + i];
}
 
return 1;
}
 
// Tries to write an entire 16-byte data block at the specified block address
unsigned char NFC_mifareclassic_WriteDataBlock(unsigned char blockNumber, unsigned char *data) {
unsigned char i;
 
// Assemble frame data
nfc_data_p->packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
nfc_data_p->packetbuffer[1] = 1; /* Card number */
nfc_data_p->packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
nfc_data_p->packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
for (i = 0; i < 16; i++) { /* Data Payload */
nfc_data_p->packetbuffer[4 + i] = data[i];
}
 
// Send frame and check for ACK
if (!NFC_Send_Command_Check_Ack(nfc_data_p->packetbuffer, 20))
return 0;
 
// Read response
NFC_I2C_Read_Data(nfc_data_p->packetbuffer, 26);
 
return 1;
}
 
// Formats a Mifare Classic card to store NDEF Records
unsigned char NFC_mifareclassic_FormatNDEF(void) {
unsigned char sectorbuffer1[16] = {0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
unsigned char sectorbuffer2[16] = {0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
unsigned char sectorbuffer3[16] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77, 0x88, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 
// Write blocks 1 and 2
if (!NFC_mifareclassic_WriteDataBlock(1, sectorbuffer1))
return 0;
if (!NFC_mifareclassic_WriteDataBlock(2, sectorbuffer2))
return 0;
// Write key A and access rights
if (!NFC_mifareclassic_WriteDataBlock(3, sectorbuffer3))
return 0;
 
return 1;
}
 
// Writes an NDEF URI Record to the specified sector (1..15)
/* Note that this function assumes that the Mifare Classic card is
already formatted to work as an "NFC Forum Tag" and uses a MAD1
file system. You can use the NXP TagWriter app on Android to
properly format cards for this. */
unsigned char NFC_mifareclassic_WriteNDEFURI(unsigned char sectorNumber, unsigned char uriIdentifier, const char * url) {
// uriIdentifier = The uri identifier code (0 = none, 0x01 = "http://www.", etc.)
// url = The uri text to write (max 38 characters)
 
// Figure out how long the string is
unsigned char len = strlen(url);
 
unsigned char sectorbuffer1[16] = {0x00, 0x00, 0x03, len + 5, 0xD1, 0x01, len + 1, 0x55, uriIdentifier, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char sectorbuffer2[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char sectorbuffer3[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char sectorbuffer4[16] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 
// Make sure we're within a 1K limit for the sector number
if ((sectorNumber < 1) || (sectorNumber > 15))
return 0;
 
// Make sure the URI payload is between 1 and 38 chars
if ((len < 1) || (len > 38))
return 0;
 
if (len <= 6) {
// Unlikely we'll get a url this short, but why not ...
memcpy(sectorbuffer1 + 9, url, len);
sectorbuffer1[len + 9] = 0xFE;
} else if (len == 7) {
// 0xFE needs to be wrapped around to next block
memcpy(sectorbuffer1 + 9, url, len);
sectorbuffer2[0] = 0xFE;
} else if ((len > 7) || (len <= 22)) {
// Url fits in two blocks
memcpy(sectorbuffer1 + 9, url, 7);
memcpy(sectorbuffer2, url + 7, len - 7);
sectorbuffer2[len - 7] = 0xFE;
} else if (len == 23) {
// 0xFE needs to be wrapped around to final block
memcpy(sectorbuffer1 + 9, url, 7);
memcpy(sectorbuffer2, url + 7, len - 7);
sectorbuffer3[0] = 0xFE;
} else {
// Url fits in three blocks
memcpy(sectorbuffer1 + 9, url, 7);
memcpy(sectorbuffer2, url + 7, 16);
memcpy(sectorbuffer3, url + 23, len - 24);
sectorbuffer3[len - 22] = 0xFE;
}
 
// Now write all three blocks back to the card
if (!(NFC_mifareclassic_WriteDataBlock(sectorNumber * 4, sectorbuffer1)))
return 0;
if (!(NFC_mifareclassic_WriteDataBlock((sectorNumber * 4) + 1, sectorbuffer2)))
return 0;
if (!(NFC_mifareclassic_WriteDataBlock((sectorNumber * 4) + 2, sectorbuffer3)))
return 0;
if (!(NFC_mifareclassic_WriteDataBlock((sectorNumber * 4) + 3, sectorbuffer4)))
return 0;
 
return 1;
}
 
// Reads and checks for the ACK signal
unsigned char NFC_I2C_Read_ACK() {
unsigned char buffer[7];
 
// Check ACK
NFC_I2C_Read_Data(buffer, 6);
 
// Return if the 7 bytes matches the ACK pattern
return (strncmp((char *) buffer, (char *) pn532ack, 7) == 0);
}
 
// Checks the IRQ pin to know if the PN532 is ready
unsigned char NFC_I2C_Read_Status() {
if (NFC_IRQ_PORT == 1) {
return PN532_I2C_BUSY;
} else {
return PN532_I2C_READY;
}
}
 
// Reads n bytes of data from the PN532 via I2C
void NFC_I2C_Read_Data(unsigned char *buffer, unsigned char length) {
unsigned char result;
 
// Wait for IRQ to go low
while (NFC_I2C_Read_Status() != PN532_I2C_READY);
 
// Read bytes from PN532 into buffer
I2C_Master_Recv(PN532_I2C_ADDRESS, length + 2);
result = I2C_Get_Status();
while (!result) {
result = I2C_Get_Status();
}
I2C_Read_Buffer((char *) buffer);
 
/* Remaining packet byte layout is as follows:
Byte Description
----- ----------------------
* 0 Data ready ACK
* 1 Preamble (0x00)
* 2-3 Start code (0x00,0xFF)
* 4 Length (TFI to N)
* 5 Length Checksum (Length + LCS = 0x00)
* 6 TFI (Frame identifier)
* 0xD4 - Host to PN532
* 0xD5 - PN532 to Host
* 7-N Data (Length - 1 bytes)
* N+1 Data checksum (TFI + Data~N + DCS = 0x00)
* N+2 Postamble (0x00) */
}
 
// Writes a command to the PN532, automatically inserting the preamble and required frame details (checksum, len, etc.)
void NFC_I2C_Write_Cmd(unsigned char* cmd, unsigned char cmdlen) {
int i;
unsigned char checksum;
unsigned char buffer[PN532_PACKBUFFSIZ + 8];
unsigned char buffer_ind = 6;
cmdlen++;
 
checksum = PN532_PREAMBLE + PN532_PREAMBLE + PN532_STARTCODE2 + PN532_HOSTTOPN532;
 
// Fill out required frame fields
buffer[0] = PN532_PREAMBLE;
buffer[1] = PN532_PREAMBLE;
buffer[2] = PN532_STARTCODE2;
buffer[3] = cmdlen;
buffer[4] = ~cmdlen + 1;
buffer[5] = PN532_HOSTTOPN532;
 
 
// Copy cmd to be sent
for (i = 0; i < cmdlen - 1; i++) {
checksum += cmd[i];
buffer[buffer_ind] = cmd[i];
buffer_ind++;
}
 
buffer[buffer_ind] = ~checksum;
buffer_ind++;
buffer[buffer_ind] = PN532_POSTAMBLE;
buffer_ind++;
 
I2C_Master_Send(PN532_I2C_ADDRESS, buffer_ind, buffer);
}
/PIC Projects/PIC_27J13/nfc_PN532.h
0,0 → 1,173
#ifndef NFC_H
#define NFC_H
 
/* PN532 NFC Reader from Adafruit */
 
#define PN532_PREAMBLE (0x00)
#define PN532_STARTCODE1 (0x00)
#define PN532_STARTCODE2 (0xFF)
#define PN532_POSTAMBLE (0x00)
 
#define PN532_HOSTTOPN532 (0xD4)
 
// PN532 Commands
#define PN532_COMMAND_DIAGNOSE (0x00)
#define PN532_COMMAND_GETFIRMWAREVERSION (0x02)
#define PN532_COMMAND_GETGENERALSTATUS (0x04)
#define PN532_COMMAND_READREGISTER (0x06)
#define PN532_COMMAND_WRITEREGISTER (0x08)
#define PN532_COMMAND_READGPIO (0x0C)
#define PN532_COMMAND_WRITEGPIO (0x0E)
#define PN532_COMMAND_SETSERIALBAUDRATE (0x10)
#define PN532_COMMAND_SETPARAMETERS (0x12)
#define PN532_COMMAND_SAMCONFIGURATION (0x14)
#define PN532_COMMAND_POWERDOWN (0x16)
#define PN532_COMMAND_RFCONFIGURATION (0x32)
#define PN532_COMMAND_RFREGULATIONTEST (0x58)
#define PN532_COMMAND_INJUMPFORDEP (0x56)
#define PN532_COMMAND_INJUMPFORPSL (0x46)
#define PN532_COMMAND_INLISTPASSIVETARGET (0x4A)
#define PN532_COMMAND_INATR (0x50)
#define PN532_COMMAND_INPSL (0x4E)
#define PN532_COMMAND_INDATAEXCHANGE (0x40)
#define PN532_COMMAND_INCOMMUNICATETHRU (0x42)
#define PN532_COMMAND_INDESELECT (0x44)
#define PN532_COMMAND_INRELEASE (0x52)
#define PN532_COMMAND_INSELECT (0x54)
#define PN532_COMMAND_INAUTOPOLL (0x60)
#define PN532_COMMAND_TGINITASTARGET (0x8C)
#define PN532_COMMAND_TGSETGENERALBYTES (0x92)
#define PN532_COMMAND_TGGETDATA (0x86)
#define PN532_COMMAND_TGSETDATA (0x8E)
#define PN532_COMMAND_TGSETMETADATA (0x94)
#define PN532_COMMAND_TGGETINITIATORCOMMAND (0x88)
#define PN532_COMMAND_TGRESPONSETOINITIATOR (0x90)
#define PN532_COMMAND_TGGETTARGETSTATUS (0x8A)
 
#define PN532_WAKEUP (0x55)
 
#define PN532_SPI_STATREAD (0x02)
#define PN532_SPI_DATAWRITE (0x01)
#define PN532_SPI_DATAREAD (0x03)
#define PN532_SPI_READY (0x01)
 
#define PN532_I2C_ADDRESS (0x48 >> 1)
#define PN532_I2C_READBIT (0x01)
#define PN532_I2C_BUSY (0x00)
#define PN532_I2C_READY (0x01)
#define PN532_I2C_READYTIMEOUT (20)
 
#define PN532_MIFARE_ISO14443A (0x00)
 
// Mifare Commands
#define MIFARE_CMD_AUTH_A (0x60)
#define MIFARE_CMD_AUTH_B (0x61)
#define MIFARE_CMD_READ (0x30)
#define MIFARE_CMD_WRITE (0xA0)
#define MIFARE_CMD_TRANSFER (0xB0)
#define MIFARE_CMD_DECREMENT (0xC0)
#define MIFARE_CMD_INCREMENT (0xC1)
#define MIFARE_CMD_STORE (0xC2)
 
// Prefixes for NDEF Records (to identify record type)
#define NDEF_URIPREFIX_NONE (0x00)
#define NDEF_URIPREFIX_HTTP_WWWDOT (0x01)
#define NDEF_URIPREFIX_HTTPS_WWWDOT (0x02)
#define NDEF_URIPREFIX_HTTP (0x03)
#define NDEF_URIPREFIX_HTTPS (0x04)
#define NDEF_URIPREFIX_TEL (0x05)
#define NDEF_URIPREFIX_MAILTO (0x06)
#define NDEF_URIPREFIX_FTP_ANONAT (0x07)
#define NDEF_URIPREFIX_FTP_FTPDOT (0x08)
#define NDEF_URIPREFIX_FTPS (0x09)
#define NDEF_URIPREFIX_SFTP (0x0A)
#define NDEF_URIPREFIX_SMB (0x0B)
#define NDEF_URIPREFIX_NFS (0x0C)
#define NDEF_URIPREFIX_FTP (0x0D)
#define NDEF_URIPREFIX_DAV (0x0E)
#define NDEF_URIPREFIX_NEWS (0x0F)
#define NDEF_URIPREFIX_TELNET (0x10)
#define NDEF_URIPREFIX_IMAP (0x11)
#define NDEF_URIPREFIX_RTSP (0x12)
#define NDEF_URIPREFIX_URN (0x13)
#define NDEF_URIPREFIX_POP (0x14)
#define NDEF_URIPREFIX_SIP (0x15)
#define NDEF_URIPREFIX_SIPS (0x16)
#define NDEF_URIPREFIX_TFTP (0x17)
#define NDEF_URIPREFIX_BTSPP (0x18)
#define NDEF_URIPREFIX_BTL2CAP (0x19)
#define NDEF_URIPREFIX_BTGOEP (0x1A)
#define NDEF_URIPREFIX_TCPOBEX (0x1B)
#define NDEF_URIPREFIX_IRDAOBEX (0x1C)
#define NDEF_URIPREFIX_FILE (0x1D)
#define NDEF_URIPREFIX_URN_EPC_ID (0x1E)
#define NDEF_URIPREFIX_URN_EPC_TAG (0x1F)
#define NDEF_URIPREFIX_URN_EPC_PAT (0x20)
#define NDEF_URIPREFIX_URN_EPC_RAW (0x21)
#define NDEF_URIPREFIX_URN_EPC (0x22)
#define NDEF_URIPREFIX_URN_NFC (0x23)
 
#define PN532_GPIO_VALIDATIONBIT (0x80)
#define PN532_GPIO_P30 (0)
#define PN532_GPIO_P31 (1)
#define PN532_GPIO_P32 (2)
#define PN532_GPIO_P33 (3)
#define PN532_GPIO_P34 (4)
#define PN532_GPIO_P35 (5)
 
#define PN532_PACKBUFFSIZ 64
#define PN532_TIMEOUT 1000
 
typedef struct {
unsigned char IC;
unsigned char Ver;
unsigned char Rev;
unsigned char Support;
} NFC_FIRMWARE_VERSION;
 
typedef struct {
unsigned char TG;
unsigned char SENS_RES[2];
unsigned char SEL_RES;
unsigned char NFCID_LEN;
unsigned char NFCID[7];
} NFC_TargetDataMiFare;
// Size can be 9 or 12 bytes
 
typedef struct __NFC_DATA {
unsigned char packetbuffer[PN532_PACKBUFFSIZ];
} NFC_DATA;
 
void NFC_Init(void);
 
// Generic PN532 functions
unsigned char NFC_SAMConfig(void);
NFC_FIRMWARE_VERSION NFC_Get_Firmware_Version(void);
unsigned char NFC_Send_Command_Check_Ack(unsigned char *cmd, unsigned char cmdlen);
//unsigned char NFC_writeGPIO(unsigned char pinstate);
//unsigned char NFC_readGPIO(void);
 
// ISO14443A functions
unsigned char NFC_Read_Passive_Target_ID(NFC_TargetDataMiFare *uidData);
unsigned char NFC_Poll_Targets(unsigned char number, unsigned char period, NFC_TargetDataMiFare *uidData);
 
// Mifare Classic functions
unsigned char NFC_mifareclassic_IsFirstBlock(unsigned long uiBlock);
unsigned char NFC_mifareclassic_IsTrailerBlock(unsigned long uiBlock);
unsigned char NFC_mifareclassic_AuthenticateBlock(unsigned char *uid, unsigned char uidLen, unsigned long blockNumber, unsigned char keyNumber, unsigned char *keyData);
unsigned char NFC_mifareclassic_ReadDataBlock(unsigned char blockNumber, unsigned char *data);
unsigned char NFC_mifareclassic_WriteDataBlock(unsigned char blockNumber, unsigned char *data);
unsigned char NFC_mifareclassic_FormatNDEF(void);
unsigned char NFC_mifareclassic_WriteNDEFURI(unsigned char sectorNumber, unsigned char uriIdentifier, const char * url);
 
// Mifare Ultralight functions
//unsigned char NFC_mifareultralight_ReadPage(unsigned char page, unsigned char * buffer);
 
// Low level SPI functions
unsigned char NFC_I2C_Read_ACK(void);
unsigned char NFC_I2C_Read_Status(void);
void NFC_I2C_Read_Data(unsigned char *buffer, unsigned char length);
void NFC_I2C_Write_Cmd(unsigned char *cmd, unsigned char cmdlen);
 
#endif
 
/PIC Projects/PIC_27J13/xbee.c
0,0 → 1,237
#include "defines.h"
#include "xbee.h"
#include <string.h>
 
#pragma udata XBEE_BUFFER
static XBEE_DATA xbee_data;
#pragma udata
static XBEE_DATA *xbee_data_p = &xbee_data;
static void *xbee_data_frame;
static void *xbee_frame;
 
/* Initialize variables used by this library */
void XBee_Init() {
XBEE_CTS_TRIS = 1; // RB0 is CTS, set by XBee chip
XBEE_RTS_TRIS = 0; // RB1 is RTS, set by PIC
 
XBEE_CTS_LAT = 0; // Pin set high to signal stop sending data to XBee
XBEE_RTS_LAT = 0; // Pin set high to indicate stop sending data to PIC
 
xbee_data_p->dataind = 0;
xbee_data_p->checksum_sum = 0;
xbee_data_p->frame_rdy = 0;
xbee_data_p->escape_flag = 0;
xbee_data_p->read_state = XBEE_STATE_READ_START;
 
// memset(&xbee_data, 0, 32);
// Grab a pointer to where the unique frame array starts
xbee_data_frame = &(xbee_data_p->rcv_frame.FRAME);
xbee_frame = &(xbee_data_p->rcv_frame);
}
 
/* Here we handle the serial input from the UART interrupt */
void XBee_Serial_In(unsigned char c) {
// For some reason writing the length straight to xbee_data doesnt seem to work
// so we work around it by pointing to the length bytes directly
XBEE_ADDRESS_16 *length = xbee_frame + 1;
#ifdef XBEE_USE_ESCAPE_CHAR
if (c == XBEE_ESCAPE_CHAR) {
// Next byte needs is an escaped char
xbee_data_p->escape_flag = 1;
return;
}
 
if (xbee_data_p->escape_flag) {
// XOR byte with 0x20 to get escaped char
c ^= XBEE_ESCAPE_VAL;
xbee_data_p->escape_flag = 0;
}
#endif
// Reset on start bit and start saving data
if (c == XBEE_START_DELIMITER) {
// On detect start delimiter, clear out initial array
xbee_data_p->dataind = 0;
xbee_data_p->checksum_sum = 0;
xbee_data_p->frame_rdy = 0;
xbee_data_p->read_state = XBEE_STATE_READ_LENGTH_HIGH;
*((unsigned char *)xbee_frame) = XBEE_START_DELIMITER;
} else {
switch (xbee_data_p->read_state) {
case XBEE_STATE_READ_START:
// Do nothing and wait till start bit is read
break;
case XBEE_STATE_READ_LENGTH_HIGH:
// Read length (MSB)
length->INT_16.char_value[1] = c;
xbee_data_p->read_state = XBEE_STATE_READ_LENGTH_LOW;
break;
case XBEE_STATE_READ_LENGTH_LOW:
// Read length (LSB)
length->INT_16.char_value[0] = c;
xbee_data_p->read_state = XBEE_STATE_READ_FRAME_DATA;
break;
case XBEE_STATE_READ_FRAME_DATA:
// Read unique frame data
if (xbee_data_p->dataind < xbee_data_p->rcv_frame.length.INT_16.int_value) {
*((char*) xbee_data_frame + xbee_data_p->dataind) = c;
xbee_data_p->checksum_sum += c;
xbee_data_p->dataind++;
}
// If total length is read, the next byte is the expected checksum
if (xbee_data_p->dataind == xbee_data_p->rcv_frame.length.INT_16.int_value) {
xbee_data_p->read_state = XBEE_STATE_READ_CHECKSUM;
}
break;
case XBEE_STATE_READ_CHECKSUM:
// Calculate and compare checksum
if (0xFF - xbee_data_p->checksum_sum == c) {
// Frame was recieved successfully
xbee_data_p->frame_rdy = 1;
// XBee_Process_Received_Frame();
} else {
// If checksum does not match, drop frame
DBG_PRINT_XBEE("XBEE: checksum mismatch\r\n");
}
xbee_data_p->read_state = XBEE_STATE_READ_START;
break;
}
}
}
 
/* This processes the frame data within the interrupt. Dont use this. */
void XBee_Process_Received_Frame() {
// DBG_PRINT_XBEE("Length: %d\r\n", xbee_data_p->rcv_frame.length.INT_16.int_value);
// Here we process the received frame depending on the frame type
switch (*((unsigned char *) xbee_data_frame)) {
case XBEE_RX_AT_COMMAND_RESPONSE:
DBG_PRINT_XBEE("XBEE: parsing recieved AT command response frame\r\n");
break;
case XBEE_RX_DATA_PACKET:
DBG_PRINT_XBEE("XBEE: parsing recieved data frame\r\n");
break;
case XBEE_RX_DATA_TX_STATUS:
DBG_PRINT_XBEE("XBEE: parsing recieved TX status frame\r\n");
break;
case XBEE_RX_IO_DATA_SAMPLE:
DBG_PRINT_XBEE("XBEE: parsing recieved IO data sample frame\r\n");
break;
case XBEE_RX_EXPLICIT_COMMAND:
DBG_PRINT_XBEE("XBEE: parsing recieved explicit command frame\r\n");
break;
case XBEE_RX_REMOTE_AT_COMMAND_RESPONSE:
DBG_PRINT_XBEE("XBEE: parsing recieved remote AT command frame\r\n");
break;
case XBEE_RX_ROUTE_RECORD:
DBG_PRINT_XBEE("XBEE: parsing recieved route record frame\r\n");
break;
case XBEE_RX_NODE_IDENTIFICATION:
DBG_PRINT_XBEE("XBEE: parsing recieved node identification frame\r\n");
break;
case XBEE_RX_FRAME_MODEM_STATUS:
DBG_PRINT_XBEE("XBEE: parsing recieved modem status frame\r\n");
break;
default:
DBG_PRINT_XBEE("XBEE: (ERROR) unrecognized frame type\r\n");
}
}
 
unsigned int XBee_Get_Received_Frame(unsigned char *frame) {
if (!xbee_data_p->frame_rdy) {
return 0;
} else {
memcpy(frame, xbee_data_frame, xbee_data_p->rcv_frame.length.INT_16.int_value);
xbee_data_p->frame_rdy = 0; // Reset frame ready status
return xbee_data_p->rcv_frame.length.INT_16.int_value;
}
}
 
void XBee_Process_Transmit_Frame(unsigned char *data, unsigned char length) {
#ifdef XBEE_USE_ESCAPE_CHAR
unsigned int i = 0;
unsigned char chksum = 0;
 
// Write the start bit and length
UART1_WriteC(XBEE_START_DELIMITER);
UART1_WriteC(0);
UART1_WriteC(length);
 
// Write the frame data
for (i = 0; i < length; i++) {
chksum += data[i];
if (data[i] == XBEE_START_DELIMITER || \
data[i] == XBEE_ESCAPE_CHAR || \
data[i] == XBEE_XON || \
data[i] == XBEE_XOFF) {
UART1_WriteC(XBEE_ESCAPE_CHAR);
UART1_WriteC(data[i] ^ XBEE_ESCAPE_VAL);
} else {
UART1_WriteC(data[i]);
}
}
// Write the checksum
if (chksum == XBEE_START_DELIMITER || \
chksum == XBEE_ESCAPE_CHAR || \
chksum == XBEE_XON || \
chksum == XBEE_XOFF) {
UART1_WriteC(XBEE_ESCAPE_CHAR);
UART1_WriteC(chksum ^ XBEE_ESCAPE_VAL);
} else {
UART1_WriteC(0xFF - chksum);
}
#else
unsigned int i = 0;
unsigned char chksum = 0;
 
UART1_WriteC(XBEE_START_DELIMITER);
UART1_WriteC(0);
UART1_WriteC(length);
for (i = 0; i < length; i++) {
chksum += data[i];
UART1_WriteC(data[i]);
}
UART1_WriteC(0xFF - chksum);
#endif
}
 
void XBee_Set_RTS(unsigned char c) {
if (c) {
XBEE_RTS_LAT = 1; // Set high to stop receiving data
} else {
XBEE_RTS_LAT = 0; // Set low to resume receiving data
}
}
 
unsigned char XBee_Read_CTS() {
unsigned char c = XBEE_CTS_PORT;
if (c) {
return 0x1; // High indicates stop sending data
} else {
return 0x0; // Low indicates ok to send data
}
}
 
void XBee_Convert_Endian_64(XBEE_ADDRESS_64 *src) {
char tmp[2];
tmp[0] = src->UPPER_32.char_value[3];
tmp[1] = src->UPPER_32.char_value[2];
src->UPPER_32.char_value[3] = src->UPPER_32.char_value[0];
src->UPPER_32.char_value[2] = src->UPPER_32.char_value[1];
src->UPPER_32.char_value[1] = tmp[1];
src->UPPER_32.char_value[0] = tmp[0];
 
tmp[0] = src->LOWER_32.char_value[3];
tmp[1] = src->LOWER_32.char_value[2];
src->LOWER_32.char_value[3] = src->LOWER_32.char_value[0];
src->LOWER_32.char_value[2] = src->LOWER_32.char_value[1];
src->LOWER_32.char_value[1] = tmp[1];
src->LOWER_32.char_value[0] = tmp[0];
}
 
void XBee_Convert_Endian_16(XBEE_ADDRESS_16 *src) {
char tmp;
tmp = src->INT_16.char_value[0];
src->INT_16.char_value[0] = src->INT_16.char_value[1];
src->INT_16.char_value[1] = tmp;
}
/PIC Projects/PIC_27J13/interrupts.c
0,0 → 1,204
#include "defines.h"
#include "interrupts.h"
#include "uart.h"
#include "i2c.h"
#include "spi.h"
#include "adc.h"
#include "timers.h"
 
//----------------------------------------------------------------------------
// Note: This code for processing interrupts is configured to allow for high and
// low priority interrupts. The high priority interrupt can interrupt the
// the processing of a low priority interrupt. However, only one of each type
// can be processed at the same time. It is possible to enable nesting of low
// priority interrupts, but this code is not setup for that and this nesting
// is not enabled.
 
void Interrupt_Init() {
// Peripheral interrupts can have their priority set to high or low
// Decide on the priority of the enabled peripheral interrupts (0 is low, 1 is high)
 
// High priority interrupts
IPR1bits.RC1IP = 1; // USART1 RX interrupt
IPR1bits.TX1IP = 1; // USART1 TX interrupt
// IPR3bits.RC2IP = 1; // USART2 RX interrupt
IPR1bits.SSPIP = 1; // I2C interrupt
IPR3bits.SSP2IP = 1; // MSSP2 (SPI2) interrupt
 
// Low priority interrupts
// INTCON2bits.TMR0IP = 0; // Timer0 interrupt
IPR1bits.TMR1IP = 0; // Timer1 interrupt
// IPR2bits.TMR3IP = 0; // Timer 3 interrupt
// IPR1bits.ADIP = 0; // ADC interupt
// INTCON2bits.RBIP = 0; // Port B interrupt
// INTCON3bits.INT1IP = 0; // INT1 interrupt
// Enable Port B interrupt
// INTCONbits.RBIE = 1;
// Enable interrupt for INT1
// INTCON3bits.INT1IE = 1;
}
 
void Interrupt_Enable() {
// Peripheral interrupts can have their priority set to high or low.
// Enable both high-priority interrupts and low-priority interrupts
RCONbits.IPEN = 1;
INTCONbits.GIEH = 1;
INTCONbits.GIEL = 1;
}
 
void Interrupt_Disable() {
RCONbits.IPEN = 0;
INTCONbits.GIEH = 0;
INTCONbits.GIEL = 0;
}
 
// Set up the interrupt vectors
void InterruptHandlerHigh();
void InterruptHandlerLow();
 
#pragma code InterruptVectorLow = 0x18
 
void InterruptVectorLow(void) {
_asm
goto InterruptHandlerLow //jump to interrupt routine
_endasm
}
 
#pragma code InterruptVectorHigh = 0x08
 
void InterruptVectorHigh(void) {
_asm
goto InterruptHandlerHigh //jump to interrupt routine
_endasm
}
 
//----------------------------------------------------------------------------
// High priority interrupt routine
// this parcels out interrupts to individual handlers
 
#pragma code
#pragma interrupt InterruptHandlerHigh
 
void InterruptHandlerHigh() {
// We need to check the interrupt flag of each enabled high-priority interrupt to
// see which device generated this interrupt. Then we can call the correct handler.
 
// // Check to see if we have an SPI2 interrupt
// if (PIR3bits.SSP2IF) {
// // Call the handler
// SPI2_Recv_Interrupt_Handler();
//
// // Clear the interrupt flag
// PIR3bits.SSP2IF = 0;
//
// return;
// }
 
// Check to see if we have an I2C interrupt
if (PIR1bits.SSPIF) {
// Call the handler
I2C_Interrupt_Handler();
 
// Clear the interrupt flag
PIR1bits.SSPIF = 0;
 
return;
}
// Check to see if we have an interrupt on USART1 RX
if (PIR1bits.RC1IF) {
// Call the interrupt handler
UART1_Recv_Interrupt_Handler();
 
// Clear the interrupt flag
PIR1bits.RC1IF = 0;
 
return;
}
 
#ifndef _DEBUG // Disable UART1 TX interrupt for debug mode (using printf)
// Check to see if we have an interrupt on USART1 TX
if (PIR1bits.TX1IF) {
// Call the interrupt handler
UART1_Send_Interrupt_Handler();
// Clear the interrupt flag
PIR1bits.TX1IF = 0;
 
return;
}
#endif
// // Check to see if we have an interrupt on USART2 RX
// if (PIR3bits.RC2IF) {
// DBG_PRINT_INT("INT: UART2 RX\r\n");
// // Call the interrupt handler
// uart_2_recv_interrupt_handler();
//
// // Clear the interrupt flag
// PIR3bits.RC2IF = 0;
// }
}
 
//----------------------------------------------------------------------------
// Low priority interrupt routine
// this parcels out interrupts to individual handlers
#pragma code
#pragma interruptlow InterruptHandlerLow
// This works the same way as the "High" interrupt handler
 
void InterruptHandlerLow() {
// // Check to see if we have an interrupt on INT1
// if (INTCON3bits.INT1IF) {
// DBG_PRINT_INT("INT: INT1\r\n");
// int1_interrupt_handler();
//
// INTCON3bits.INT1IF = 0;
// }
 
// // Check to see if we have an interrupt on any port B inputs <4:7>
// if (INTCONbits.RBIF) {
// DBG_PRINT_INT("INT: Port B\r\n");
// port_b_int_interrupt_handler();
//
// INTCONbits.RBIF = 0;
// }
// // Check to see if we have an interrupt on timer 0
// if (INTCONbits.TMR0IF) {
// DBG_PRINT_INT("INT: Timer 0\r\n");
// // Call the handler
// timer0_interrupt_handler();
//
// // Clear this interrupt flag
// INTCONbits.TMR0IF = 0;
// }
 
// Check to see if we have an interrupt on timer 1
if (PIR1bits.TMR1IF) {
// Call the interrupt handler
Timer1_Interrupt_Handler();
 
// Clear the interrupt flag
PIR1bits.TMR1IF = 0;
}
 
// // Check to see if we have an interrupt on timer 3
// if (PIR2bits.TMR3IF) {
// DBG_PRINT_INT("INT: Timer 3\r\n");
// timer3_interrupt_handler();
//
// PIR2bits.TMR3IF = 0;
// }
 
// // Check to see if we have an interrupt on ADC
// if (PIR1bits.ADIF) {
// // Call the interrupt handler
// ADC_Interrupt_Handler();
//
// // Clear the interrupt flag
// PIR1bits.ADIF = 0;
// }
}
 
/PIC Projects/PIC_27J13/temp_BMP085.c
0,0 → 1,190
#include "defines.h"
#include "temp_BMP085.h"
#include "i2c.h"
#include <delays.h>
#include <math.h>
 
static BMP085_DATA bmp085_data;
static BMP085_DATA *bmp085_data_p = &bmp085_data;
 
void BMP_Init() {
 
}
 
void BMP_Begin(unsigned char mode) {
if (mode > BMP085_ULTRAHIGHRES)
mode = BMP085_ULTRAHIGHRES;
bmp085_data_p->oversampling = mode;
 
if (BMP_Read8(0xD0) != 0x55) {
DBG_PRINT_BMP("Error contacting BMP085!\r\n");
return;
}
 
bmp085_data_p->ac1 = BMP_Read16(BMP085_CAL_AC1);
bmp085_data_p->ac2 = BMP_Read16(BMP085_CAL_AC2);
bmp085_data_p->ac3 = BMP_Read16(BMP085_CAL_AC3);
bmp085_data_p->ac4 = BMP_Read16(BMP085_CAL_AC4);
bmp085_data_p->ac5 = BMP_Read16(BMP085_CAL_AC5);
bmp085_data_p->ac6 = BMP_Read16(BMP085_CAL_AC6);
 
bmp085_data_p->b1 = BMP_Read16(BMP085_CAL_B1);
bmp085_data_p->b2 = BMP_Read16(BMP085_CAL_B2);
 
bmp085_data_p->mb = BMP_Read16(BMP085_CAL_MB);
bmp085_data_p->mc = BMP_Read16(BMP085_CAL_MC);
bmp085_data_p->md = BMP_Read16(BMP085_CAL_MD);
 
DBG_PRINT_BMP("AC1 = %d\r\n", bmp085_data_p->ac1);
DBG_PRINT_BMP("AC2 = %d\r\n", bmp085_data_p->ac2);
DBG_PRINT_BMP("AC3 = %d\r\n", bmp085_data_p->ac3);
DBG_PRINT_BMP("AC4 = %u\r\n", bmp085_data_p->ac4);
DBG_PRINT_BMP("AC5 = %u\r\n", bmp085_data_p->ac5);
DBG_PRINT_BMP("AC6 = %u\r\n", bmp085_data_p->ac6);
 
DBG_PRINT_BMP("B1 = %d\r\n", bmp085_data_p->b1);
DBG_PRINT_BMP("B2 = %d\r\n", bmp085_data_p->b2);
 
DBG_PRINT_BMP("MB = %d\r\n", bmp085_data_p->mb);
DBG_PRINT_BMP("MC = %d\r\n", bmp085_data_p->mc);
DBG_PRINT_BMP("MD = %d\r\n", bmp085_data_p->md);
}
 
unsigned int BMP_Read_Raw_Temperature() {
unsigned int ret;
 
BMP_Write8(BMP085_CONTROL, BMP085_READTEMPCMD);
Delay10KTCYx(255);
ret = BMP_Read16(BMP085_TEMPDATA);
DBG_PRINT_BMP("Raw Temp: %d\r\n", ret);
return ret;
}
 
unsigned long BMP_Read_Raw_Pressure() {
unsigned long ret;
 
BMP_Write8(BMP085_CONTROL, BMP085_READPRESSURECMD + (bmp085_data_p->oversampling << 6));
 
if (bmp085_data_p->oversampling == BMP085_ULTRALOWPOWER)
Delay10KTCYx(255);
else if (bmp085_data_p->oversampling == BMP085_STANDARD)
Delay10KTCYx(255);
else if (bmp085_data_p->oversampling == BMP085_HIGHRES)
Delay10KTCYx(255);
else
Delay10KTCYx(255);
 
ret = BMP_Read16(BMP085_PRESSUREDATA);
ret <<= 8;
ret |= BMP_Read8(BMP085_PRESSUREDATA+2);
ret >>= (8 - bmp085_data_p->oversampling);
 
DBG_PRINT_BMP("Raw Pressure: %ld\r\n", ret);
 
return ret;
}
 
long BMP_Read_Pressure() {
long UT, UP, B3, B5, B6, X1, X2, X3, p;
unsigned long B4, B7;
 
UT = BMP_Read_Raw_Temperature();
UP = BMP_Read_Raw_Pressure();
 
// Temperature calculations
X1 = ((UT - (long) bmp085_data_p->ac6) * (long) bmp085_data_p->ac5) >> 15;
X2 = ((long) bmp085_data_p->mc << 11) - (X1 + bmp085_data_p->md) / 2; // round up
X2 /= (X1 + bmp085_data_p->md);
B5 = X1 + X2;
 
// Pressure calcs
B6 = B5 - 4000;
X1 = ((long) bmp085_data_p->b2 * ((B6 * B6) >> 12)) >> 11;
X2 = ((long) bmp085_data_p->ac2 * B6) >> 11;
X3 = X1 + X2;
B3 = ((((long) bmp085_data_p->ac1 * 4 + X3) << bmp085_data_p->oversampling) + 2) / 4;
 
X1 = ((long) bmp085_data_p->ac3 * B6) >> 13;
X2 = ((long) bmp085_data_p->b1 * ((B6 * B6) >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
B4 = ((unsigned long) bmp085_data_p->ac4 * (unsigned long) (X3 + 32768)) >> 15;
B7 = ((unsigned long) UP - B3) * (unsigned long) (50000UL >> bmp085_data_p->oversampling);
 
if (B7 < 0x80000000) {
p = (B7 * 2) / B4;
} else {
p = (B7 / B4) * 2;
}
X1 = (p >> 8) * (p >> 8);
X1 = (X1 * 3038) >> 16;
X2 = (-7357 * p) >> 16;
 
p = p + ((X1 + X2 + (long)3791)>>4);
 
return p;
}
 
float BMP_Read_Temperature() {
long UT, X1, X2, B5;
float temp;
 
UT = BMP_Read_Raw_Temperature();
 
X1 = ((UT - (long) bmp085_data_p->ac6) * (long) bmp085_data_p->ac5) >> 15;
X2 = ((long) bmp085_data_p->mc << 11) / (X1 + (long) bmp085_data_p->md);
B5 = X1 + X2;
temp = (B5 + 8) >> 4;
temp /= 10;
 
return temp;
}
 
float BMP_Read_Altitude(float seaLevelPressure) {
float altitude;
float pressure = BMP_Read_Pressure();
altitude = 44330 * (1.0 - pow(pressure /seaLevelPressure,0.1903));
return altitude;
}
 
unsigned char BMP_Read8(unsigned char a) {
unsigned char buffer[6], result, length, ret = 0;
I2C_Master_Restart(BMP085_I2CADDR, a, 1);
do {
result = I2C_Get_Status();
} while (!result);
length = I2C_Read_Buffer((char *)buffer);
ret = buffer[0];
 
return ret;
}
 
unsigned int BMP_Read16(unsigned char a) {
unsigned char buffer[6], result, length;
unsigned int ret;
 
I2C_Master_Restart(BMP085_I2CADDR, a, 2);
do {
result = I2C_Get_Status();
} while (!result);
length = I2C_Read_Buffer((char *)buffer);
ret = buffer[0];
ret <<= 8;
ret |= buffer[1];
 
return ret;
}
 
void BMP_Write8(unsigned char a, unsigned char d) {
unsigned char buffer[2], result;
buffer[0] = a;
buffer[1] = d;
 
I2C_Master_Send(BMP085_I2CADDR, 2, buffer);
do {
result = I2C_Get_Status();
} while (!result);
}
/PIC Projects/PIC_27J13/temp_BMP085.h
0,0 → 1,47
#ifndef TEMP_BMP085_H
#define TEMP_BMP085_H
 
#define BMP085_I2CADDR 0x77
 
#define BMP085_ULTRALOWPOWER 0
#define BMP085_STANDARD 1
#define BMP085_HIGHRES 2
#define BMP085_ULTRAHIGHRES 3
#define BMP085_CAL_AC1 0xAA // R Calibration data (16 bits)
#define BMP085_CAL_AC2 0xAC // R Calibration data (16 bits)
#define BMP085_CAL_AC3 0xAE // R Calibration data (16 bits)
#define BMP085_CAL_AC4 0xB0 // R Calibration data (16 bits)
#define BMP085_CAL_AC5 0xB2 // R Calibration data (16 bits)
#define BMP085_CAL_AC6 0xB4 // R Calibration data (16 bits)
#define BMP085_CAL_B1 0xB6 // R Calibration data (16 bits)
#define BMP085_CAL_B2 0xB8 // R Calibration data (16 bits)
#define BMP085_CAL_MB 0xBA // R Calibration data (16 bits)
#define BMP085_CAL_MC 0xBC // R Calibration data (16 bits)
#define BMP085_CAL_MD 0xBE // R Calibration data (16 bits)
 
#define BMP085_CONTROL 0xF4
#define BMP085_TEMPDATA 0xF6
#define BMP085_PRESSUREDATA 0xF6
#define BMP085_READTEMPCMD 0x2E
#define BMP085_READPRESSURECMD 0x34
 
typedef struct __BMP085_DATA {
int ac1, ac2, ac3, b1, b2, mb, mc, md;
unsigned int ac4, ac5, ac6;
unsigned char oversampling;
} BMP085_DATA;
 
void BMP_Init(void);
void BMP_Begin(unsigned char mode);
unsigned int BMP_Read_Raw_Temperature(void);
unsigned long BMP_Read_Raw_Pressure(void);
float BMP_Read_Temperature(void);
long BMP_Read_Pressure(void);
float BMP_Read_Altitude(float seaLevelPressure);
 
unsigned char BMP_Read8(unsigned char a);
unsigned int BMP_Read16(unsigned char a);
void BMP_Write8(unsigned char a, unsigned char d);
 
#endif /* TEMP_BMP085_H */
 
/PIC Projects/PIC_27J13/uart.c
0,0 → 1,244
#include "defines.h"
#include "uart.h"
#include "xbee.h"
#include <string.h>
#include <stdio.h>
 
#pragma udata UART1_BUFFER
static UART_DATA uart_1_data;
#pragma udata
static UART_DATA *uart_1_data_p = &uart_1_data;
 
void UART1_Init() {
// Configure the hardware USART device
// UART1 TX RC6
// UART1 RX RC7
 
UART1_TX_TRIS = 0; // Tx pin set to output
UART1_RX_TRIS = 1; // Rx pin set to input
 
BAUDCON1bits.BRG16 = 0; // 8-bit baud rate generator
SPBRG1 = 25; // Set UART speed to 115200 baud
TXSTA1bits.BRGH = 1; // High speed mode
TXSTA1bits.SYNC = 0; // Async mode
RCSTA1bits.SPEN = 1; // Serial port enable
TXSTA1bits.TX9 = 0; // 8 bit transmission
RCSTA1bits.RX9 = 0; // 8 bit reception
RCSTA1bits.CREN = 1; // Continuous receive mode
 
#ifdef _DEBUG // In debug mode we want to have TXEN constantly enabled
TXSTA1bits.TXEN = 1; // TX is always enabled
PIE1bits.TX1IE = 0; // Disable TX interrupt
#else
TXSTA1bits.TXEN = 0; // Enable transmission
PIE1bits.TX1IE = 1; // Enable TX interrupt
#endif
 
PIE1bits.RC1IE = 1; // Enable RX interrupt
 
// Initialize the buffer that holds UART messages
uart_1_data_p->buffer_in_read_ind = 0;
uart_1_data_p->buffer_in_write_ind = 0;
uart_1_data_p->buffer_in_len = 0;
uart_1_data_p->buffer_in_len_tmp = 0;
}
 
//void uart_2_init() {
// // Configure the PPS USART ports
//
// // UART2 RX Pin RP5
// RPINR16 = PPS_UART2_RX; // 5 is PPS RP5
// // UART2 TX Pin RP6
// PPS_UART2_TX = 6; // 6 is TX2/CK2 (EUSART2 Asynchronous Transmit/Asynchronous Clock Output)
//
// Open2USART(USART_TX_INT_OFF & // Interrupt on TX off
// USART_RX_INT_ON & // Interrupt on RX on
// USART_ASYNCH_MODE & // Operate in async mode
// USART_EIGHT_BIT & // Operate in 8-bit mode
// USART_CONT_RX & // Continuously recieve messages
// USART_BRGH_HIGH, 25); // Set UART speed to 115200 baud
//}
 
void UART1_Recv_Interrupt_Handler() {
unsigned char c;
if (PIR1bits.RC1IF) { // Check if data receive flag is set
c = RCREG1;
#ifdef UART1_RX_TO_BUFFER
// Save received data into buffer
uart_1_data_p->buffer_in[uart_1_data_p->buffer_in_write_ind] = c;
if (uart_1_data_p->buffer_in_write_ind == MAXUARTBUF - 1) {
uart_1_data_p->buffer_in_write_ind = 0;
} else {
uart_1_data_p->buffer_in_write_ind++;
}
 
// Store the last MAXUARTBUF values entered
if (uart_1_data_p->buffer_in_len_tmp < MAXUARTBUF) {
uart_1_data_p->buffer_in_len_tmp++;
} else {
if (uart_1_data_p->buffer_in_read_ind == MAXUARTBUF - 1) {
uart_1_data_p->buffer_in_read_ind = 0;
} else {
uart_1_data_p->buffer_in_read_ind++;
}
}
 
// Update buffer size upon receiving newline (0x0D)
if (c == UART1_BREAK_CHAR) {
uart_1_data_p->buffer_in_len = uart_1_data_p->buffer_in_len_tmp;
uart_1_data_p->buffer_in_len_tmp = 0;
}
#endif
#ifdef UART1_RX_TO_XBEE
XBee_Serial_In(c);
#endif
}
 
if (RCSTA1bits.OERR == 1) {
// We've overrun the USART and must reset
RCSTA1bits.CREN = 0; // Reset UART1
RCSTA1bits.CREN = 1;
DBG_PRINT_UART("UART1: (ERROR) overrun\r\n");
TXSTA1bits.TXEN = 0; // Kill anything currently sending
}
}
 
//void uart_2_recv_interrupt_handler() {
// if (DataRdy2USART()) {
//// xbee_read_serial(Read2USART());
// }
//
// if (USART2_Status.OVERRUN_ERROR == 1) {
// // We've overrun the USART and must reset
// RCSTA2bits.CREN = 0; // Reset UART2
// RCSTA2bits.CREN = 1;
// }
//}
 
void UART1_Send_Interrupt_Handler() {
// Put remaining data in TSR for transmit
if (uart_1_data_p->buffer_out_ind != uart_1_data_p->buffer_out_len) {
TXREG1 = uart_1_data_p->buffer_out[uart_1_data_p->buffer_out_ind];
uart_1_data_p->buffer_out_ind++;
} else {
while (!TXSTA1bits.TRMT); // Wait for last byte to finish sending
TXSTA1bits.TXEN = 0; // End transmission and disable TX interrupt
uart_1_data_p->buffer_out_ind = 0;
uart_1_data_p->buffer_out_len = 0;
}
}
 
void UART1_WriteS(const rom char *fmt, ...) {
#ifdef _DEBUG
unsigned char i;
va_list args;
va_start(args, fmt);
vsprintf((char *) uart_1_data_p->buffer_out, fmt, args);
va_end(args);
uart_1_data_p->buffer_out_len = strlen((char *) uart_1_data_p->buffer_out);
uart_1_data_p->buffer_out_ind = 1;
for (i = 0; i < uart_1_data_p->buffer_out_len; i++) {
TXREG1 = uart_1_data_p->buffer_out[i];
Nop();
while (!PIR1bits.TX1IF); // Wait for byte to be transmitted
}
#else
va_list args;
while (TXSTA1bits.TXEN); // Wait for previous message to finish sending
va_start(args, fmt);
vsprintf((char *) uart_1_data_p->buffer_out, fmt, args);
va_end(args);
uart_1_data_p->buffer_out_len = strlen((char *) uart_1_data_p->buffer_out);
uart_1_data_p->buffer_out_ind = 1;
TXREG1 = uart_1_data_p->buffer_out[0]; // Put first byte in TSR
TXSTA1bits.TXEN = 1; // Begin transmission
#endif
}
 
void UART1_WriteF(float f, unsigned char m) {
long whole = 0;
unsigned long decimal = 0;
unsigned int multiplier = 1;
unsigned char i;
 
for (i = 0; i < m; i++)
multiplier *= 10;
 
whole = (long)((float)f);
decimal = (long)((float)f*multiplier) - whole*multiplier;
// Round up if necessary
if ((long)((float)f*multiplier*10) % 10 >= 5)
decimal += 1;
#ifdef _DEBUG
sprintf((char *) uart_1_data_p->buffer_out, "%ld.%ld", whole, decimal);
uart_1_data_p->buffer_out_len = strlen((char *) uart_1_data_p->buffer_out);
uart_1_data_p->buffer_out_ind = 1;
for (i = 0; i < uart_1_data_p->buffer_out_len; i++) {
TXREG1 = uart_1_data_p->buffer_out[i];
Nop();
while (!PIR1bits.TX1IF); // Wait for byte to be transmitted
}
#else
while (TXSTA1bits.TXEN); // Wait for previous message to finish sending
sprintf((char *) uart_1_data_p->buffer_out, "%ld.%ld", whole, decimal);
uart_1_data_p->buffer_out_len = strlen((char *) uart_1_data_p->buffer_out);
uart_1_data_p->buffer_out_ind = 1;
TXREG1 = uart_1_data_p->buffer_out[0]; // Put first byte in TSR
TXSTA1bits.TXEN = 1; // Begin transmission
#endif
}
 
void UART1_WriteB(const char *msg, unsigned char length) {
unsigned char i;
#ifdef _DEBUG
for (i = 0; i < length; i++) {
TXREG1 = msg[i];
Nop();
while (!PIR1bits.TX1IF); // Wait for byte to be transmitted
}
#else
while (TXSTA1bits.TXEN); // Wait for previous message to finish sending
uart_1_data_p->buffer_out_len = length;
uart_1_data_p->buffer_out_ind = 1;
for (i = 0; i < length; i++) {
uart_1_data_p->buffer_out[i] = msg[i];
}
TXREG1 = uart_1_data_p->buffer_out[0]; // Put first byte in TSR
TXSTA1bits.TXEN = 1; // Begin transmission
#endif
}
 
void UART1_WriteC(const unsigned char c) {
#ifdef _DEBUG
TXREG1 = c;
Nop();
while (!PIR1bits.TX1IF);
#else
while (TXSTA1bits.TXEN);
uart_1_data_p->buffer_out_len = 1;
uart_1_data_p->buffer_out_ind = 1;
TXREG1 = c;
TXSTA1bits.TXEN = 1;
#endif
 
}
 
unsigned char UART1_Buffer_Len() {
return uart_1_data_p->buffer_in_len;
}
 
/* Reader interface to the UART buffer, returns the number of bytes read */
unsigned char UART1_Read_Buffer(unsigned char *buffer) {
unsigned char i = 0;
while (uart_1_data_p->buffer_in_len != 0) {
buffer[i] = uart_1_data_p->buffer_in[uart_1_data_p->buffer_in_read_ind];
i++;
if (uart_1_data_p->buffer_in_read_ind == MAXUARTBUF - 1) {
uart_1_data_p->buffer_in_read_ind = 0;
} else {
uart_1_data_p->buffer_in_read_ind++;
}
uart_1_data_p->buffer_in_len--;
}
return i;
}
/PIC Projects/PIC_27J13/oled_NHD-0216KZW-AB5.c
0,0 → 1,196
#include "oled_NHD-0216KZW-AB5.h"
#include "defines.h"
#include <delays.h>
#include <string.h>
#include <stdio.h>
 
static OLED_CHAR_DATA oled_char_data;
static OLED_CHAR_DATA *oled_char_data_p = &oled_char_data;
 
void NHD_Init() {
PARALLEL_RS_TRIS = 0;
PARALLEL_RW_TRIS = 0;
PARALLEL_EN_TRIS = 0;
 
PARALLEL_D4_TRIS = 0;
PARALLEL_D5_TRIS = 0;
PARALLEL_D6_TRIS = 0;
PARALLEL_D7_TRIS = 0;
 
oled_char_data_p->display_function = LCD_FUNCTIONSET | LCD_4BITMODE;
}
 
void NHD_Begin(char cols, char rows) {
oled_char_data_p->num_lines = rows;
oled_char_data_p->current_line = 0;
 
PARALLEL_RS_LAT = 0;
PARALLEL_RW_LAT = 0;
PARALLEL_EN_LAT = 0;
 
PARALLEL_D4_LAT = 0;
PARALLEL_D5_LAT = 0;
PARALLEL_D6_LAT = 0;
PARALLEL_D7_LAT = 0;
Delay10KTCYx(1); // ~1ms
 
// Initialization sequence
NHD_Write_4_Bits(0x3);
NHD_Write_4_Bits(0x2);
NHD_Write_4_Bits(0x2);
NHD_Write_4_Bits(0x8);
NHD_Wait_For_Ready();
 
NHD_Send_Command(0x08); // Turn Off
NHD_Send_Command(0x01); // Clear Display
NHD_Send_Command(0x06); // Set Entry Mode
NHD_Send_Command(0x02); // Return to Home Position
NHD_Send_Command(0x0C); // Turn On
}
 
void NHD_Clear() {
NHD_Send_Command(LCD_CLEARDISPLAY);
}
 
void NHD_Home() {
NHD_Send_Command(LCD_RETURNHOME);
}
 
void NHD_Set_Cursor(unsigned char col, unsigned char row) {
unsigned char row_offsets[] = {0x00, 0x40, 0x14, 0x54};
if (row >= oled_char_data_p->num_lines) {
row = 0;
}
NHD_Send_Command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}
 
void NHD_Display(char option) {
if (option) {
oled_char_data_p->display_control |= LCD_DISPLAYON;
} else {
oled_char_data_p->display_control &= ~LCD_DISPLAYON;
}
NHD_Send_Command(LCD_DISPLAYCONTROL | oled_char_data_p->display_control);
}
 
void NHD_Blink(char option) {
if (option) {
oled_char_data_p->display_control |= LCD_BLINKON;
} else {
oled_char_data_p->display_control &= ~LCD_BLINKON;
}
NHD_Send_Command(LCD_DISPLAYCONTROL | oled_char_data_p->display_control);
}
 
void NHD_Cursor(char option) {
if (option) {
oled_char_data_p->display_control |= LCD_CURSORON;
} else {
oled_char_data_p->display_control &= ~LCD_CURSORON;
}
NHD_Send_Command(LCD_DISPLAYCONTROL | oled_char_data_p->display_control);
}
 
void NHD_Scroll_Display_Left() {
NHD_Send_Command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
 
void NHD_Scroll_Display_Right() {
NHD_Send_Command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}
 
void NHD_Left_To_Rigtht() {
oled_char_data_p->display_mode |= LCD_ENTRYLEFT;
NHD_Send_Command(LCD_ENTRYMODESET | oled_char_data_p->display_mode);
}
 
void NHD_Right_To_Left() {
oled_char_data_p->display_mode &= ~LCD_ENTRYLEFT;
NHD_Send_Command(LCD_ENTRYMODESET | oled_char_data_p->display_mode);
}
 
void NHD_Autoscroll(char option) {
if (option) {
oled_char_data_p->display_mode |= LCD_ENTRYSHIFTINCREMENT;
} else {
oled_char_data_p->display_mode &= ~LCD_ENTRYSHIFTINCREMENT;
}
NHD_Send_Command(LCD_ENTRYMODESET | oled_char_data_p->display_mode);
}
 
void NHD_Create_Char(unsigned char location, unsigned char *charmap) {
char i;
location &= 0x7;
NHD_Send_Command(LCD_SETCGRAMADDR | (location << 3));
for (i = 0; i < 8; i++) {
NHD_Send_Data(charmap[i]);
}
}
 
void NHD_Send_Command(unsigned char value) {
PARALLEL_RS_LAT = 0;
PARALLEL_RW_LAT = 0;
NHD_Write_4_Bits(value>>4);
NHD_Write_4_Bits(value);
NHD_Wait_For_Ready();
}
 
void NHD_Send_Data(unsigned char value) {
PARALLEL_RS_LAT = 1;
PARALLEL_RW_LAT = 0;
NHD_Write_4_Bits(value>>4);
NHD_Write_4_Bits(value);
NHD_Wait_For_Ready();
}
 
void NHD_Pulse_Enable(void) {
PARALLEL_EN_LAT = 1;
Nop();
Nop();
PARALLEL_EN_LAT = 0;
}
 
void NHD_Write_4_Bits(unsigned char value) {
PARALLEL_D4_LAT = (value) & 0x01;
PARALLEL_D5_LAT = (value>>1) & 0x01;
PARALLEL_D6_LAT = (value>>2) & 0x01;
PARALLEL_D7_LAT = (value>>3) & 0x01;
NHD_Pulse_Enable();
}
 
void NHD_Wait_For_Ready() {
char busy;
PARALLEL_BUSY_TRIS = 1;
PARALLEL_RS_LAT = 0;
PARALLEL_RW_LAT = 1;
do {
NHD_Pulse_Enable();
Nop();
busy = PARALLEL_BUSY_PORT;
NHD_Pulse_Enable();
} while (busy);
PARALLEL_BUSY_TRIS = 0;
PARALLEL_RW_LAT = 0;
}
 
void NHD_Write_String(const rom char *fmt, ...) {
unsigned char i, len;
unsigned char buffer[NHD_STRING_BUFFER_SIZE];
 
// Parse and create string
va_list args;
va_start(args, fmt);
vsprintf((char *) buffer, fmt, args);
va_end(args);
len = strlen((char *) buffer);
 
// Make sure string to insert fits in buffer, truncate if necessary
if (len > NHD_STRING_BUFFER_SIZE)
len = NHD_STRING_BUFFER_SIZE;
 
// Print buffer to string
for (i = 0; i < len; i++) {
NHD_Send_Data(buffer[i]);
}
}
/PIC Projects/PIC_27J13/oled_NHD-0216KZW-AB5.h
0,0 → 1,78
#ifndef OLED_NHD_0216KZW_AB5_H
#define OLED_NHD_0216KZW_AB5_H
 
#define NHD_STRING_BUFFER_SIZE 64
 
// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x28
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
 
// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
 
// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
 
// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
 
// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_JAPANESE 0x00
#define LCD_EUROPEAN_I 0x01
#define LCD_RUSSIAN 0x02
#define LCD_EUROPEAN_II 0x03
 
typedef struct __OLED_CHAR_DATA {
unsigned char display_function;
unsigned char display_control;
unsigned char display_mode;
unsigned char current_line;
unsigned char num_lines;
} OLED_CHAR_DATA;
 
void NHD_Init(void);
void NHD_Begin(char cols, char rows);
void NHD_Clear(void);
void NHD_Home(void);
void NHD_Display(char option);
void NHD_Blink(char option);
void NHD_Cursor(char option);
void NHD_Autoscroll(char option);
void NHD_Scroll_Display_Left(void);
void NHD_Scroll_Display_Right(void);
void NHD_Left_To_Rigtht(void);
void NHD_Right_To_Left(void);
 
void NHD_Create_Char(unsigned char location, unsigned char *charmap);
void NHD_Set_Cursor(unsigned char col, unsigned char row);
 
void NHD_Send_Data(unsigned char value);
void NHD_Send_Command(unsigned char value);
 
void NHD_Pulse_Enable(void);
void NHD_Write_4_Bits(unsigned char value);
void NHD_Wait_For_Ready(void);
 
void NHD_Write_String(const rom char *fmt, ...);
 
#endif /* OLED_NHD_0216KZW_AB5_H */
 
/PIC Projects/PIC_27J13/oled_ssd1306.c
0,0 → 1,825
#include "defines.h"
#include "oled_ssd1306.h"
#include "spi.h"
#include "glcdfont.c"
#include <delays.h>
#include <string.h>
#include <stdio.h>
 
static SSD1306_DATA ssd1306_data;
static SSD1306_DATA *ssd1306_data_p = &ssd1306_data;
 
#pragma idata LCD_BUFFER
// 512 (128x32) or 1024 (128x64) bytes allocated for LCD buffer
// See linker file for details
static unsigned char LCD_Buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,
0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,
0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,
0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,
0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,
0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,
0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,
0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,
0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,
0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,
0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#if (SSD1306_LCDHEIGHT == 64)
0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,
0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,
0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,
0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,
0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,
0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,
0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,
0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,
0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,
0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
#endif
};
#pragma idata
 
int SSD1306_Abs(int i) {
if (i < 0)
return -i;
else
return i;
}
 
void SSD1306_Swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
 
void SSD1306_Init() {
ssd1306_data_p->_width = ssd1306_data_p->WIDTH = SSD1306_LCDWIDTH;
ssd1306_data_p->_height = ssd1306_data_p->HEIGHT = SSD1306_LCDHEIGHT;
ssd1306_data_p->rotation = 0;
ssd1306_data_p->cursor_x = ssd1306_data_p->cursor_y = 0;
ssd1306_data_p->textsize = 1;
ssd1306_data_p->textcolor = SSD1306_WHITE;
ssd1306_data_p->textbgcolor = SSD1306_BLACK;
ssd1306_data_p->wrap = 1;
}
 
void SSD1306_Begin(unsigned char vccstate) {
// Toggle reset pin
SPI_RESET_LAT = 0;
Delay10KTCYx(1);
SPI_RESET_LAT = 1;
 
#if defined SSD1306_128_32
// Init sequence for 128x32 OLED module
SSD1306_Command(SSD1306_DISPLAYOFF); // 0xAE
SSD1306_Command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
SSD1306_Command(0x80); // The suggested ratio 0x80
SSD1306_Command(SSD1306_SETMULTIPLEX); // 0xA8
SSD1306_Command(0x1F);
SSD1306_Command(SSD1306_SETDISPLAYOFFSET); // 0xD3
SSD1306_Command(0x0); // No offset
SSD1306_Command(SSD1306_SETSTARTLINE | 0x0); // Line #0
SSD1306_Command(SSD1306_CHARGEPUMP); // 0x8D
if (vccstate == SSD1306_EXTERNALVCC) {
SSD1306_Command(0x10);
} else {
SSD1306_Command(0x14);
}
SSD1306_Command(SSD1306_MEMORYMODE); // 0x20
SSD1306_Command(0x00); // 0x0 act like ks0108
SSD1306_Command(SSD1306_SEGREMAP | 0x1);
SSD1306_Command(SSD1306_COMSCANDEC);
SSD1306_Command(SSD1306_SETCOMPINS); // 0xDA
SSD1306_Command(0x02);
SSD1306_Command(SSD1306_SETCONTRAST); // 0x81
SSD1306_Command(0x8F);
SSD1306_Command(SSD1306_SETPRECHARGE); // 0xd9
if (vccstate == SSD1306_EXTERNALVCC) {
SSD1306_Command(0x22);
} else {
SSD1306_Command(0xF1);
}
SSD1306_Command(SSD1306_SETVCOMDETECT); // 0xDB
SSD1306_Command(0x40);
SSD1306_Command(SSD1306_DISPLAYALLON_RESUME); // 0xA4
SSD1306_Command(SSD1306_NORMALDISPLAY); // 0xA6
#endif
 
#if defined SSD1306_128_64
// Init sequence for 128x64 OLED module
SSD1306_Command(SSD1306_DISPLAYOFF); // 0xAE
SSD1306_Command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
SSD1306_Command(0x80); // The suggested ratio 0x80
SSD1306_Command(SSD1306_SETMULTIPLEX); // 0xA8
SSD1306_Command(0x3F);
SSD1306_Command(SSD1306_SETDISPLAYOFFSET); // 0xD3
SSD1306_Command(0x0); // No offset
SSD1306_Command(SSD1306_SETSTARTLINE | 0x0); // Line #0
SSD1306_Command(SSD1306_CHARGEPUMP); // 0x8D
if (vccstate == SSD1306_EXTERNALVCC) {
SSD1306_Command(0x10);
} else {
SSD1306_Command(0x14);
}
SSD1306_Command(SSD1306_MEMORYMODE); // 0x20
SSD1306_Command(0x00); // 0x0 act like ks0108
SSD1306_Command(SSD1306_SEGREMAP | 0x1);
SSD1306_Command(SSD1306_COMSCANDEC);
SSD1306_Command(SSD1306_SETCOMPINS); // 0xDA
SSD1306_Command(0x12);
SSD1306_Command(SSD1306_SETCONTRAST); // 0x81
if (vccstate == SSD1306_EXTERNALVCC) {
SSD1306_Command(0x9F);
} else {
SSD1306_Command(0xCF);
}
SSD1306_Command(SSD1306_SETPRECHARGE); // 0xd9
if (vccstate == SSD1306_EXTERNALVCC) {
SSD1306_Command(0x22);
} else {
SSD1306_Command(0xF1);
}
SSD1306_Command(SSD1306_SETVCOMDETECT); // 0xDB
SSD1306_Command(0x40);
SSD1306_Command(SSD1306_DISPLAYALLON_RESUME); // 0xA4
SSD1306_Command(SSD1306_NORMALDISPLAY); // 0xA6
#endif
 
SSD1306_Command(SSD1306_DISPLAYON); // Turn on OLED panel
}
 
void SSD1306_Command(unsigned char cmd) {
unsigned char c = cmd;
SPI_DC_SELECT_LAT = 0; // D/C low (cmd)
SPI2_Write(&c, 1);
}
 
void SSD1306_Data(unsigned char data) {
unsigned char c = data;
SPI_DC_SELECT_LAT = 1; // D/C high (data)
SPI2_Write(&c, 1);
}
 
void SSD1306_Clear_Display() {
memset(LCD_Buffer, 0, (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8));
}
 
void SSD1306_Invert_Display(unsigned char c) {
if (c) {
SSD1306_Command(SSD1306_INVERTDISPLAY);
} else {
SSD1306_Command((SSD1306_NORMALDISPLAY));
}
}
 
void SSD1306_Display() {
unsigned int i;
unsigned char c = 0;
 
SSD1306_Command(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0
SSD1306_Command(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0
SSD1306_Command(SSD1306_SETSTARTLINE | 0x0); // line #0
 
SPI_DC_SELECT_LAT = 1; // D/C high (data)
SPI2_Write(LCD_Buffer, SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8);
 
// if (SSD1306_LCDHEIGHT == 32) {
// SPI2_Write_Repeat(0, SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8);
// }
}
 
void SSD1306_Draw_Pixel(int x, int y, unsigned int color) {
if ((x < 0) || (x >= ssd1306_data_p->_width) || (y < 0) || (y >= ssd1306_data_p->_height))
return;
 
// check rotation, move pixel around if necessary
switch (ssd1306_data_p->rotation) {
case 1:
SSD1306_Swap(&x, &y);
x = SSD1306_LCDWIDTH - x - 1;
break;
case 2:
x = SSD1306_LCDWIDTH - x - 1;
y = SSD1306_LCDHEIGHT - y - 1;
break;
case 3:
SSD1306_Swap(&x, &y);
y = SSD1306_LCDHEIGHT - y - 1;
break;
}
 
// x is which column
if (color == SSD1306_WHITE)
LCD_Buffer[x + (y / 8) * SSD1306_LCDWIDTH] |= 1<<(y % 8);
else
LCD_Buffer[x + (y / 8) * SSD1306_LCDWIDTH] &= ~(1<<(y % 8));
}
 
void SSD1306_Draw_Line(int x0, int y0, int x1, int y1, unsigned int color) {
int dx, dy, err, ystep;
int steep = SSD1306_Abs(y1 - y0) > SSD1306_Abs(x1 - x0);
if (steep) {
SSD1306_Swap(&x0, &y0);
SSD1306_Swap(&x1, &y1);
}
 
if (x0 > x1) {
SSD1306_Swap(&x0, &x1);
SSD1306_Swap(&y0, &y1);
}
 
dx = x1 - x0;
dy = SSD1306_Abs(y1 - y0);
 
err = dx / 2;
 
if (y0 < y1) {
ystep = 1;
} else {
ystep = -1;
}
 
for (; x0 <= x1; x0++) {
 
if (steep) {
SSD1306_Draw_Pixel(y0, x0, color);
} else {
SSD1306_Draw_Pixel(x0, y0, color);
}
err -= dy;
if (err < 0) {
y0 += ystep;
err += dx;
}
}
}
 
void SSD1306_Draw_Fast_VLine(int x, int y, int h, unsigned int color) {
SSD1306_Draw_Line(x, y, x, y + h - 1, color);
}
 
void SSD1306_Draw_Fast_HLine(int x, int y, int w, unsigned int color) {
SSD1306_Draw_Line(x, y, x + w - 1, y, color);
}
 
void SSD1306_Draw_Rect(int x, int y, int w, int h, unsigned int color) {
SSD1306_Draw_Fast_HLine(x, y, w, color);
SSD1306_Draw_Fast_HLine(x, y + h, w, color);
SSD1306_Draw_Fast_VLine(x, y, h, color);
SSD1306_Draw_Fast_VLine(x + w, y, h, color);
}
 
void SSD1306_Fill_Rect(int x, int y, int w, int h, unsigned int color) {
int i;
for (i = x; i < x + w; i++) {
SSD1306_Draw_Fast_VLine(i, y, h, color);
}
}
 
void SSD1306_Draw_Circle(int x0, int y0, int r, unsigned int color) {
int f = 1 - r;
int ddF_x = 1;
int ddF_y = -2 * r;
int x = 0;
int y = r;
 
SSD1306_Draw_Pixel(x0, y0 + r, color);
SSD1306_Draw_Pixel(x0, y0 - r, color);
SSD1306_Draw_Pixel(x0 + r, y0, color);
SSD1306_Draw_Pixel(x0 - r, y0, color);
 
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
 
SSD1306_Draw_Pixel(x0 + x, y0 + y, color);
SSD1306_Draw_Pixel(x0 - x, y0 + y, color);
SSD1306_Draw_Pixel(x0 + x, y0 - y, color);
SSD1306_Draw_Pixel(x0 - x, y0 - y, color);
SSD1306_Draw_Pixel(x0 + y, y0 + x, color);
SSD1306_Draw_Pixel(x0 - y, y0 + x, color);
SSD1306_Draw_Pixel(x0 + y, y0 - x, color);
SSD1306_Draw_Pixel(x0 - y, y0 - x, color);
}
}
 
void SSD1306_Draw_Circle_Helper(int x0, int y0, int r, unsigned char cornername, unsigned int color) {
int f = 1 - r;
int ddF_x = 1;
int ddF_y = -2 * r;
int x = 0;
int y = r;
 
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
if (cornername & 0x4) {
SSD1306_Draw_Pixel(x0 + x, y0 + y, color);
SSD1306_Draw_Pixel(x0 + y, y0 + x, color);
}
if (cornername & 0x2) {
SSD1306_Draw_Pixel(x0 + x, y0 - y, color);
SSD1306_Draw_Pixel(x0 + y, y0 - x, color);
}
if (cornername & 0x8) {
SSD1306_Draw_Pixel(x0 - y, y0 + x, color);
SSD1306_Draw_Pixel(x0 - x, y0 + y, color);
}
if (cornername & 0x1) {
SSD1306_Draw_Pixel(x0 - y, y0 - x, color);
SSD1306_Draw_Pixel(x0 - x, y0 - y, color);
}
}
}
 
void SSD1306_Fill_Circle(int x0, int y0, int r, unsigned int color) {
SSD1306_Draw_Fast_VLine(x0, y0 - r, 2 * r + 1, color);
SSD1306_Fill_Circle_Helper(x0, y0, r, 3, 0, color);
}
 
void SSD1306_Fill_Circle_Helper(int x0, int y0, int r, unsigned char cornername, int delta, unsigned int color) {
int f = 1 - r;
int ddF_x = 1;
int ddF_y = -2 * r;
int x = 0;
int y = r;
 
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
 
if (cornername & 0x1) {
SSD1306_Draw_Fast_VLine(x0 + x, y0 - y, 2 * y + 1 + delta, color);
SSD1306_Draw_Fast_VLine(x0 + y, y0 - x, 2 * x + 1 + delta, color);
}
if (cornername & 0x2) {
SSD1306_Draw_Fast_VLine(x0 - x, y0 - y, 2 * y + 1 + delta, color);
SSD1306_Draw_Fast_VLine(x0 - y, y0 - x, 2 * x + 1 + delta, color);
}
}
}
 
void SSD1306_Draw_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {
SSD1306_Draw_Line(x0, y0, x1, y1, color);
SSD1306_Draw_Line(x1, y1, x2, y2, color);
SSD1306_Draw_Line(x2, y2, x0, y0, color);
}
 
void SSD1306_Fill_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {
int a, b, y, last;
int dx01 = x1 - x0;
int dy01 = y1 - y0;
int dx02 = x2 - x0;
int dy02 = y2 - y0;
int dx12 = x2 - x1;
int dy12 = y2 - y1;
int sa = 0;
int sb = 0;
 
// Sort coordinates by Y order (y2 >= y1 >= y0)
if (y0 > y1) {
SSD1306_Swap(&y0, &y1);
SSD1306_Swap(&x0, &x1);
}
if (y1 > y2) {
SSD1306_Swap(&y2, &y1);
SSD1306_Swap(&x2, &x1);
}
if (y0 > y1) {
SSD1306_Swap(&y0, &y1);
SSD1306_Swap(&x0, &x1);
}
 
if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
a = b = x0;
if (x1 < a) a = x1;
else if (x1 > b) b = x1;
if (x2 < a) a = x2;
else if (x2 > b) b = x2;
SSD1306_Draw_Fast_HLine(a, y0, b - a + 1, color);
return;
}
 
// For upper part of triangle, find scanline crossings for segments
// 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
// is included here (and second loop will be skipped, avoiding a /0
// error there), otherwise scanline y1 is skipped here and handled
// in the second loop...which also avoids a /0 error here if y0=y1
// (flat-topped triangle).
if (y1 == y2) last = y1; // Include y1 scanline
else last = y1 - 1; // Skip it
 
for (y = y0; y <= last; y++) {
a = x0 + sa / dy01;
b = x0 + sb / dy02;
sa += dx01;
sb += dx02;
/* longhand:
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if (a > b) SSD1306_Swap(&a, &b);
SSD1306_Draw_Fast_HLine(a, y, b - a + 1, color);
}
 
// For lower part of triangle, find scanline crossings for segments
// 0-2 and 1-2. This loop is skipped if y1=y2.
sa = dx12 * (y - y1);
sb = dx02 * (y - y0);
for (; y <= y2; y++) {
a = x1 + sa / dy12;
b = x0 + sb / dy02;
sa += dx12;
sb += dx02;
/* longhand:
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if (a > b) SSD1306_Swap(&a, &b);
SSD1306_Draw_Fast_HLine(a, y, b - a + 1, color);
}
}
 
void SSD1306_Draw_Round_Rect(int x, int y, int w, int h, int r, unsigned int color) {
// smarter version
SSD1306_Draw_Fast_HLine(x + r, y, w - 2 * r, color); // Top
SSD1306_Draw_Fast_HLine(x + r, y + h - 1, w - 2 * r, color); // Bottom
SSD1306_Draw_Fast_VLine(x, y + r, h - 2 * r, color); // Left
SSD1306_Draw_Fast_VLine(x + w - 1, y + r, h - 2 * r, color); // Right
 
// draw four corners
SSD1306_Draw_Circle_Helper(x + r, y + r, r, 1, color);
SSD1306_Draw_Circle_Helper(x + w - r - 1, y + r, r, 2, color);
SSD1306_Draw_Circle_Helper(x + w - r - 1, y + h - r - 1, r, 4, color);
SSD1306_Draw_Circle_Helper(x + r, y + h - r - 1, r, 8, color);
}
 
void SSD1306_Fill_Round_Rect(int x, int y, int w, int h, int r, unsigned int color) {
// smarter version
SSD1306_Fill_Rect(x + r, y, w - 2 * r, h, color);
 
// draw four corners
SSD1306_Fill_Circle_Helper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);
SSD1306_Fill_Circle_Helper(x + r, y + r, r, 2, h - 2 * r - 1, color);
}
 
void SSD1306_Draw_Bitmap(int x, int y, const unsigned char* bitmap, int w, int h, unsigned int color) {
int i, j;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
if (bitmap[i + (j / 8) * w] & (j % 8)) {
SSD1306_Draw_Pixel(x + i, y + j, color);
}
}
}
}
 
void SSD1306_Draw_Char(int x, int y, unsigned char c, unsigned int color, unsigned int bg, unsigned char size) {
int i, j;
unsigned int line;
 
if ((x >= ssd1306_data_p->_width) || // Clip right
(y >= ssd1306_data_p->_height) || // Clip bottom
((x + 5 * size - 1) < 0) || // Clip left
((y + 8 * size - 1) < 0)) // Clip top
return;
 
for (i = 0; i < 6; i++) {
if (i == 5)
line = 0x0;
else
line = font[(c * 5) + i];
for (j = 0; j < 8; j++) {
if (line & 0x1) {
if (size == 1) {// default size
SSD1306_Draw_Pixel(x + i, y + j, color);
} else { // big size
SSD1306_Fill_Rect(x + (i * size), y + (j * size), size, size, color);
}
} else if (bg != color) {
if (size == 1) { // default size
SSD1306_Draw_Pixel(x + i, y + j, bg);
} else { // big size
SSD1306_Fill_Rect(x + i*size, y + j*size, size, size, bg);
}
}
line >>= 1;
}
}
}
 
void SSD1306_Write(unsigned char c) {
if (c == '\n' || c == '\r') {
ssd1306_data_p->cursor_y += ssd1306_data_p->textsize * 8;
ssd1306_data_p->cursor_x = 0;
// } else if (c == '\r') {
// // skip em
} else {
SSD1306_Draw_Char(ssd1306_data_p->cursor_x, ssd1306_data_p->cursor_y, c, ssd1306_data_p->textcolor, ssd1306_data_p->textbgcolor, ssd1306_data_p->textsize);
ssd1306_data_p->cursor_x += ssd1306_data_p->textsize * 6;
if (ssd1306_data_p->wrap && (ssd1306_data_p->cursor_x > (ssd1306_data_p->_width - ssd1306_data_p->textsize * 6))) {
ssd1306_data_p->cursor_y += ssd1306_data_p->textsize * 8;
ssd1306_data_p->cursor_x = 0;
}
}
}
 
void SSD1306_Write_String(const rom char *fmt, ...) {
unsigned char i, len;
unsigned char buffer[SSD1306_STRING_BUFFER_SIZE];
// Parse and create string
va_list args;
va_start(args, fmt);
vsprintf((char *) buffer, fmt, args);
va_end(args);
len = strlen((char *) buffer);
 
// Make sure string to insert fits in buffer, truncate if necessary
if (len > SSD1306_STRING_BUFFER_SIZE)
len = SSD1306_STRING_BUFFER_SIZE;
 
// Print buffer to string
for (i = 0; i < len; i++) {
SSD1306_Write(buffer[i]);
}
}
 
//void SSD1306_Append_String(const rom char *fmt, ...) {
// unsigned char i, len;
// unsigned char buffer[SSD1306_STRING_BUFFER_SIZE];
//
// // Parse and create string
// va_list args;
// va_start(args, fmt);
// vsprintf((char *) buffer, fmt, args);
// va_end(args);
//
// // Make sure string to insert fits in buffer, truncate if necessary
// len = strlen((char *) buffer);
//
// if (len == 1) { // This will only occur on "\n"
// // Do nothing?
// return;
// }
//
// if (len > SSD1306_STRING_BUFFER_SIZE)
// len = SSD1306_STRING_BUFFER_SIZE;
//
// // Omit the newline if string fill entire line
// if (((len - 1)%(ssd1306_data_p->_width / 6)) == 0) { // 16 or 10
// len -= 1;
// }
//
// // Shift everything right and insert string at beginning
// for (i = 127; i > len - 1; i--) {
// ssd1306_data_p->lcd_buffer[i] = ssd1306_data_p->lcd_buffer[i - len];
// }
// memcpy((char *)ssd1306_data_p->lcd_buffer, (const char *) buffer, len);
//
// // Print full buffer to screen
// SSD1306_Clear_Display();
// SSD1306_Display();
//
// SSD1306_Set_Cursor(0,0);
// for (i = 0; i < SSD1306_LCD_BUFFER_SIZE-1; i++) {
// SSD1306_Write(ssd1306_data_p->lcd_buffer[i]);
// }
//}
 
void SSD1306_Set_Cursor(int x, int y) {
ssd1306_data_p->cursor_x = x;
ssd1306_data_p->cursor_y = y;
}
 
void SSD1306_Set_Text_Color(unsigned int c) {
// for 'transparent' background, we'll set the bg
// to the same as fg instead of using a flag
ssd1306_data_p->textcolor = c;
ssd1306_data_p->textbgcolor = c;
}
 
void SSD1306_Set_Text_Color_BG(unsigned int c, unsigned int bg) {
ssd1306_data_p->textcolor = c;
ssd1306_data_p->textbgcolor = bg;
}
 
void SSD1306_Set_Text_Size(unsigned char s) {
ssd1306_data_p->textsize = (s > 0) ? s : 1;
}
 
void SSD1306_Set_Text_Wrap(unsigned char w) {
ssd1306_data_p->wrap = w;
}
 
void SSD1306_Set_Rotation(unsigned char x) {
x %= 4; // cant be higher than 3
ssd1306_data_p->rotation = x;
switch (x) {
case 0:
case 2:
ssd1306_data_p->_width = ssd1306_data_p->WIDTH;
ssd1306_data_p->_height = ssd1306_data_p->HEIGHT;
break;
case 1:
case 3:
ssd1306_data_p->_width = ssd1306_data_p->HEIGHT;
ssd1306_data_p->_height = ssd1306_data_p->WIDTH;
break;
}
}
 
 
 
void SSD1306_Test_DrawChar() {
unsigned char i;
SSD1306_Set_Text_Size(1);
SSD1306_Set_Text_Color(SSD1306_WHITE);
SSD1306_Set_Cursor(0, 0);
 
for (i = 0; i < 168; i++) {
if (i == '\n') continue;
SSD1306_Write(i);
// if ((i > 0) && (i % 21 == 0))
// SSD1306_write('\n');
}
SSD1306_Display();
}
 
void SSD1306_Test_DrawCircle() {
int i;
for (i = 0; i < ssd1306_data_p->_height; i += 2) {
SSD1306_Draw_Circle(ssd1306_data_p->_width / 2, ssd1306_data_p->_height / 2, i, SSD1306_WHITE);
SSD1306_Display();
}
}
 
void SSD1306_Test_DrawRect(void) {
int i;
for (i = 0; i < ssd1306_data_p->_height / 2; i += 2) {
SSD1306_Draw_Rect(i, i, ssd1306_data_p->_width - 2 * i, ssd1306_data_p->_height - 2 * i, SSD1306_WHITE);
SSD1306_Display();
}
}
 
void SSD1306_Test_FillRect(void) {
unsigned char color = 1;
int i;
for (i = 0; i < ssd1306_data_p->_height / 2; i += 3) {
// alternate colors
SSD1306_Fill_Rect(i, i, ssd1306_data_p->_width - i * 2, ssd1306_data_p->_height - i * 2, color % 2);
SSD1306_Display();
color++;
}
}
 
void SSD1306_Test_DrawTriangle(void) {
int i;
int min = ssd1306_data_p->_width < ssd1306_data_p->_height ? ssd1306_data_p->_width : ssd1306_data_p->_height;
for (i = 0; i < min / 2; i += 5) {
SSD1306_Draw_Triangle(ssd1306_data_p->_width / 2, ssd1306_data_p->_height / 2 - i,
ssd1306_data_p->_width / 2 - i, ssd1306_data_p->_height / 2 + i,
ssd1306_data_p->_width / 2 + i, ssd1306_data_p->_height / 2 + i, SSD1306_WHITE);
SSD1306_Display();
}
}
 
void SSD1306_Test_FillTriangle(void) {
unsigned char color = SSD1306_WHITE;
int i;
int min = ssd1306_data_p->_width < ssd1306_data_p->_height ? ssd1306_data_p->_width : ssd1306_data_p->_height;
for (i = min / 2; i > 0; i -= 5) {
SSD1306_Fill_Triangle(ssd1306_data_p->_width / 2, ssd1306_data_p->_height / 2 - i,
ssd1306_data_p->_width / 2 - i, ssd1306_data_p->_height / 2 + i,
ssd1306_data_p->_width / 2 + i, ssd1306_data_p->_height / 2 + i, SSD1306_WHITE);
if (color == SSD1306_WHITE) color = SSD1306_BLACK;
else color = SSD1306_WHITE;
SSD1306_Display();
}
}
 
void SSD1306_Test_DrawRoundRect(void) {
int i;
for (i = 0; i < ssd1306_data_p->_height / 2 - 2; i += 2) {
SSD1306_Draw_Round_Rect(i, i, ssd1306_data_p->_width - 2 * i, ssd1306_data_p->_height - 2 * i, ssd1306_data_p->_height / 4, SSD1306_WHITE);
SSD1306_Display();
}
}
 
void SSD1306_Test_FillRoundRect(void) {
unsigned char color = SSD1306_WHITE;
int i;
for (i = 0; i < ssd1306_data_p->_height / 2 - 2; i += 2) {
SSD1306_Fill_Round_Rect(i, i, ssd1306_data_p->_width - 2 * i, ssd1306_data_p->_height - 2 * i, ssd1306_data_p->_height / 4, color);
if (color == SSD1306_WHITE) color = SSD1306_BLACK;
else color = SSD1306_WHITE;
SSD1306_Display();
}
}
 
void SSD1306_Test_DrawLine(void) {
int i;
for (i = 0; i < ssd1306_data_p->_width; i += 4) {
SSD1306_Draw_Line(0, 0, i, ssd1306_data_p->_height - 1, SSD1306_WHITE);
SSD1306_Display();
}
for (i = 0; i < ssd1306_data_p->_height; i += 4) {
SSD1306_Draw_Line(0, 0, ssd1306_data_p->_width - 1, i, SSD1306_WHITE);
SSD1306_Display();
}
Delay10KTCYx(255);
 
SSD1306_Clear_Display();
for (i = 0; i < ssd1306_data_p->_width; i += 4) {
SSD1306_Draw_Line(0, ssd1306_data_p->_height - 1, i, 0, SSD1306_WHITE);
SSD1306_Display();
}
for (i = ssd1306_data_p->_height - 1; i >= 0; i -= 4) {
SSD1306_Draw_Line(0, ssd1306_data_p->_height - 1, ssd1306_data_p->_width - 1, i, SSD1306_WHITE);
SSD1306_Display();
}
Delay10KTCYx(255);
 
SSD1306_Clear_Display();
for (i = ssd1306_data_p->_width - 1; i >= 0; i -= 4) {
SSD1306_Draw_Line(ssd1306_data_p->_width - 1, ssd1306_data_p->_height - 1, i, 0, SSD1306_WHITE);
SSD1306_Display();
}
for (i = ssd1306_data_p->_height - 1; i >= 0; i -= 4) {
SSD1306_Draw_Line(ssd1306_data_p->_width - 1, ssd1306_data_p->_height - 1, 0, i, SSD1306_WHITE);
SSD1306_Display();
}
Delay10KTCYx(255);
 
SSD1306_Clear_Display();
for (i = 0; i < ssd1306_data_p->_height; i += 4) {
SSD1306_Draw_Line(ssd1306_data_p->_width - 1, 0, 0, i, SSD1306_WHITE);
SSD1306_Display();
}
for (i = 0; i < ssd1306_data_p->_width; i += 4) {
SSD1306_Draw_Line(ssd1306_data_p->_width - 1, 0, i, ssd1306_data_p->_height - 1, SSD1306_WHITE);
SSD1306_Display();
}
Delay10KTCYx(255);
}
/PIC Projects/PIC_27J13/adc.c
0,0 → 1,53
#include "defines.h"
#include "adc.h"
 
static ADC_DATA adc_data;
static ADC_DATA *adc_data_p = &adc_data;
 
void ADC_Init(unsigned char TAD, unsigned char FOSC) {
ADC_AN0_TRIS = 1;
ADC_AN1_TRIS = 1;
ADC_AN2_TRIS = 1;
 
adc_data_p->last_channel = 0;
adc_data_p->result = 0;
 
ADCON0bits.VCFG1 = 0; // VRef- = AVss
ADCON0bits.VCFG0 = 1; // VRef+ != AVdd
ADCON1bits.ADFM = 1; // Right justified result
ADCON1bits.ADCAL = 1; // Calibrate A/D
ADCON1bits.ACQT = TAD;
ADCON1bits.ADCS = FOSC;
ADCON0bits.ADON = 1; // Enable A/D module
 
ADCON0bits.GO_DONE = 1; // Start calibration
while (ADCON0bits.GO_DONE); // Wait for calibration to finish
PIR1bits.ADIF = 0; // Clear the IF flag
ADCON1bits.ADCAL = 0; // Normal A/D operation
 
PIE1bits.ADIE = 1; // Enable A/D interrupt
 
}
 
void ADC_Start(unsigned char channel) {
adc_data_p->last_channel = channel;
ADCON0bits.CHS = channel; // Set A/D channel
ADCON0bits.GO_DONE = 1; // Start A/D conversion
}
 
void ADC_Stop() {
ADCON0bits.ADON = 0; // Disable A/D module
}
 
void ADC_Interrupt_Handler() {
adc_data_p->result = ADRES;
}
 
char ADC_Get_Result(unsigned int* ret) {
if (ADCON0bits.GO_DONE) {
return 0;
} else {
*ret = adc_data_p->result;
return 1;
}
}
/PIC Projects/PIC_27J13/i2c.c
0,0 → 1,554
#include "defines.h"
#include "i2c.h"
 
static I2C_DATA i2c_data;
static I2C_DATA *i2c_data_p = &i2c_data;
 
// Set up the data structures for the i2c code
// Should be called once before any i2c routines are called
void I2C_Init() {
i2c_data_p->buffer_in_len = 0;
i2c_data_p->buffer_in_len_tmp = 0;
i2c_data_p->buffer_in_read_ind = 0;
i2c_data_p->buffer_in_write_ind = 0;
 
i2c_data_p->buffer_out_ind = 0;
i2c_data_p->buffer_out_len = 0;
i2c_data_p->operating_mode = 0;
i2c_data_p->operating_state = I2C_IDLE;
i2c_data_p->return_status = 0;
 
i2c_data_p->slave_in_last_byte = 0;
i2c_data_p->slave_sending_data = 0;
 
i2c_data_p->master_dest_addr = 0;
i2c_data_p->master_status = I2C_MASTER_IDLE;
// Enable I2C interrupt
PIE1bits.SSPIE = 1;
}
 
// Setup the PIC to operate as a master.
void I2C_Configure_Master(unsigned char speed) {
i2c_data_p->operating_mode = I2C_MODE_MASTER;
 
I2C_CLK_TRIS = 1;
I2C_DAT_TRIS = 1;
 
SSPSTAT = 0x0;
SSPCON1 = 0x0;
SSPCON2 = 0x0;
SSPCON1bits.SSPM = 0x8; // I2C Master Mode
if (speed) {
SSPADD = 0x74; // Operate at 100KHz (48MHz)
} else {
SSPADD = 0x1A; // Operate at 400KHz (48MHz)
}
SSPSTATbits.SMP = 1; // Disable Slew Rate Control
SSPCON1bits.SSPEN = 1; // Enable MSSP Module
}
 
// Sends length number of bytes in msg to specified address (no R/W bit)
void I2C_Master_Send(unsigned char address, unsigned char length, unsigned char *msg) {
unsigned char i;
if (length == 0)
return;
// Copy message to send into buffer and save length/address
for (i = 0; i < length; i++) {
i2c_data_p->buffer_in[i] = msg[i];
}
i2c_data_p->buffer_in_len = length;
i2c_data_p->master_dest_addr = address;
i2c_data_p->buffer_in_read_ind = 0;
i2c_data_p->buffer_in_write_ind = 0;
 
// Change status to 'next' operation
i2c_data_p->operating_state = I2C_SEND_ADDR;
i2c_data_p->master_status = I2C_MASTER_SEND;
// Generate start condition
SSPCON2bits.SEN = 1;
}
 
// Reads length number of bytes from address (no R/W bit)
void I2C_Master_Recv(unsigned char address, unsigned char length) {
if (length == 0)
return;
 
// Save length and address to get data from
i2c_data_p->buffer_in_len = length;
i2c_data_p->master_dest_addr = address;
i2c_data_p->buffer_in_read_ind = 0;
i2c_data_p->buffer_in_write_ind = 0;
 
// Change status to 'next' operation
i2c_data_p->operating_state = I2C_SEND_ADDR;
i2c_data_p->master_status = I2C_MASTER_RECV;
// Generate start condition
SSPCON2bits.SEN = 1;
}
 
// Writes msg to address then reads length number of bytes from address
void I2C_Master_Restart(unsigned char address, unsigned char msg, unsigned char length) {
unsigned char c;
if (length == 0) {
c = msg;
I2C_Master_Send(address, 1, &c);
return;
}
 
// Save length and address to get data from
i2c_data_p->buffer_in[0] = msg;
i2c_data_p->buffer_in_len = length;
i2c_data_p->master_dest_addr = address;
i2c_data_p->buffer_in_read_ind = 0;
i2c_data_p->buffer_in_write_ind = 0;
 
// Change status to 'next' operation
i2c_data_p->operating_state = I2C_SEND_ADDR;
i2c_data_p->master_status = I2C_MASTER_RESTART;
 
// Generate start condition
SSPCON2bits.SEN = 1;
}
 
// Setup the PIC to operate as a slave. The address must not include the R/W bit
void I2C_Configure_Slave(unsigned char addr) {
i2c_data_p->operating_mode = I2C_MODE_SLAVE;
 
// Ensure the two lines are set for input (we are a slave)
I2C_CLK_TRIS = 1;
I2C_DAT_TRIS = 1;
 
SSPADD = addr << 1; // Set the slave address
 
SSPSTAT = 0x0;
SSPCON1 = 0x0;
SSPCON2 = 0x0;
SSPCON1bits.SSPM = 0xE; // Enable Slave 7-bit w/ start/stop interrupts
SSPSTATbits.SMP = 1; // Slew Off
SSPCON2bits.SEN = 1; // Enable clock-stretching
SSPCON1bits.SSPEN = 1; // Enable MSSP Module
}
 
void I2C_Interrupt_Handler() {
// Call interrupt depending on which mode we are operating in
if (i2c_data_p->operating_mode == I2C_MODE_MASTER) {
I2C_Interrupt_Master();
} else if (i2c_data_p->operating_mode == I2C_MODE_SLAVE) {
I2C_Interrupt_Slave();
}
}
 
// An internal subroutine used in the master version of the i2c_interrupt_handler
void I2C_Interrupt_Master() {
// If we are in the middle of sending data
if (i2c_data_p->master_status == I2C_MASTER_SEND) {
switch (i2c_data_p->operating_state) {
case I2C_IDLE:
break;
case I2C_SEND_ADDR:
// Send the address with read bit set
i2c_data_p->operating_state = I2C_CHECK_ACK_SEND;
SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x0;
break;
case I2C_CHECK_ACK_SEND:
// Check if ACK is received or not
if (!SSPCON2bits.ACKSTAT) {
// If an ACK is received, send next byte of data
if (i2c_data_p->buffer_in_read_ind < i2c_data_p->buffer_in_len) {
SSPBUF = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
i2c_data_p->buffer_in_read_ind++;
} else {
// If no more data is to be sent, send stop bit
i2c_data_p->operating_state = I2C_IDLE;
SSPCON2bits.PEN = 1;
i2c_data_p->master_status = I2C_MASTER_IDLE;
i2c_data_p->return_status = I2C_SEND_OK;
}
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C_IDLE;
SSPCON2bits.PEN = 1;
i2c_data_p->master_status = I2C_MASTER_IDLE;
i2c_data_p->return_status = I2C_SEND_FAIL;
}
break;
}
// If we are in the middle of receiving data
} else if (i2c_data_p->master_status == I2C_MASTER_RECV) {
switch (i2c_data_p->operating_state) {
case I2C_IDLE:
break;
case I2C_SEND_ADDR:
// Send address with write bit set
i2c_data_p->operating_state = I2C_CHECK_ACK_RECV;
SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x1;
break;
case I2C_CHECK_ACK_RECV:
// Check if ACK is received
if (!SSPCON2bits.ACKSTAT) {
// If an ACK is received, set module to receive 1 byte of data
i2c_data_p->operating_state = I2C_RCV_DATA;
SSPCON2bits.RCEN = 1;
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C_IDLE;
SSPCON2bits.PEN = 1;
i2c_data_p->master_status = I2C_MASTER_IDLE;
i2c_data_p->return_status = I2C_RECV_FAIL;
}
break;
case I2C_RCV_DATA:
// On receive, save byte into buffer
// TODO: handle i2c buffer overflow
i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = SSPBUF;
i2c_data_p->buffer_in_write_ind++;
if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
// If we still need to read, send an ACK to the slave
i2c_data_p->operating_state = I2C_REQ_DATA;
SSPCON2bits.ACKDT = 0; // ACK
SSPCON2bits.ACKEN = 1;
} else {
// If we are done reading, send an NACK to the slave
i2c_data_p->operating_state = I2C_SEND_STOP;
SSPCON2bits.ACKDT = 1; // NACK
SSPCON2bits.ACKEN = 1;
}
break;
case I2C_REQ_DATA:
// Set module to receive one byte of data
i2c_data_p->operating_state = I2C_RCV_DATA;
SSPCON2bits.RCEN = 1;
break;
case I2C_SEND_STOP:
// Send the stop bit and copy message to send to Main()
i2c_data_p->operating_state = I2C_IDLE;
SSPCON2bits.PEN = 1;
i2c_data_p->master_status = I2C_MASTER_IDLE;
i2c_data_p->return_status = I2C_RECV_OK;
break;
}
} else if (i2c_data_p->master_status == I2C_MASTER_RESTART) {
switch (i2c_data_p->operating_state) {
case I2C_IDLE:
break;
case I2C_SEND_ADDR:
// Send the address with read bit set
i2c_data_p->operating_state = I2C_CHECK_ACK_SEND;
SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x0;
break;
case I2C_CHECK_ACK_SEND:
// Check if ACK is received or not
if (!SSPCON2bits.ACKSTAT) {
// If an ACK is received, send first byte of data
SSPBUF = i2c_data_p->buffer_in[0];
i2c_data_p->operating_state = I2C_CHECK_ACK_RESTART;
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C_IDLE;
SSPCON2bits.PEN = 1;
i2c_data_p->master_status = I2C_MASTER_IDLE;
i2c_data_p->return_status = I2C_SEND_FAIL;
}
break;
case I2C_CHECK_ACK_RESTART:
if (!SSPCON2bits.ACKSTAT) {
SSPCON2bits.RSEN = 1;
i2c_data_p->operating_state = I2C_SEND_ADDR_2;
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C_IDLE;
SSPCON2bits.PEN = 1;
i2c_data_p->master_status = I2C_MASTER_IDLE;
i2c_data_p->return_status = I2C_SEND_FAIL;
}
break;
case I2C_SEND_ADDR_2:
// Send the address with read bit set
i2c_data_p->operating_state = I2C_CHECK_ACK_RECV;
SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x1;
break;
case I2C_CHECK_ACK_RECV:
// Check if ACK is received
if (!SSPCON2bits.ACKSTAT) {
// If an ACK is received, set module to receive 1 byte of data
i2c_data_p->operating_state = I2C_RCV_DATA;
SSPCON2bits.RCEN = 1;
} else {
// If a NACK is received, stop transmission and send error
i2c_data_p->operating_state = I2C_IDLE;
SSPCON2bits.PEN = 1;
i2c_data_p->master_status = I2C_MASTER_IDLE;
i2c_data_p->return_status = I2C_RECV_FAIL;
}
break;
case I2C_RCV_DATA:
// On receive, save byte into buffer
// TODO: handle i2c buffer overflow
i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = SSPBUF;
i2c_data_p->buffer_in_write_ind++;
if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
// If we still need to read, send an ACK to the slave
i2c_data_p->operating_state = I2C_REQ_DATA;
SSPCON2bits.ACKDT = 0; // ACK
SSPCON2bits.ACKEN = 1;
} else {
// If we are done reading, send an NACK to the slave
i2c_data_p->operating_state = I2C_SEND_STOP;
SSPCON2bits.ACKDT = 1; // NACK
SSPCON2bits.ACKEN = 1;
}
break;
case I2C_REQ_DATA:
// Set module to receive one byte of data
i2c_data_p->operating_state = I2C_RCV_DATA;
SSPCON2bits.RCEN = 1;
break;
case I2C_SEND_STOP:
// Send the stop bit and copy message to send to Main()
i2c_data_p->operating_state = I2C_IDLE;
SSPCON2bits.PEN = 1;
i2c_data_p->master_status = I2C_MASTER_IDLE;
i2c_data_p->return_status = I2C_RECV_OK;
break;
}
}
}
 
void I2C_Interrupt_Slave() {
unsigned char received_data;
unsigned char data_read_from_buffer = 0;
unsigned char data_written_to_buffer = 0;
unsigned char overrun_error = 0;
 
// Clear SSPOV (overflow bit)
if (SSPCON1bits.SSPOV == 1) {
DBG_PRINT_I2C("I2C: (ERROR) overflow detected\r\n");
SSPCON1bits.SSPOV = 0;
// We failed to read the buffer in time, so we know we
// can't properly receive this message, just put us in the
// a state where we are looking for a new message
i2c_data_p->operating_state = I2C_IDLE;
overrun_error = 1;
i2c_data_p->return_status = I2C_ERR_OVERRUN;
}
 
// Read SPPxBUF if it is full
if (SSPSTATbits.BF == 1) {
received_data = SSPBUF;
// DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF);
data_read_from_buffer = 1;
}
 
if (!overrun_error) {
switch (i2c_data_p->operating_state) {
case I2C_IDLE:
{
// Ignore anything except a start
if (SSPSTATbits.S == 1) {
i2c_data_p->buffer_in_len_tmp = 0;
i2c_data_p->operating_state = I2C_STARTED;
// if (data_read_from_buffer) {
// if (SSPSTATbits.D_A == 1) {
// DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n");
// // This is bad because we got data and we wanted an address
// i2c_data_p->operating_state = I2C_IDLE;
// i2c_data_p->return_status = I2C_ERR_NOADDR;
// } else {
// // Determine if we are sending or receiving data
// if (SSPSTATbits.R_W == 1) {
// i2c_data_p->operating_state = I2C_SEND_DATA;
// } else {
// i2c_data_p->operating_state = I2C_RCV_DATA;
// }
// }
// } else {
// i2c_data_p->operating_state = I2C_STARTED;
// }
}
break;
}
case I2C_STARTED:
{
// In this case, we expect either an address or a stop bit
if (SSPSTATbits.P == 1) {
// Return to idle mode
i2c_data_p->operating_state = I2C_IDLE;
} else if (data_read_from_buffer) {
if (SSPSTATbits.D_A == 0) {
// Address received
if (SSPSTATbits.R_W == 0) {
// Slave write mode
i2c_data_p->operating_state = I2C_RCV_DATA;
} else {
// Slave read mode
i2c_data_p->operating_state = I2C_SEND_DATA;
// Process the first byte immediatly if sending data
goto send;
}
} else {
DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
i2c_data_p->operating_state = I2C_IDLE;
i2c_data_p->return_status = I2C_ERR_NODATA;
}
}
break;
}
send:
case I2C_SEND_DATA:
{
if (!i2c_data_p->slave_sending_data) {
// If we are not currently sending data, figure out what to reply with
if (I2C_Process_Send(i2c_data_p->slave_in_last_byte)) {
// Data exists to be returned, send first byte
SSPBUF = i2c_data_p->buffer_out[0];
i2c_data_p->buffer_out_ind = 1;
i2c_data_p->slave_sending_data = 1;
data_written_to_buffer = 1;
} else {
// Unknown request
i2c_data_p->slave_sending_data = 0;
i2c_data_p->operating_state = I2C_IDLE;
}
} else {
// Sending remaining data back to master
if (i2c_data_p->buffer_out_ind < i2c_data_p->buffer_out_len) {
SSPBUF = i2c_data_p->buffer_out[i2c_data_p->buffer_out_ind];
i2c_data_p->buffer_out_ind++;
data_written_to_buffer = 1;
} else {
// Nothing left to send
i2c_data_p->slave_sending_data = 0;
i2c_data_p->operating_state = I2C_IDLE;
}
}
break;
}
case I2C_RCV_DATA:
{
// We expect either data or a stop bit or a (if a restart, an addr)
if (SSPSTATbits.P == 1) {
// Stop bit detected, we need to check to see if we also read data
if (data_read_from_buffer) {
if (SSPSTATbits.D_A == 1) {
// Data received with stop bit
// TODO: handle i2c buffer overflow
i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = received_data;
if (i2c_data_p->buffer_in_write_ind == MAXI2CBUF-1) {
i2c_data_p->buffer_in_write_ind = 0;
} else {
i2c_data_p->buffer_in_write_ind++;
}
i2c_data_p->buffer_in_len_tmp++;
// Save the last byte received
i2c_data_p->slave_in_last_byte = received_data;
i2c_data_p->return_status = I2C_DATA_AVAL;
} else {
DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
i2c_data_p->operating_state = I2C_IDLE;
i2c_data_p->return_status = I2C_ERR_NODATA;
}
}
i2c_data_p->buffer_in_len += i2c_data_p->buffer_in_len_tmp;
i2c_data_p->operating_state = I2C_IDLE;
} else if (data_read_from_buffer) {
if (SSPSTATbits.D_A == 1) {
// Data received
i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = received_data;
if (i2c_data_p->buffer_in_write_ind == MAXI2CBUF-1) {
i2c_data_p->buffer_in_write_ind = 0;
} else {
i2c_data_p->buffer_in_write_ind++;
}
i2c_data_p->buffer_in_len_tmp++;
// Save the last byte received
i2c_data_p->slave_in_last_byte = received_data;
i2c_data_p->return_status = I2C_DATA_AVAL;
} else {
// Restart bit detected
if (SSPSTATbits.R_W == 1) {
i2c_data_p->buffer_in_len += i2c_data_p->buffer_in_len_tmp;
i2c_data_p->operating_state = I2C_SEND_DATA;
// Process the first byte immediatly if sending data
goto send;
} else {
// Bad to recv an address again, we aren't ready
DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
i2c_data_p->operating_state = I2C_IDLE;
i2c_data_p->return_status = I2C_ERR_NODATA;
}
}
}
break;
}
}
}
 
// Release the clock stretching bit (if we should)
if (data_read_from_buffer || data_written_to_buffer) {
// Release the clock
if (SSPCON1bits.CKP == 0) {
SSPCON1bits.CKP = 1;
}
}
}
 
/* Returns 0 if I2C module is currently busy, otherwise returns status code */
unsigned char I2C_Get_Status() {
if (i2c_data_p->operating_mode == I2C_MODE_MASTER) {
if (i2c_data_p->master_status != I2C_MASTER_IDLE || i2c_data_p->buffer_in_len == 0) {
return 0;
} else {
return i2c_data_p->return_status;
}
} else if (i2c_data_p->operating_mode = I2C_MODE_SLAVE) {
if (i2c_data_p->operating_state != I2C_IDLE || i2c_data_p->buffer_in_len == 0) {
return 0;
} else {
return i2c_data_p->return_status;
}
}
}
 
unsigned char I2C_Buffer_Len() {
return i2c_data_p->buffer_in_len;
}
 
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
unsigned char I2C_Read_Buffer(char *buffer) {
unsigned char i = 0;
while (i2c_data_p->buffer_in_len != 0) {
buffer[i] = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
i++;
if (i2c_data_p->buffer_in_read_ind == MAXI2CBUF-1) {
i2c_data_p->buffer_in_read_ind = 0;
} else {
i2c_data_p->buffer_in_read_ind++;
}
i2c_data_p->buffer_in_len--;
}
return i;
}
 
/* Put data to be returned here */
unsigned char I2C_Process_Send(unsigned char c) {
unsigned char ret = 0;
switch (c) {
case 0xAA:
i2c_data_p->buffer_out[0] = 'A';
i2c_data_p->buffer_out_len = 1;
ret = 1;
break;
case 0xBB:
i2c_data_p->buffer_out[0] = '1';
i2c_data_p->buffer_out[1] = '2';
i2c_data_p->buffer_out_len = 2;
ret = 1;
break;
}
return ret;
}
/PIC Projects/PIC_27J13/oled_ssd1331.c
0,0 → 1,895
#include "defines.h"
#include "oled_ssd1331.h"
#include "spi.h"
#include "string.h"
#include "glcdfont.c"
#include <delays.h>
#include <string.h>
#include <stdio.h>
 
static SSD1331_DATA ssd1331_data;
static SSD1331_DATA *ssd1331_data_p = &ssd1331_data;
 
int SSD1331_Abs(int i) {
if (i < 0)
return -i;
else
return i;
}
 
void SSD1331_Swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
 
void SSD1331_Init() {
ssd1331_data_p->_width = ssd1331_data_p->WIDTH = SSD1331_LCDWIDTH;
ssd1331_data_p->_height = ssd1331_data_p->HEIGHT = SSD1331_LCDHEIGHT;
ssd1331_data_p->rotation = 0;
ssd1331_data_p->cursor_x = ssd1331_data_p->cursor_y = 0;
ssd1331_data_p->textsize = 1;
ssd1331_data_p->textcolor = ssd1331_data_p->textbgcolor = 0xFFFF;
ssd1331_data_p->wrap = 1;
}
 
void SSD1331_Begin() {
unsigned char buffer[37];
 
// Toggle reset pin
SPI_RESET_LAT = 0;
Delay10KTCYx(1);
SPI_RESET_LAT = 1;
 
// Initialization Sequence
buffer[0] = SSD1331_CMD_DISPLAYOFF; // 0xAE
buffer[1] = SSD1331_CMD_SETREMAP; // 0xA0
#if defined SSD1331_COLORORDER_RGB
buffer[2] = 0x72; // RGB Color
#else
buffer[2] = 0x76; // BGR Color
#endif
buffer[3] = SSD1331_CMD_STARTLINE; // 0xA1
buffer[4] = 0x0;
buffer[5] = SSD1331_CMD_DISPLAYOFFSET; // 0xA2
buffer[6] = 0x0;
buffer[7] = SSD1331_CMD_NORMALDISPLAY; // 0xA4
buffer[8] = SSD1331_CMD_SETMULTIPLEX; // 0xA8
buffer[9] = 0x3F; // 0x3F 1/64 duty
buffer[10] = SSD1331_CMD_SETMASTER; // 0xAD
buffer[11] = 0x8E;
buffer[12] = SSD1331_CMD_POWERMODE; // 0xB0
buffer[13] = 0x0B;
buffer[14] = SSD1331_CMD_PRECHARGE; // 0xB1
buffer[15] = 0x31;
buffer[16] = SSD1331_CMD_CLOCKDIV; // 0xB3
buffer[17] = 0xF0; // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
buffer[18] = SSD1331_CMD_PRECHARGEA; // 0x8A
buffer[19] = 0x64;
buffer[20] = SSD1331_CMD_PRECHARGEB; // 0x8B
buffer[21] = 0x78;
buffer[22] = SSD1331_CMD_PRECHARGEA; // 0x8C
buffer[23] = 0x64;
buffer[24] = SSD1331_CMD_PRECHARGELEVEL; // 0xBB
buffer[25] = 0x3A;
buffer[26] = SSD1331_CMD_VCOMH; // 0xBE
buffer[27] = 0x3E;
buffer[28] = SSD1331_CMD_MASTERCURRENT; // 0x87
buffer[29] = 0x06;
buffer[30] = SSD1331_CMD_CONTRASTA; // 0x81
buffer[31] = 0x91;
buffer[32] = SSD1331_CMD_CONTRASTB; // 0x82
buffer[33] = 0x50;
buffer[34] = SSD1331_CMD_CONTRASTC; // 0x83
buffer[35] = 0x7D;
buffer[36] = SSD1331_CMD_DISPLAYON; //--turn on oled panel
 
SPI_DC_SELECT_LAT = 0; // D/C low (cmd)
SPI2_Write(buffer, 37);
}
 
void SSD1331_GoTo(int x, int y) {
unsigned char buffer[6];
if ((x >= SSD1331_LCDWIDTH) || (y >= SSD1331_LCDHEIGHT)) return;
 
// set x and y coordinate
buffer[0] = (SSD1331_CMD_SETCOLUMN);
buffer[1] = (x); // Start x address
buffer[2] = (SSD1331_LCDWIDTH - 1); // End x address
 
buffer[3] = (SSD1331_CMD_SETROW);
buffer[4] = (y); // Start y address
buffer[5] = (SSD1331_LCDHEIGHT - 1); // End y address
 
SPI_DC_SELECT_LAT = 0; // D/C low (cmd)
SPI2_Write(buffer, 6);
}
 
void SSD1331_Command(unsigned char cmd) {
SPI_DC_SELECT_LAT = 0; // D/C low (cmd)
SPI2_Write(&cmd, 1);
}
 
void SSD1331_Data(unsigned char data) {
SPI_DC_SELECT_LAT = 1; // D/C high (data)
SPI2_Write(&data, 1);
}
 
void SSD1331_Clear_Display() {
unsigned char buffer[5];
 
buffer[0] = SSD1331_CMD_CLEARWINDOW;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = SSD1331_LCDWIDTH-1;
buffer[4] = SSD1331_LCDHEIGHT-1;
 
SPI_DC_SELECT_LAT = 0; // D/C low (cmd)
SPI2_Write(buffer, 5);
 
Delay1KTCYx(4);
}
 
void SSD1331_Draw_Pixel(int x, int y, unsigned int color) {
unsigned char buffer[2];
buffer[0] = color >> 8;
buffer[1] = color;
if ((x < 0) || (x >= ssd1331_data_p->_width) || (y < 0) || (y >= ssd1331_data_p->_height)) return;
 
// check rotation, move pixel around if necessary
switch (ssd1331_data_p->rotation) {
case 1:
SSD1331_Swap(&x, &y);
x = SSD1331_LCDWIDTH - x - 1;
break;
case 2:
x = SSD1331_LCDWIDTH - x - 1;
y = SSD1331_LCDHEIGHT - y - 1;
break;
case 3:
SSD1331_Swap(&x, &y);
y = SSD1331_LCDHEIGHT - y - 1;
break;
}
 
SSD1331_GoTo(x, y);
 
// setup for data
SPI_DC_SELECT_LAT = 1; // D/C high (data)
 
SPI2_Write(buffer, 2);
}
 
void SSD1331_Draw_Line(int x0, int y0, int x1, int y1, unsigned int color) {
unsigned char buffer[8];
 
// check rotation, move pixel around if necessary
switch (ssd1331_data_p->rotation) {
case 1:
SSD1331_Swap(&x0, &y0);
SSD1331_Swap(&x1, &y1);
x0 = SSD1331_LCDWIDTH - x0 - 1;
x1 = SSD1331_LCDWIDTH - x1 - 1;
break;
case 2:
x0 = SSD1331_LCDWIDTH - x0 - 1;
y0 = SSD1331_LCDHEIGHT - y0 - 1;
x1 = SSD1331_LCDWIDTH - x1 - 1;
y1 = SSD1331_LCDHEIGHT - y1 - 1;
break;
case 3:
SSD1331_Swap(&x0, &y0);
SSD1331_Swap(&x1, &y1);
y0 = SSD1331_LCDHEIGHT - y0 - 1;
y1 = SSD1331_LCDHEIGHT - y1 - 1;
break;
}
 
// Boundary check
if ((y0 >= SSD1331_LCDHEIGHT) && (y1 >= SSD1331_LCDHEIGHT))
return;
if ((x0 >= SSD1331_LCDWIDTH) && (x1 >= SSD1331_LCDWIDTH))
return;
if (x0 >= SSD1331_LCDWIDTH)
x0 = SSD1331_LCDWIDTH - 1;
if (y0 >= SSD1331_LCDHEIGHT)
y0 = SSD1331_LCDHEIGHT - 1;
if (x1 >= SSD1331_LCDWIDTH)
x1 = SSD1331_LCDWIDTH - 1;
if (y1 >= SSD1331_LCDHEIGHT)
y1 = SSD1331_LCDHEIGHT - 1;
if (x0 < 0)
x0 = 0;
if (y0 < 0)
y0 = 0;
if (x1 < 0)
x1 = 0;
if (y1 < 0)
y1 = 0;
 
buffer[0] = SSD1331_CMD_DRAWLINE;
buffer[1] = x0;
buffer[2] = y0;
buffer[3] = x1;
buffer[4] = y1;
buffer[5] = (color >> 11) << 1;
buffer[6] = (color >> 5) & 0x3F;
buffer[7] = (color << 1) & 0x3F;
 
SPI_DC_SELECT_LAT = 0; // D/C low (cmd)
SPI2_Write(buffer, 8);
}
 
void SSD1331_Draw_Fast_VLine(int x, int y, int h, unsigned int color) {
SSD1331_Draw_Line(x, y, x, y + h - 1, color);
}
 
void SSD1331_Draw_Fast_HLine(int x, int y, int w, unsigned int color) {
SSD1331_Draw_Line(x, y, x + w - 1, y, color);
}
 
void SSD1331_Draw_Rect(int tx0, int ty0, int tx1, int ty1, unsigned int color) {
unsigned char buffer[13];
int x0,y0,x1,y1;
// check rotation, move pixel around if necessary
switch (ssd1331_data_p->rotation) {
case 0:
x0 = tx0;
y0 = ty0;
x1 = tx1;
y1 = ty1;
break;
case 1:
x0 = SSD1331_LCDWIDTH - ty1 - 1;
y0 = tx0;
x1 = SSD1331_LCDWIDTH - ty0 - 1;
y1 = tx1;
break;
case 2:
x0 = SSD1331_LCDWIDTH - tx1 - 1;
y0 = SSD1331_LCDHEIGHT - ty1 - 1;
x1 = SSD1331_LCDWIDTH - tx0 - 1;
y1 = SSD1331_LCDHEIGHT - ty0 - 1;
break;
case 3:
x0 = ty0;
y0 = SSD1331_LCDHEIGHT - tx1 - 1;
x1 = ty1;
y1 = SSD1331_LCDHEIGHT - tx0 - 1;
break;
}
 
// Boundary check
if ((y0 >= SSD1331_LCDHEIGHT) && (y1 >= SSD1331_LCDHEIGHT))
return;
if ((x0 >= SSD1331_LCDWIDTH) && (x1 >= SSD1331_LCDWIDTH))
return;
if (x0 >= SSD1331_LCDWIDTH)
x0 = SSD1331_LCDWIDTH - 1;
if (y0 >= SSD1331_LCDHEIGHT)
y0 = SSD1331_LCDHEIGHT - 1;
if (x1 >= SSD1331_LCDWIDTH)
x1 = SSD1331_LCDWIDTH - 1;
if (y1 >= SSD1331_LCDHEIGHT)
y1 = SSD1331_LCDHEIGHT - 1;
if (x0 < 0)
x0 = 0;
if (y0 < 0)
y0 = 0;
if (x1 < 0)
x1 = 0;
if (y1 < 0)
y1 = 0;
 
buffer[0] = SSD1331_CMD_FILL;
buffer[1] = 0;
buffer[2] = SSD1331_CMD_DRAWRECT;
buffer[3] = x0;
buffer[4] = y0;
buffer[5] = x1;
buffer[6] = y1;
buffer[7] = (color >> 11) << 1;
buffer[8] = (color >> 5) & 0x3F;
buffer[9] = (color << 1) & 0x3F;
buffer[10] = 0;
buffer[11] = 0;
buffer[12] = 0;
 
SPI_DC_SELECT_LAT = 0; // D/C low (cmd)
SPI2_Write(buffer, 13);
}
 
void SSD1331_Fill_Rect(int tx0, int ty0, int tx1, int ty1, unsigned int color) {
unsigned char buffer[13];
int x0,y0,x1,y1;
// check rotation, move pixel around if necessary
switch (ssd1331_data_p->rotation) {
case 0:
x0 = tx0;
y0 = ty0;
x1 = tx1;
y1 = ty1;
break;
case 1:
x0 = SSD1331_LCDWIDTH - ty1 - 1;
y0 = tx0;
x1 = SSD1331_LCDWIDTH - ty0 - 1;
y1 = tx1;
break;
case 2:
x0 = SSD1331_LCDWIDTH - tx1 - 1;
y0 = SSD1331_LCDHEIGHT - ty1 - 1;
x1 = SSD1331_LCDWIDTH - tx0 - 1;
y1 = SSD1331_LCDHEIGHT - ty0 - 1;
break;
case 3:
x0 = ty0;
y0 = SSD1331_LCDHEIGHT - tx1 - 1;
x1 = ty1;
y1 = SSD1331_LCDHEIGHT - tx0 - 1;
break;
}
 
// Boundary check
if ((y0 >= SSD1331_LCDHEIGHT) && (y1 >= SSD1331_LCDHEIGHT))
return;
if ((x0 >= SSD1331_LCDWIDTH) && (x1 >= SSD1331_LCDWIDTH))
return;
if (x0 >= SSD1331_LCDWIDTH)
x0 = SSD1331_LCDWIDTH - 1;
if (y0 >= SSD1331_LCDHEIGHT)
y0 = SSD1331_LCDHEIGHT - 1;
if (x1 >= SSD1331_LCDWIDTH)
x1 = SSD1331_LCDWIDTH - 1;
if (y1 >= SSD1331_LCDHEIGHT)
y1 = SSD1331_LCDHEIGHT - 1;
if (x0 < 0)
x0 = 0;
if (y0 < 0)
y0 = 0;
if (x1 < 0)
x1 = 0;
if (y1 < 0)
y1 = 0;
 
buffer[0] = SSD1331_CMD_FILL;
buffer[1] = 1;
buffer[2] = SSD1331_CMD_DRAWRECT;
buffer[3] = x0;
buffer[4] = y0;
buffer[5] = x1;
buffer[6] = y1;
buffer[7] = (color >> 11) << 1;
buffer[8] = (color >> 5) & 0x3F;
buffer[9] = (color << 1) & 0x3F;
buffer[10] = (color >> 11) << 1;
buffer[11] = (color >> 5) & 0x3F;
buffer[12] = (color << 1) & 0x3F;
 
SPI_DC_SELECT_LAT = 0; // D/C low (cmd)
SPI2_Write(buffer, 13);
 
Delay1KTCYx(4);
}
 
void SSD1331_Draw_Circle(int x0, int y0, int r, unsigned int color) {
int f = 1 - r;
int ddF_x = 1;
int ddF_y = -2 * r;
int x = 0;
int y = r;
 
SSD1331_Draw_Pixel(x0, y0 + r, color);
SSD1331_Draw_Pixel(x0, y0 - r, color);
SSD1331_Draw_Pixel(x0 + r, y0, color);
SSD1331_Draw_Pixel(x0 - r, y0, color);
 
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
 
SSD1331_Draw_Pixel(x0 + x, y0 + y, color);
SSD1331_Draw_Pixel(x0 - x, y0 + y, color);
SSD1331_Draw_Pixel(x0 + x, y0 - y, color);
SSD1331_Draw_Pixel(x0 - x, y0 - y, color);
SSD1331_Draw_Pixel(x0 + y, y0 + x, color);
SSD1331_Draw_Pixel(x0 - y, y0 + x, color);
SSD1331_Draw_Pixel(x0 + y, y0 - x, color);
SSD1331_Draw_Pixel(x0 - y, y0 - x, color);
}
}
 
void SSD1331_Draw_Circle_Helper(int x0, int y0, int r, unsigned char cornername, unsigned int color) {
int f = 1 - r;
int ddF_x = 1;
int ddF_y = -2 * r;
int x = 0;
int y = r;
 
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
if (cornername & 0x4) {
SSD1331_Draw_Pixel(x0 + x, y0 + y, color);
SSD1331_Draw_Pixel(x0 + y, y0 + x, color);
}
if (cornername & 0x2) {
SSD1331_Draw_Pixel(x0 + x, y0 - y, color);
SSD1331_Draw_Pixel(x0 + y, y0 - x, color);
}
if (cornername & 0x8) {
SSD1331_Draw_Pixel(x0 - y, y0 + x, color);
SSD1331_Draw_Pixel(x0 - x, y0 + y, color);
}
if (cornername & 0x1) {
SSD1331_Draw_Pixel(x0 - y, y0 - x, color);
SSD1331_Draw_Pixel(x0 - x, y0 - y, color);
}
}
}
 
void SSD1331_Fill_Circle(int x0, int y0, int r, unsigned int color) {
SSD1331_Draw_Fast_VLine(x0, y0 - r, 2 * r + 1, color);
SSD1331_Fill_Circle_Helper(x0, y0, r, 3, 0, color);
}
 
void SSD1331_Fill_Circle_Helper(int x0, int y0, int r, unsigned char cornername, int delta, unsigned int color) {
int f = 1 - r;
int ddF_x = 1;
int ddF_y = -2 * r;
int x = 0;
int y = r;
 
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
 
if (cornername & 0x1) {
SSD1331_Draw_Fast_VLine(x0 + x, y0 - y, 2 * y + 1 + delta, color);
SSD1331_Draw_Fast_VLine(x0 + y, y0 - x, 2 * x + 1 + delta, color);
}
if (cornername & 0x2) {
SSD1331_Draw_Fast_VLine(x0 - x, y0 - y, 2 * y + 1 + delta, color);
SSD1331_Draw_Fast_VLine(x0 - y, y0 - x, 2 * x + 1 + delta, color);
}
}
}
void SSD1331_Draw_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {
SSD1331_Draw_Line(x0, y0, x1, y1, color);
SSD1331_Draw_Line(x1, y1, x2, y2, color);
SSD1331_Draw_Line(x2, y2, x0, y0, color);
}
 
void SSD1331_Fill_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {
int a, b, y, last;
int dx01 = x1 - x0;
int dy01 = y1 - y0;
int dx02 = x2 - x0;
int dy02 = y2 - y0;
int dx12 = x2 - x1;
int dy12 = y2 - y1;
int sa = 0;
int sb = 0;
 
// Sort coordinates by Y order (y2 >= y1 >= y0)
if (y0 > y1) {
SSD1331_Swap(&y0, &y1);
SSD1331_Swap(&x0, &x1);
}
if (y1 > y2) {
SSD1331_Swap(&y2, &y1);
SSD1331_Swap(&x2, &x1);
}
if (y0 > y1) {
SSD1331_Swap(&y0, &y1);
SSD1331_Swap(&x0, &x1);
}
 
if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
a = b = x0;
if (x1 < a) a = x1;
else if (x1 > b) b = x1;
if (x2 < a) a = x2;
else if (x2 > b) b = x2;
SSD1331_Draw_Fast_HLine(a, y0, b - a + 1, color);
return;
}
 
// For upper part of triangle, find scanline crossings for segments
// 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
// is included here (and second loop will be skipped, avoiding a /0
// error there), otherwise scanline y1 is skipped here and handled
// in the second loop...which also avoids a /0 error here if y0=y1
// (flat-topped triangle).
if (y1 == y2) last = y1; // Include y1 scanline
else last = y1 - 1; // Skip it
 
for (y = y0; y <= last; y++) {
a = x0 + sa / dy01;
b = x0 + sb / dy02;
sa += dx01;
sb += dx02;
/* longhand:
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if (a > b) SSD1331_Swap(&a, &b);
SSD1331_Draw_Fast_HLine(a, y, b - a + 1, color);
}
 
// For lower part of triangle, find scanline crossings for segments
// 0-2 and 1-2. This loop is skipped if y1=y2.
sa = dx12 * (y - y1);
sb = dx02 * (y - y0);
for (; y <= y2; y++) {
a = x1 + sa / dy12;
b = x0 + sb / dy02;
sa += dx12;
sb += dx02;
/* longhand:
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if (a > b) SSD1331_Swap(&a, &b);
SSD1331_Draw_Fast_HLine(a, y, b - a + 1, color);
}
}
 
void SSD1331_Draw_Round_Rect(int x, int y, int w, int h, int r, unsigned int color) {
// smarter version
SSD1331_Draw_Fast_HLine(x + r, y, w - 2 * r, color); // Top
SSD1331_Draw_Fast_HLine(x + r, y + h - 1, w - 2 * r, color); // Bottom
SSD1331_Draw_Fast_VLine(x, y + r, h - 2 * r, color); // Left
SSD1331_Draw_Fast_VLine(x + w - 1, y + r, h - 2 * r, color); // Right
 
// draw four corners
SSD1331_Draw_Circle_Helper(x + r, y + r, r, 1, color);
SSD1331_Draw_Circle_Helper(x + w - r - 1, y + r, r, 2, color);
SSD1331_Draw_Circle_Helper(x + w - r - 1, y + h - r - 1, r, 4, color);
SSD1331_Draw_Circle_Helper(x + r, y + h - r - 1, r, 8, color);
}
 
void SSD1331_Fill_Round_Rect(int x, int y, int w, int h, int r, unsigned int color) {
// smarter version
SSD1331_Fill_Rect(x + r, y, w - 2 * r, h, color);
 
// draw four corners
SSD1331_Fill_Circle_Helper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);
SSD1331_Fill_Circle_Helper(x + r, y + r, r, 2, h - 2 * r - 1, color);
}
 
void SSD1331_Draw_Bitmap(int x, int y, const unsigned char* bitmap, int w, int h, unsigned int color) {
int i, j;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
if (bitmap[i + (j / 8) * w] & (j % 8)) {
SSD1331_Draw_Pixel(x + i, y + j, color);
}
}
}
}
 
void SSD1331_Draw_Char(int x, int y, unsigned char c, unsigned int color, unsigned int bg, unsigned char size) {
int i, j;
unsigned int line;
 
if ((x >= ssd1331_data_p->_width) || // Clip right
(y >= ssd1331_data_p->_height) || // Clip bottom
((x + 5 * size - 1) < 0) || // Clip left
((y + 8 * size - 1) < 0)) // Clip top
return;
 
for (i = 0; i < 6; i++) {
if (i == 5)
line = 0x0;
else
line = font[(c * 5) + i];
for (j = 0; j < 8; j++) {
if (line & 0x1) {
if (size == 1) {// default size
SSD1331_Draw_Pixel(x + i, y + j, color);
} else { // big size
SSD1331_Fill_Rect(x + (i * size), y + (j * size), size, size, color);
}
} else if (bg != color) {
if (size == 1) { // default size
SSD1331_Draw_Pixel(x + i, y + j, bg);
} else { // big size
SSD1331_Fill_Rect(x + i*size, y + j*size, size, size, bg);
}
}
line >>= 1;
}
}
}
 
void SSD1331_Write(unsigned char c) {
if (c == '\n' || c == '\r') {
ssd1331_data_p->cursor_y += ssd1331_data_p->textsize * 8;
ssd1331_data_p->cursor_x = 0;
// } else if (c == '\r') {
// // skip em
} else {
SSD1331_Draw_Char(ssd1331_data_p->cursor_x, ssd1331_data_p->cursor_y, c, ssd1331_data_p->textcolor, ssd1331_data_p->textbgcolor, ssd1331_data_p->textsize);
ssd1331_data_p->cursor_x += ssd1331_data_p->textsize * 6;
if (ssd1331_data_p->wrap && (ssd1331_data_p->cursor_x > (ssd1331_data_p->_width - ssd1331_data_p->textsize * 6))) {
ssd1331_data_p->cursor_y += ssd1331_data_p->textsize * 8;
ssd1331_data_p->cursor_x = 0;
}
}
}
 
void SSD1331_Write_String(const rom char *fmt, ...) {
unsigned char i, len;
unsigned char buffer[SSD1331_STRING_BUFFER_SIZE];
// Parse and create string
va_list args;
va_start(args, fmt);
vsprintf((char *) buffer, fmt, args);
va_end(args);
len = strlen((char *) buffer);
 
// Make sure string to insert fits in buffer, truncate if necessary
if (len > SSD1331_STRING_BUFFER_SIZE)
len = SSD1331_STRING_BUFFER_SIZE;
 
// Print buffer to string
for (i = 0; i < len; i++) {
SSD1331_Write(buffer[i]);
}
}
 
void SSD1331_Set_Cursor(int x, int y) {
ssd1331_data_p->cursor_x = x;
ssd1331_data_p->cursor_y = y;
}
 
void SSD1331_Set_Text_Color(unsigned int c) {
// for 'transparent' background, we'll set the bg
// to the same as fg instead of using a flag
ssd1331_data_p->textcolor = c;
ssd1331_data_p->textbgcolor = c;
}
 
void SSD1331_Set_Text_Color_BG(unsigned int c, unsigned int bg) {
ssd1331_data_p->textcolor = c;
ssd1331_data_p->textbgcolor = bg;
}
 
void SSD1331_Set_Text_Size(unsigned char s) {
ssd1331_data_p->textsize = (s > 0) ? s : 1;
}
 
void SSD1331_Set_Text_Wrap(unsigned char w) {
ssd1331_data_p->wrap = w;
}
 
void SSD1331_Set_Rotation(unsigned char x) {
x %= 4; // cant be higher than 3
ssd1331_data_p->rotation = x;
switch (x) {
case 0:
case 2:
ssd1331_data_p->_width = ssd1331_data_p->WIDTH;
ssd1331_data_p->_height = ssd1331_data_p->HEIGHT;
break;
case 1:
case 3:
ssd1331_data_p->_width = ssd1331_data_p->HEIGHT;
ssd1331_data_p->_height = ssd1331_data_p->WIDTH;
break;
}
}
 
unsigned int SSD1331_Color565(unsigned char r, unsigned char g, unsigned char b) {
unsigned int c;
c = r >> 3;
c <<= 6;
c |= g >> 2;
c <<= 5;
c |= b >> 3;
 
return c;
}
 
void SSD1331_Test_DrawLines(unsigned int color) {
int x, y;
SSD1331_Clear_Display();
for (x = 0; x < ssd1331_data_p->_width - 1; x += 6) {
SSD1331_Draw_Line(0, 0, x, ssd1331_data_p->_height - 1, color);
}
for (y = 0; y < ssd1331_data_p->_height - 1; y += 6) {
SSD1331_Draw_Line(0, 0, ssd1331_data_p->_width - 1, y, color);
}
 
SSD1331_Clear_Display();
for (x = 0; x < ssd1331_data_p->_width - 1; x += 6) {
SSD1331_Draw_Line(ssd1331_data_p->_width - 1, 0, x, ssd1331_data_p->_height - 1, color);
}
for (y = 0; y < ssd1331_data_p->_height - 1; y += 6) {
SSD1331_Draw_Line(ssd1331_data_p->_width - 1, 0, 0, y, color);
}
 
SSD1331_Clear_Display();
for (x = 0; x < ssd1331_data_p->_width - 1; x += 6) {
SSD1331_Draw_Line(0, ssd1331_data_p->_height - 1, x, 0, color);
}
for (y = 0; y < ssd1331_data_p->_height - 1; y += 6) {
SSD1331_Draw_Line(0, ssd1331_data_p->_height - 1, ssd1331_data_p->_width - 1, y, color);
}
 
SSD1331_Clear_Display();
for (x = 0; x < ssd1331_data_p->_width - 1; x += 6) {
SSD1331_Draw_Line(ssd1331_data_p->_width - 1, ssd1331_data_p->_height - 1, x, 0, color);
}
for (y = 0; y < ssd1331_data_p->_height - 1; y += 6) {
SSD1331_Draw_Line(ssd1331_data_p->_width - 1, ssd1331_data_p->_height - 1, 0, y, color);
}
}
 
void SSD1331_Test_DrawRect(unsigned int color) {
int x;
SSD1331_Clear_Display();
if (ssd1331_data_p->_height < ssd1331_data_p->_width) {
for (x = 0; x < ssd1331_data_p->_height - 1; x += 6) {
SSD1331_Draw_Rect((ssd1331_data_p->_width - 1) / 2 - x / 2, (ssd1331_data_p->_height - 1) / 2 - x / 2, x, x, color);
}
} else {
for (x = 0; x < ssd1331_data_p->_width - 1; x += 6) {
SSD1331_Draw_Rect((ssd1331_data_p->_width - 1) / 2 - x / 2, (ssd1331_data_p->_height - 1) / 2 - x / 2, x, x, color);
}
}
}
 
void SSD1331_Test_FillRect(unsigned int color1, unsigned int color2) {
int x;
SSD1331_Clear_Display();
if (ssd1331_data_p->_height < ssd1331_data_p->_width) {
for (x = ssd1331_data_p->_height - 1; x > 6; x -= 6) {
SSD1331_Fill_Rect((ssd1331_data_p->_width - 1) / 2 - x / 2, (ssd1331_data_p->_height - 1) / 2 - x / 2, x, x, color1);
SSD1331_Draw_Rect((ssd1331_data_p->_width - 1) / 2 - x / 2, (ssd1331_data_p->_height - 1) / 2 - x / 2, x, x, color2);
}
} else {
for (x = ssd1331_data_p->_width - 1; x > 6; x -= 6) {
SSD1331_Fill_Rect((ssd1331_data_p->_width - 1) / 2 - x / 2, (ssd1331_data_p->_height - 1) / 2 - x / 2, x, x, color1);
SSD1331_Draw_Rect((ssd1331_data_p->_width - 1) / 2 - x / 2, (ssd1331_data_p->_height - 1) / 2 - x / 2, x, x, color2);
}
}
}
 
void SSD1331_Test_DrawCircle(unsigned int radius, unsigned int color) {
int x, y;
for (x = 0; x < ssd1331_data_p->_width - 1 + radius; x += radius * 2) {
for (y = 0; y < ssd1331_data_p->_height - 1 + radius; y += radius * 2) {
SSD1331_Draw_Circle(x, y, radius, color);
}
}
}
 
void SSD1331_Test_FillCircle(unsigned int radius, unsigned int color) {
unsigned char x, y;
for (x = radius; x < ssd1331_data_p->_width - 1; x += radius * 2) {
for (y = radius; y < ssd1331_data_p->_height - 1; y += radius * 2) {
SSD1331_Fill_Circle(x, y, radius, color);
}
}
}
 
void SSD1331_Test_DrawTria(void) {
int color = 0xF800;
int t;
int w = ssd1331_data_p->_width / 2;
int x = ssd1331_data_p->_height;
int y = 0;
int z = ssd1331_data_p->_width;
SSD1331_Clear_Display();
for (t = 0; t <= 15; t += 1) {
SSD1331_Draw_Triangle(w, y, y, x, z, x, color);
x -= 4;
y += 4;
z -= 4;
color += 100;
}
}
 
void SSD1331_Test_DrawRoundRect(void) {
int color = 100;
int i, t, x, y, w, h;
SSD1331_Clear_Display();
for (t = 0; t <= 4; t += 1) {
x = 0;
y = 0;
w = ssd1331_data_p->_width;
h = ssd1331_data_p->_height;
for (i = 0; i <= 24; i += 1) {
SSD1331_Draw_Round_Rect(x, y, w, h, 5, color);
x += 2;
y += 3;
w -= 4;
h -= 6;
color += 1100;
}
color += 100;
}
}
 
void SSD1331_Test_MediaButtons(void) {
// play
SSD1331_Clear_Display();
SSD1331_Fill_Round_Rect(25, 10, 78, 60, 8, SSD1331_WHITE);
SSD1331_Fill_Triangle(42, 20, 42, 60, 90, 40, SSD1331_RED);
Delay10KTCYx(100);
// pause
SSD1331_Fill_Round_Rect(25, 90, 78, 60, 8, SSD1331_WHITE);
SSD1331_Fill_Round_Rect(39, 98, 20, 45, 5, SSD1331_GREEN);
SSD1331_Fill_Round_Rect(69, 98, 20, 45, 5, SSD1331_GREEN);
Delay10KTCYx(100);
// play color
SSD1331_Fill_Triangle(42, 20, 42, 60, 90, 40, SSD1331_BLUE);
Delay10KTCYx(100);
// pause color
SSD1331_Fill_Round_Rect(39, 98, 20, 45, 5, SSD1331_RED);
SSD1331_Fill_Round_Rect(69, 98, 20, 45, 5, SSD1331_RED);
// play color
SSD1331_Fill_Triangle(42, 20, 42, 60, 90, 40, SSD1331_GREEN);
}
 
void SSD1331_Test_Pattern(void) {
unsigned char buffer[2];
unsigned int i, j;
SSD1331_GoTo(0, 0);
 
for (i = 0; i < 64; i++) {
for (j = 0; j < 96; j++) {
if (i > 55) {
buffer[0] = (SSD1331_WHITE >> 8);
buffer[1] = (SSD1331_WHITE);
} else if (i > 47) {
buffer[0] = (SSD1331_BLUE >> 8);
buffer[1] = (SSD1331_BLUE);
} else if (i > 39) {
buffer[0] = (SSD1331_GREEN >> 8);
buffer[1] = (SSD1331_GREEN);
} else if (i > 31) {
buffer[0] = (SSD1331_CYAN >> 8);
buffer[1] = (SSD1331_CYAN);
} else if (i > 23) {
buffer[0] = (SSD1331_RED >> 8);
buffer[1] = (SSD1331_RED);
} else if (i > 15) {
buffer[0] = (SSD1331_MAGENTA >> 8);
buffer[1] = (SSD1331_MAGENTA);
} else if (i > 7) {
buffer[0] = (SSD1331_YELLOW >> 8);
buffer[1] = (SSD1331_YELLOW);
} else {
buffer[0] = (SSD1331_BLACK >> 8);
buffer[1] = (SSD1331_BLACK);
}
SPI_DC_SELECT_LAT = 1; // D/C high (data)
SPI2_Write(buffer, 2);
}
}
}
/PIC Projects/PIC_27J13/oled_ssd1331.h
0,0 → 1,122
#ifndef OLED_SSD1331_H
#define OLED_SSD1331_H
 
#define SSD1331_LCDWIDTH 96
#define SSD1331_LCDHEIGHT 64
#define SSD1331_STRING_BUFFER_SIZE 64
 
// Select one of these defines to set the pixel color order
#define SSD1331_COLORORDER_RGB
// #define SSD1331_COLORORDER_BGR
 
// SSD1331 Commands
#define SSD1331_CMD_DRAWLINE 0x21
#define SSD1331_CMD_DRAWRECT 0x22
#define SSD1331_CMD_CLEARWINDOW 0x25
#define SSD1331_CMD_FILL 0x26
#define SSD1331_CMD_SETCOLUMN 0x15
#define SSD1331_CMD_SETROW 0x75
#define SSD1331_CMD_CONTRASTA 0x81
#define SSD1331_CMD_CONTRASTB 0x82
#define SSD1331_CMD_CONTRASTC 0x83
#define SSD1331_CMD_MASTERCURRENT 0x87
#define SSD1331_CMD_SETREMAP 0xA0
#define SSD1331_CMD_STARTLINE 0xA1
#define SSD1331_CMD_DISPLAYOFFSET 0xA2
#define SSD1331_CMD_NORMALDISPLAY 0xA4
#define SSD1331_CMD_DISPLAYALLON 0xA5
#define SSD1331_CMD_DISPLAYALLOFF 0xA6
#define SSD1331_CMD_INVERTDISPLAY 0xA7
#define SSD1331_CMD_SETMULTIPLEX 0xA8
#define SSD1331_CMD_SETMASTER 0xAD
#define SSD1331_CMD_DISPLAYOFF 0xAE
#define SSD1331_CMD_DISPLAYON 0xAF
#define SSD1331_CMD_POWERMODE 0xB0
#define SSD1331_CMD_PRECHARGE 0xB1
#define SSD1331_CMD_CLOCKDIV 0xB3
#define SSD1331_CMD_PRECHARGEA 0x8A
#define SSD1331_CMD_PRECHARGEB 0x8B
#define SSD1331_CMD_PRECHARGEC 0x8C
#define SSD1331_CMD_PRECHARGELEVEL 0xBB
#define SSD1331_CMD_VCOMH 0xBE
 
// Color definitions
#define SSD1331_BLACK 0x0000
#define SSD1331_BLUE 0x001F
#define SSD1331_RED 0xF800
#define SSD1331_GREEN 0x07E0
#define SSD1331_CYAN 0x07FF
#define SSD1331_MAGENTA 0xF81F
#define SSD1331_YELLOW 0xFFE0
#define SSD1331_WHITE 0xFFFF
 
typedef struct __SSD1331_DATA {
int WIDTH, HEIGHT; // raw display size
int _width, _height; // size depending on rotation
int cursor_x, cursor_y;
unsigned int textcolor, textbgcolor;
unsigned char textsize;
unsigned char rotation;
unsigned char wrap; // If set, wrap text at right side
} SSD1331_DATA;
 
// Misc functions
int SSD1331_Abs(int i);
void SSD1331_Swap(int *a, int *b);
unsigned int SSD1331_Color565(unsigned char r, unsigned char g, unsigned char b);
 
// Core functions
void SSD1331_Init(void);
void SSD1331_Begin(void);
void SSD1331_GoTo(int x, int y);
 
void SSD1331_Command(unsigned char c);
void SSD1331_Data(unsigned char d);
 
// Display functions
void SSD1331_Clear_Display(void);
 
void SSD1331_Draw_Pixel(int x, int y, unsigned int color);
void SSD1331_Draw_Line(int x0, int y0, int x1, int y1, unsigned int color);
void SSD1331_Draw_Fast_VLine(int x, int y, int h, unsigned int color);
void SSD1331_Draw_Fast_HLine(int x, int y, int w, unsigned int color);
void SSD1331_Draw_Rect(int x0, int y0, int x1, int y1, unsigned int color);
void SSD1331_Fill_Rect(int x0, int y0, int x1, int y1, unsigned int color);
 
void SSD1331_Draw_Circle(int x0, int y0, int r, unsigned int color);
void SSD1331_Draw_Circle_Helper(int x0, int y0, int r, unsigned char cornername, unsigned int color);
void SSD1331_Fill_Circle(int x0, int y0, int r, unsigned int color);
void SSD1331_Fill_Circle_Helper(int x0, int y0, int r, unsigned char cornername, int delta, unsigned int color);
 
void SSD1331_Draw_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color);
void SSD1331_Fill_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color);
void SSD1331_Draw_Round_Rect(int x0, int y0, int w, int h, int radius, unsigned int color);
void SSD1331_Fill_Round_Rect(int x0, int y0, int w, int h, int radius, unsigned int color);
 
void SSD1331_Draw_Bitmap(int x, int y, const unsigned char *bitmap, int w, int h, unsigned int color);
void SSD1331_Draw_Char(int x, int y, unsigned char c, unsigned int color, unsigned int bg, unsigned char size);
 
void SSD1331_Write(unsigned char c);
void SSD1331_Write_String(const rom char *fmt, ...);
//void SSD1331_Append_String(const rom char *fmt, ...);
 
void SSD1331_Set_Cursor(int x, int y);
void SSD1331_Set_Text_Color(unsigned int c);
void SSD1331_Set_Text_Color_BG(unsigned int c, unsigned int bg);
void SSD1331_Set_Text_Size(unsigned char s);
void SSD1331_Set_Text_Wrap(unsigned char w);
void SSD1331_Set_Rotation(unsigned char r);
 
// Test functions
void SSD1331_Test_DrawLines(unsigned int color);
void SSD1331_Test_DrawRect(unsigned int color);
void SSD1331_Test_FillRect(unsigned int color1, unsigned int color2);
void SSD1331_Test_DrawCircle(unsigned int radius, unsigned int color);
void SSD1331_Test_FillCircle(unsigned int radius, unsigned int color);
void SSD1331_Test_DrawTria(void);
void SSD1331_Test_DrawRoundRect(void);
void SSD1331_Test_MediaButtons(void);
void SSD1331_Test_Pattern(void);
 
#endif /* OLED_SSD1331_H */
 
/PIC Projects/PIC_27J13/spi.c
0,0 → 1,197
#include "defines.h"
#include "spi.h"
 
static SPI_DATA spi_data;
static SPI_DATA *spi_data_p = &spi_data;
 
void SPI2_Init(unsigned char speed) {
// Set up SPI2 with specified pins
RPINR22 = PPS_SPI2_CLK_IN; // SPI2 CLK Input
PPS_SPI2_CLK_OUT = 11; // SPI2 CLK Output
 
#ifndef SPI2_WRITE_ONLY
RPINR21 = PPS_SPI2_MISO; // SPI2 Data Input
SPI_MISO_TRIS = 1; // SPI2 data in pin (MISO)
#endif
SPI_CLK_TRIS = 0; // SPI2 clock pin
PPS_SPI2_MOSI = 10; // SPI2 Data Output (MOSI)
SPI_MOSI_TRIS = 0; // SPI2 data out pin (MOSI)
 
SPI_SLAVE_SELECT_TRIS = 0; // SPI2 slave select
SPI_SLAVE_SELECT_LAT = 1; // SPI2 SS high (Idle)
 
SPI_RESET_TRIS = 0; // SPI2 reset
SPI_RESET_LAT = 1; // SPI2 reset active low
 
SPI_DC_SELECT_TRIS = 0; // SPI2 D/C select
SPI_DC_SELECT_LAT = 0;
 
SSP2STATbits.SMP = 0; // Input is sampled in the middle of data output time
SSP2STATbits.CKE = 0; // Transmit occurs on transition from Idle to active clock state
 
SSP2CON1bits.SSPM = speed;
 
SSP2CON1bits.CKP = 1; // Idle state for clock is a high level
SSP2CON1bits.SSPEN = 1; // Enable MSSP module
 
#ifdef SPI2_USE_INTERRUPT
PIE3bits.SSP2IE = 1; // Enable MSSP2 interrupt
#else
PIE3bits.SSP2IE = 0;
#endif
 
#ifndef SPI2_WRITE_ONLY
spi_data_p->buffer_in_len = 0;
spi_data_p->buffer_in_read_ind = 0;
spi_data_p->buffer_in_write_ind = 0;
#endif
spi_data_p->buffer_out_ind = 0;
spi_data_p->buffer_out_len = 0;
}
 
void SPI2_Write(unsigned char *msg, unsigned int length) {
#ifdef SPI2_USE_INTERRUPT
unsigned char i;
spi_data_p->buffer_out_len = length;
spi_data_p->buffer_out_ind = 1;
for (i = 0; i < length; i++) {
spi_data_p->buffer_out[i] = msg[i];
}
SPI_SLAVE_SELECT_LAT = 0; // Bring SS line low
SSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte
#else
unsigned int i = 0;
unsigned char tmp = 0;
SPI_SLAVE_SELECT_LAT = 0;
while (i != length) {
SSP2BUF = msg[i];
i++;
while (!SSP2STATbits.BF);
 
#ifndef SPI2_WRITE_ONLY
spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
spi_data_p->buffer_in_write_ind = 0;
} else {
spi_data_p->buffer_in_write_ind++;
}
spi_data_p->buffer_in_len++;
#else
// Read data in buffer to clear it
tmp = SSP2BUF;
#endif
}
SPI_SLAVE_SELECT_LAT = 1;
#endif
}
 
void SPI2_Write_Repeat(unsigned char c, unsigned int length) {
#ifdef SPI2_USE_INTERRUPT
// TODO Implement interrupts for SPI2
#else
unsigned int i = 0;
unsigned char tmp = 0;
SPI_SLAVE_SELECT_LAT = 0;
while (i != length) {
SSP2BUF = c;
i++;
while (!SSP2STATbits.BF);
 
#ifndef SPI2_WRITE_ONLY
spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
spi_data_p->buffer_in_write_ind = 0;
} else {
spi_data_p->buffer_in_write_ind++;
}
spi_data_p->buffer_in_len++;
#else
// Read data in buffer to clear it
tmp = SSP2BUF;
#endif
}
SPI_SLAVE_SELECT_LAT = 1;
#endif
}
 
#ifndef SPI2_WRITE_ONLY
void SPI2_Recv_Interrupt_Handler() {
unsigned char c;
 
if (SSP2STATbits.BF) { // Check if data receive flag is set
if (spi_data_p->buffer_in_len == MAXSPIBUF - 1) {
DBG_PRINT_SPI("SPI2: (ERROR) buffer overflow\r\n");
c = SSP2BUF; // Read SSP2BUF to clear it
} else {
// Save received data into buffer
spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
spi_data_p->buffer_in_write_ind = 0;
} else {
spi_data_p->buffer_in_write_ind++;
}
spi_data_p->buffer_in_len++;
 
// Put next byte in SSP2BUF for transmit
if (spi_data_p->buffer_out_ind != spi_data_p->buffer_out_len) {
SSP2BUF = spi_data_p->buffer_out[spi_data_p->buffer_out_ind];
spi_data_p->buffer_out_ind++;
} else {
SPI_SLAVE_SELECT_LAT = 1; // Bring SS line high
spi_data_p->buffer_out_ind = 0;
spi_data_p->buffer_out_len = 0;
}
}
}
}
 
void SPI2_Read(unsigned char length) {
#ifdef SPI2_USE_INTERRUPT
unsigned char i;
spi_data_p->buffer_out_len = length;
spi_data_p->buffer_out_ind = 1;
for (i = 0; i < length; i++) {
spi_data_p->buffer_out[i] = 0x0;
}
SPI_SLAVE_SELECT_LAT = 0; // Bring SS line low
SSP2BUF = spi_data_p->buffer_out[0]; // Transmit first byte
#else
unsigned char i = 0;
SPI_SLAVE_SELECT_LAT = 0;
 
for (i = 0; i < length; i++) {
SSP2BUF = 0x0;
while (!SSP2STATbits.BF);
 
spi_data_p->buffer_in[spi_data_p->buffer_in_write_ind] = SSP2BUF;
if (spi_data_p->buffer_in_write_ind == MAXSPIBUF - 1) {
spi_data_p->buffer_in_write_ind = 0;
} else {
spi_data_p->buffer_in_write_ind++;
}
spi_data_p->buffer_in_len++;
}
SPI_SLAVE_SELECT_LAT = 1;
#endif
}
 
unsigned char SPI2_Buffer_Len() {
return spi_data_p->buffer_in_len;
}
 
unsigned char SPI2_Buffer_Read(unsigned char* buffer) {
unsigned char i = 0;
while (spi_data_p->buffer_in_len != 0) {
buffer[i] = spi_data_p->buffer_in[spi_data_p->buffer_in_read_ind];
i++;
if (spi_data_p->buffer_in_read_ind == MAXSPIBUF - 1) {
spi_data_p->buffer_in_read_ind = 0;
} else {
spi_data_p->buffer_in_read_ind++;
}
spi_data_p->buffer_in_len--;
}
return i;
}
#endif
/PIC Projects/PIC_27J13/spi.h
0,0 → 1,42
#ifndef SPI_H
#define SPI_H
 
#include "defines.h"
 
#define MAXSPIBUF 64
 
// Option to use interrupt. If interrupt are used, SPI write does not block but
// there is a longer delay between reading/writing data
//#define SPI2_USE_INTERRUPT
 
// SPI speed selection
#define SPI2_FOSC_64 0b0010
#define SPI2_FOSC_16 0b0001
#define SPI2_FOSC_8 0b1010
#define SPI2_FOSC_4 0b0000
 
typedef struct __SPI_DATA {
#ifndef SPI2_WRITE_ONLY
unsigned char buffer_in[MAXSPIBUF];
unsigned char buffer_in_read_ind;
unsigned char buffer_in_write_ind;
unsigned char buffer_in_len;
#endif
 
unsigned char buffer_out[MAXSPIBUF];
unsigned char buffer_out_ind;
unsigned char buffer_out_len;
} SPI_DATA;
 
void SPI2_Init(unsigned char speed);
void SPI2_Write(unsigned char *msg, unsigned int length);
void SPI2_Write_Repeat(unsigned char c, unsigned int length);
#ifndef SPI2_WRITE_ONLY
void SPI2_Recv_Interrupt_Handler(void);
void SPI2_Read(unsigned char length);
unsigned char SPI2_Buffer_Len(void);
unsigned char SPI2_Read_Buffer(unsigned char *buffer);
#endif
 
#endif /* SPI_H */
 
/PIC Projects/PIC_27J13/timers.c
0,0 → 1,35
/* The processor calls these handlers when an interrupt is triggered */
#include "defines.h"
#include "timers.h"
 
void Timer1_Init(void) {
T1CONbits.TMR1CS = 0x2; // Clock source using T1OSC and T1CLK pins
T1CONbits.RD16 = 0x1; // Configure for 16-bit read/writes
T1CONbits.T1OSCEN = 0x1; // Enable crystal driver
PIE1bits.TMR1IE = 0x1; // Enable interrupt
 
// Non-applicable settings
T1CONbits.T1CKPS = 0x0; // 1:1 prescale value
T1CONbits.NOT_T1SYNC = 0x1; // No external sync
T1GCONbits.TMR1GE = 0x0; // Disable gate control
}
 
void Timer1_Enable(void) {
T1CONbits.TMR1ON = 1;
}
 
void Timer1_Disable(void) {
T1CONbits.TMR1ON = 0;
}
 
void Timer1_Interrupt_Handler(void) {
#ifdef _TEST_TIMER1_RTC
TMR1H = 0x7F;
TMR1L = 0xFF;
LED_BLUE_LAT = 1;
LED_RED_LAT = 1;
Delay10KTCYx(255);
LED_BLUE_LAT = 0;
LED_RED_LAT = 0;
#endif
}
/PIC Projects/PIC_27J13/18f27j13.lkr
0,0 → 1,87
// File: 18f27j13_g.lkr
// Generic linker script for the PIC18F27J13 processor
 
#DEFINE _CODEEND _DEBUGCODESTART - 1
#DEFINE _CEND _CODEEND + _DEBUGCODELEN
#DEFINE _DATAEND _DEBUGDATASTART - 1
#DEFINE _DEND _DATAEND + _DEBUGDATALEN
 
LIBPATH .
 
#IFDEF _CRUNTIME
#IFDEF _EXTENDEDMODE
FILES c018i_e.o
FILES clib_e.lib
FILES p18f27j13_e.lib
 
#ELSE
FILES c018i.o
FILES clib.lib
FILES p18f27j13.lib
#FI
 
#FI
 
#IFDEF _DEBUGCODESTART
CODEPAGE NAME=page START=0x0 END=_CODEEND
CODEPAGE NAME=debug START=_DEBUGCODESTART END=_CEND PROTECTED
#ELSE
CODEPAGE NAME=page START=0x0 END=0x1FFF7
#FI
 
CODEPAGE NAME=config START=0x1FFF8 END=0x1FFFF PROTECTED
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
 
#IFDEF _EXTENDEDMODE
DATABANK NAME=gpre START=0x0 END=0x5F
#ELSE
ACCESSBANK NAME=accessram START=0x0 END=0x5F
#FI
 
DATABANK NAME=gpr0 START=0x60 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=gpr4 START=0x400 END=0x4FF
DATABANK NAME=gpr5 START=0x500 END=0x5FF
DATABANK NAME=gpr6 START=0x600 END=0x6FF
 
//DATABANK NAME=gpr7 START=0x700 END=0x7FF
//DATABANK NAME=gpr8 START=0x800 END=0x8FF
//DATABANK NAME=gpr9 START=0x900 END=0x9FF
//DATABANK NAME=gpr10 START=0xA00 END=0xAFF
//DATABANK NAME=gpr11 START=0xB00 END=0xBFF
//DATABANK NAME=gpr12 START=0xC00 END=0xCFF
 
// Large (256b) buffer allocated in RAM for UART1 (replaces gpr7)
DATABANK NAME=UART1_BUFFER START=0x700 END=0x7FF
SECTION NAME=UART1_BUFFER RAM=UART1_BUFFER
 
// Large (256b) buffer allocated in RAM for XBee (replaces gpr8)
DATABANK NAME=XBEE_BUFFER START=0x800 END=0x8FF
SECTION NAME=XBEE_BUFFER RAM=XBEE_BUFFER
 
// Large (1024b) buffer allocated in RAM for LCD (replaces gpr9-12)
DATABANK NAME=LCD_BUFFER START=0x900 END=0xCFF
SECTION NAME=LCD_BUFFER RAM=LCD_BUFFER
 
#IFDEF _DEBUGDATASTART
DATABANK NAME=gpr13 START=0xD00 END=_DATAEND
DATABANK NAME=dbgspr START=_DEBUGDATASTART END=_DEND PROTECTED
#ELSE //no debug
DATABANK NAME=gpr13 START=0xD00 END=0xDFF
#FI
 
DATABANK NAME=gpr14 START=0xE00 END=0xEAF
DATABANK NAME=sfr14 START=0xEB0 END=0xEFF PROTECTED
DATABANK NAME=sfr15 START=0xF00 END=0xF5F PROTECTED
ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED
 
#IFDEF _CRUNTIME
SECTION NAME=CONFIG ROM=config
#IFDEF _DEBUGDATASTART
STACK SIZE=0x100 RAM=gpr12
#ELSE
STACK SIZE=0x100 RAM=gpr13
#FI
#FI
/PIC Projects/PIC_27J13/oled_ssd1306.h
0,0 → 1,131
#ifndef OLED_SSD1306_H
#define OLED_SSD1306_H
 
/*=========================================================================
SSD1306 Displays
-----------------------------------------------------------------------
The driver is used in multiple displays (128x64, 128x32, etc.).
Select the appropriate display below to create an appropriately
sized framebuffer, etc.
 
SSD1306_128_64 128x64 pixel display
 
SSD1306_128_32 128x32 pixel display
 
You also need to set the LCDWIDTH and LCDHEIGHT defines to an
appropriate size
 
-----------------------------------------------------------------------*/
#define SSD1306_128_64
// #define SSD1306_128_32
/*=========================================================================*/
 
#if defined SSD1306_128_64
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 64
#endif
#if defined SSD1306_128_32
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 32
#endif
 
#define SSD1306_STRING_BUFFER_SIZE 32
 
#define SSD1306_BLACK 0
#define SSD1306_WHITE 1
 
#define SSD1306_I2C_ADDRESS 0x3D // 011110+SA0+RW
 
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2
 
typedef struct __SSD1306_DATA {
int WIDTH, HEIGHT; // raw display size
int _width, _height; // size depending on rotation
int cursor_x, cursor_y;
unsigned int textcolor, textbgcolor;
unsigned char textsize;
unsigned char rotation;
unsigned char wrap; // If set, wrap text at right side
} SSD1306_DATA;
 
// Misc functions
int SSD1306_Abs(int i);
void SSD1306_Swap(int *a, int *b);
 
// Core functions
void SSD1306_Init(void);
void SSD1306_Begin(unsigned char vcc);
void SSD1306_Command(unsigned char cmd);
void SSD1306_Data(unsigned char data);
 
void SSD1306_Clear_Display(void);
void SSD1306_Invert_Display(unsigned char);
void SSD1306_Display(void);
 
// Drawing functions
void SSD1306_Draw_Pixel(int x, int y, unsigned int color);
void SSD1306_Draw_Line(int x0, int y0, int x1, int y1, unsigned int color);
void SSD1306_Draw_Fast_VLine(int x, int y, int h, unsigned int color);
void SSD1306_Draw_Fast_HLine(int x, int y, int w, unsigned int color);
void SSD1306_Draw_Rect(int x, int y, int w, int h, unsigned int color);
void SSD1306_Fill_Rect(int x, int y, int w, int h, unsigned int color);
 
void SSD1306_Draw_Circle(int x0, int y0, int r, unsigned int color);
void SSD1306_Draw_Circle_Helper(int x0, int y0, int r, unsigned char cornername, unsigned int color);
void SSD1306_Fill_Circle(int x0, int y0, int r, unsigned int color);
void SSD1306_Fill_Circle_Helper(int x0, int y0, int r, unsigned char cornername, int delta, unsigned int color);
 
void SSD1306_Draw_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color);
void SSD1306_Fill_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color);
void SSD1306_Draw_Round_Rect(int x0, int y0, int w, int h, int radius, unsigned int color);
void SSD1306_Fill_Round_Rect(int x0, int y0, int w, int h, int radius, unsigned int color);
 
void SSD1306_Draw_Bitmap(int x, int y, const unsigned char *bitmap, int w, int h, unsigned int color);
void SSD1306_Draw_Char(int x, int y, unsigned char c, unsigned int color, unsigned int bg, unsigned char size);
 
void SSD1306_Write(unsigned char c);
void SSD1306_Write_String(const rom char *fmt, ...);
//void SSD1306_Append_String(const rom char *fmt, ...);
 
void SSD1306_Set_Cursor(int x, int y);
void SSD1306_Set_Text_Color(unsigned int c);
void SSD1306_Set_Text_Color_BG(unsigned int c, unsigned int bg);
void SSD1306_Set_Text_Size(unsigned char s);
void SSD1306_Set_Text_Wrap(unsigned char w);
void SSD1306_Set_Rotation(unsigned char r);
 
// Test functions
void SSD1306_Test_DrawChar(void);
void SSD1306_Test_DrawCircle(void);
void SSD1306_Test_DrawRect(void);
void SSD1306_Test_FillRect(void);
void SSD1306_Test_DrawTriangle(void);
void SSD1306_Test_FillTriangle(void);
void SSD1306_Test_DrawRoundRect(void);
void SSD1306_Test_FillRoundRect(void);
void SSD1306_Test_DrawLine(void);
 
#endif /* OLED_SSD1306_H */
 
/PIC Projects/PIC_27J13/glcdfont.c
0,0 → 1,263
#ifndef FONT5X7_H
#define FONT5X7_H
 
// standard ascii 5x7 font
 
static rom unsigned char font[] = {
0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
0x18, 0x3C, 0x7E, 0x3C, 0x18,
0x1C, 0x57, 0x7D, 0x57, 0x1C,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
0x00, 0x18, 0x3C, 0x18, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
0x00, 0x18, 0x24, 0x18, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
0x30, 0x48, 0x3A, 0x06, 0x0E,
0x26, 0x29, 0x79, 0x29, 0x26,
0x40, 0x7F, 0x05, 0x05, 0x07,
0x40, 0x7F, 0x05, 0x25, 0x3F,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
0x7F, 0x3E, 0x1C, 0x1C, 0x08,
0x08, 0x1C, 0x1C, 0x3E, 0x7F,
0x14, 0x22, 0x7F, 0x22, 0x14,
0x5F, 0x5F, 0x00, 0x5F, 0x5F,
0x06, 0x09, 0x7F, 0x01, 0x7F,
0x00, 0x66, 0x89, 0x95, 0x6A,
0x60, 0x60, 0x60, 0x60, 0x60,
0x94, 0xA2, 0xFF, 0xA2, 0x94,
0x08, 0x04, 0x7E, 0x04, 0x08,
0x10, 0x20, 0x7E, 0x20, 0x10,
0x08, 0x08, 0x2A, 0x1C, 0x08,
0x08, 0x1C, 0x2A, 0x08, 0x08,
0x1E, 0x10, 0x10, 0x10, 0x10,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
0x30, 0x38, 0x3E, 0x38, 0x30,
0x06, 0x0E, 0x3E, 0x0E, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14,
0x24, 0x2A, 0x7F, 0x2A, 0x12,
0x23, 0x13, 0x08, 0x64, 0x62,
0x36, 0x49, 0x56, 0x20, 0x50,
0x00, 0x08, 0x07, 0x03, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
0x08, 0x08, 0x3E, 0x08, 0x08,
0x00, 0x80, 0x70, 0x30, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x60, 0x60, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02,
0x3E, 0x51, 0x49, 0x45, 0x3E,
0x00, 0x42, 0x7F, 0x40, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46,
0x21, 0x41, 0x49, 0x4D, 0x33,
0x18, 0x14, 0x12, 0x7F, 0x10,
0x27, 0x45, 0x45, 0x45, 0x39,
0x3C, 0x4A, 0x49, 0x49, 0x31,
0x41, 0x21, 0x11, 0x09, 0x07,
0x36, 0x49, 0x49, 0x49, 0x36,
0x46, 0x49, 0x49, 0x29, 0x1E,
0x00, 0x00, 0x14, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41,
0x14, 0x14, 0x14, 0x14, 0x14,
0x00, 0x41, 0x22, 0x14, 0x08,
0x02, 0x01, 0x59, 0x09, 0x06,
0x3E, 0x41, 0x5D, 0x59, 0x4E,
0x7C, 0x12, 0x11, 0x12, 0x7C,
0x7F, 0x49, 0x49, 0x49, 0x36,
0x3E, 0x41, 0x41, 0x41, 0x22,
0x7F, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x49, 0x49, 0x49, 0x41,
0x7F, 0x09, 0x09, 0x09, 0x01,
0x3E, 0x41, 0x41, 0x51, 0x73,
0x7F, 0x08, 0x08, 0x08, 0x7F,
0x00, 0x41, 0x7F, 0x41, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01,
0x7F, 0x08, 0x14, 0x22, 0x41,
0x7F, 0x40, 0x40, 0x40, 0x40,
0x7F, 0x02, 0x1C, 0x02, 0x7F,
0x7F, 0x04, 0x08, 0x10, 0x7F,
0x3E, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x09, 0x09, 0x09, 0x06,
0x3E, 0x41, 0x51, 0x21, 0x5E,
0x7F, 0x09, 0x19, 0x29, 0x46,
0x26, 0x49, 0x49, 0x49, 0x32,
0x03, 0x01, 0x7F, 0x01, 0x03,
0x3F, 0x40, 0x40, 0x40, 0x3F,
0x1F, 0x20, 0x40, 0x20, 0x1F,
0x3F, 0x40, 0x38, 0x40, 0x3F,
0x63, 0x14, 0x08, 0x14, 0x63,
0x03, 0x04, 0x78, 0x04, 0x03,
0x61, 0x59, 0x49, 0x4D, 0x43,
0x00, 0x7F, 0x41, 0x41, 0x41,
0x02, 0x04, 0x08, 0x10, 0x20,
0x00, 0x41, 0x41, 0x41, 0x7F,
0x04, 0x02, 0x01, 0x02, 0x04,
0x40, 0x40, 0x40, 0x40, 0x40,
0x00, 0x03, 0x07, 0x08, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40,
0x7F, 0x28, 0x44, 0x44, 0x38,
0x38, 0x44, 0x44, 0x44, 0x28,
0x38, 0x44, 0x44, 0x28, 0x7F,
0x38, 0x54, 0x54, 0x54, 0x18,
0x00, 0x08, 0x7E, 0x09, 0x02,
0x18, 0xA4, 0xA4, 0x9C, 0x78,
0x7F, 0x08, 0x04, 0x04, 0x78,
0x00, 0x44, 0x7D, 0x40, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78,
0x7C, 0x08, 0x04, 0x04, 0x78,
0x38, 0x44, 0x44, 0x44, 0x38,
0xFC, 0x18, 0x24, 0x24, 0x18,
0x18, 0x24, 0x24, 0x18, 0xFC,
0x7C, 0x08, 0x04, 0x04, 0x08,
0x48, 0x54, 0x54, 0x54, 0x24,
0x04, 0x04, 0x3F, 0x44, 0x24,
0x3C, 0x40, 0x40, 0x20, 0x7C,
0x1C, 0x20, 0x40, 0x20, 0x1C,
0x3C, 0x40, 0x30, 0x40, 0x3C,
0x44, 0x28, 0x10, 0x28, 0x44,
0x4C, 0x90, 0x90, 0x90, 0x7C,
0x44, 0x64, 0x54, 0x4C, 0x44,
0x00, 0x08, 0x36, 0x41, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02,
0x3C, 0x26, 0x23, 0x26, 0x3C,
0x1E, 0xA1, 0xA1, 0x61, 0x12,
0x3A, 0x40, 0x40, 0x20, 0x7A,
0x38, 0x54, 0x54, 0x55, 0x59,
0x21, 0x55, 0x55, 0x79, 0x41,
0x21, 0x54, 0x54, 0x78, 0x41,
0x21, 0x55, 0x54, 0x78, 0x40,
0x20, 0x54, 0x55, 0x79, 0x40,
0x0C, 0x1E, 0x52, 0x72, 0x12,
0x39, 0x55, 0x55, 0x55, 0x59,
0x39, 0x54, 0x54, 0x54, 0x59,
0x39, 0x55, 0x54, 0x54, 0x58,
0x00, 0x00, 0x45, 0x7C, 0x41,
0x00, 0x02, 0x45, 0x7D, 0x42,
0x00, 0x01, 0x45, 0x7C, 0x40,
0xF0, 0x29, 0x24, 0x29, 0xF0,
0xF0, 0x28, 0x25, 0x28, 0xF0,
0x7C, 0x54, 0x55, 0x45, 0x00,
0x20, 0x54, 0x54, 0x7C, 0x54,
0x7C, 0x0A, 0x09, 0x7F, 0x49,
0x32, 0x49, 0x49, 0x49, 0x32,
0x32, 0x48, 0x48, 0x48, 0x32,
0x32, 0x4A, 0x48, 0x48, 0x30,
0x3A, 0x41, 0x41, 0x21, 0x7A,
0x3A, 0x42, 0x40, 0x20, 0x78,
0x00, 0x9D, 0xA0, 0xA0, 0x7D,
0x39, 0x44, 0x44, 0x44, 0x39,
0x3D, 0x40, 0x40, 0x40, 0x3D,
0x3C, 0x24, 0xFF, 0x24, 0x24,
0x48, 0x7E, 0x49, 0x43, 0x66,
0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
0xFF, 0x09, 0x29, 0xF6, 0x20,
0xC0, 0x88, 0x7E, 0x09, 0x03,
0x20, 0x54, 0x54, 0x79, 0x41,
0x00, 0x00, 0x44, 0x7D, 0x41,
0x30, 0x48, 0x48, 0x4A, 0x32,
0x38, 0x40, 0x40, 0x22, 0x7A,
0x00, 0x7A, 0x0A, 0x0A, 0x72,
0x7D, 0x0D, 0x19, 0x31, 0x7D,
0x26, 0x29, 0x29, 0x2F, 0x28,
0x26, 0x29, 0x29, 0x29, 0x26,
0x30, 0x48, 0x4D, 0x40, 0x20,
0x38, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x38,
0x2F, 0x10, 0xC8, 0xAC, 0xBA,
0x2F, 0x10, 0x28, 0x34, 0xFA,
0x00, 0x00, 0x7B, 0x00, 0x00,
0x08, 0x14, 0x2A, 0x14, 0x22,
0x22, 0x14, 0x2A, 0x14, 0x08,
0xAA, 0x00, 0x55, 0x00, 0xAA,
0xAA, 0x55, 0xAA, 0x55, 0xAA,
0x00, 0x00, 0x00, 0xFF, 0x00,
0x10, 0x10, 0x10, 0xFF, 0x00,
0x14, 0x14, 0x14, 0xFF, 0x00,
0x10, 0x10, 0xFF, 0x00, 0xFF,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x14, 0x14, 0x14, 0xFC, 0x00,
0x14, 0x14, 0xF7, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x14, 0x14, 0xF4, 0x04, 0xFC,
0x14, 0x14, 0x17, 0x10, 0x1F,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0x1F, 0x00,
0x10, 0x10, 0x10, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x10,
0x10, 0x10, 0x10, 0x1F, 0x10,
0x10, 0x10, 0x10, 0xF0, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0xFF, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x14,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x1F, 0x10, 0x17,
0x00, 0x00, 0xFC, 0x04, 0xF4,
0x14, 0x14, 0x17, 0x10, 0x17,
0x14, 0x14, 0xF4, 0x04, 0xF4,
0x00, 0x00, 0xFF, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0xF7, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x17, 0x14,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0xF4, 0x14,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x00, 0x00, 0x1F, 0x10, 0x1F,
0x00, 0x00, 0x00, 0x1F, 0x14,
0x00, 0x00, 0x00, 0xFC, 0x14,
0x00, 0x00, 0xF0, 0x10, 0xF0,
0x10, 0x10, 0xFF, 0x10, 0xFF,
0x14, 0x14, 0x14, 0xFF, 0x14,
0x10, 0x10, 0x10, 0x1F, 0x00,
0x00, 0x00, 0x00, 0xF0, 0x10,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x38, 0x44, 0x44, 0x38, 0x44,
0x7C, 0x2A, 0x2A, 0x3E, 0x14,
0x7E, 0x02, 0x02, 0x06, 0x06,
0x02, 0x7E, 0x02, 0x7E, 0x02,
0x63, 0x55, 0x49, 0x41, 0x63,
0x38, 0x44, 0x44, 0x3C, 0x04,
0x40, 0x7E, 0x20, 0x1E, 0x20,
0x06, 0x02, 0x7E, 0x02, 0x02,
0x99, 0xA5, 0xE7, 0xA5, 0x99,
0x1C, 0x2A, 0x49, 0x2A, 0x1C,
0x4C, 0x72, 0x01, 0x72, 0x4C,
0x30, 0x4A, 0x4D, 0x4D, 0x30,
0x30, 0x48, 0x78, 0x48, 0x30,
0xBC, 0x62, 0x5A, 0x46, 0x3D,
0x3E, 0x49, 0x49, 0x49, 0x00,
0x7E, 0x01, 0x01, 0x01, 0x7E,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x44, 0x44, 0x5F, 0x44, 0x44,
0x40, 0x51, 0x4A, 0x44, 0x40,
0x40, 0x44, 0x4A, 0x51, 0x40,
0x00, 0x00, 0xFF, 0x01, 0x03,
0xE0, 0x80, 0xFF, 0x00, 0x00,
0x08, 0x08, 0x6B, 0x6B, 0x08,
0x36, 0x12, 0x36, 0x24, 0x36,
0x06, 0x0F, 0x09, 0x0F, 0x06,
0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x00, 0x10, 0x10, 0x00,
0x30, 0x40, 0xFF, 0x01, 0x01,
0x00, 0x1F, 0x01, 0x01, 0x1E,
0x00, 0x19, 0x1D, 0x17, 0x12,
0x00, 0x3C, 0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00,
};
#endif
/PIC Projects/PIC_27J13/Makefile
0,0 → 1,108
#
# 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...
 
.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
/PIC Projects/PIC_27J13/pin_interrupts.c
0,0 → 1,101
#include "maindefs.h"
#include "pin_interrupts.h"
#include "pwm.h"
#include "msg_queues.h"
#include <delays.h>
 
static unsigned char port_b_prev_state;
 
void intx_init() {
TRISAbits.TRISA5 = 1;
TRISCbits.TRISC2 = 0;
LATCbits.LATC2 = 0;
 
RPINR1 = 2; // Bind INT1 interrupt to RP2
 
INTCON2bits.INTEDG1 = 0; // Trigger on falling edge
}
 
void int1_interrupt_handler() {
LATCbits.LATC2 = 1;
Delay10TCYx(255);
LATCbits.LATC2 = 0;
MQ_sendmsg_ToMainFromLow(0, MSGTYPE_INT1, (void *) 0);
}
 
void port_b_int_init() {
port_b_prev_state = 0x0F;
 
INTCON2bits.RBPU = 0;
// Set pins as inputs
TRISBbits.TRISB4 = 1;
TRISBbits.TRISB5 = 1;
TRISBbits.TRISB6 = 1;
TRISBbits.TRISB7 = 1;
 
// Turn on internal voltage pull-up
PORTBbits.RB4 = 1;
PORTBbits.RB5 = 1;
PORTBbits.RB6 = 1;
PORTBbits.RB7 = 1;
LATBbits.LATB4 = 1;
LATBbits.LATB5 = 1;
LATBbits.LATB6 = 1;
LATBbits.LATB7 = 1;
}
 
void port_b_int_interrupt_handler() {
// Pull the new pin values
unsigned char new_state = (PORTB & 0xF0) >> 4;
 
// Query which pin input value changed and send value to main()
if ((new_state ^ port_b_prev_state) & 0x01) {
if (port_b_prev_state & 0x01) {
// Pin transitioned HIGH -> LOW (button pressed)
DBG_PRINT_PORTB_INT("Port B4 HIGH->LOW\r\n");
MQ_sendmsg_ToMainFromLow(0, MSGTYPE_PORTB_4_DOWN, (void *) 0);
} else {
// Pin transitioned LOW -> HIGH (button released)
DBG_PRINT_PORTB_INT("Port B4 LOW->HIGH\r\n");
MQ_sendmsg_ToMainFromLow(0, MSGTYPE_PORTB_4_UP, (void *) 0);
}
}
if ((new_state ^ port_b_prev_state) & 0x02) {
if (port_b_prev_state & 0x02) {
// Pin transitioned HIGH -> LOW (button pressed)
DBG_PRINT_PORTB_INT("Port B5 HIGH->LOW\r\n");
MQ_sendmsg_ToMainFromLow(0, MSGTYPE_PORTB_5_DOWN, (void *) 0);
} else {
// Pin transitioned LOW -> HIGH (button released)
DBG_PRINT_PORTB_INT("Port B5 LOW->HIGH\r\n");
MQ_sendmsg_ToMainFromLow(0, MSGTYPE_PORTB_5_UP, (void *) 0);
}
}
if ((new_state ^ port_b_prev_state) & 0x04) {
if (port_b_prev_state & 0x04) {
// Pin transitioned HIGH -> LOW (button pressed)
DBG_PRINT_PORTB_INT("Port B6 HIGH->LOW\r\n");
MQ_sendmsg_ToMainFromLow(0, MSGTYPE_PORTB_6_DOWN, (void *) 0);
} else {
// Pin transitioned LOW -> HIGH (button released)
DBG_PRINT_PORTB_INT("Port B6 LOW->HIGH\r\n");
MQ_sendmsg_ToMainFromLow(0, MSGTYPE_PORTB_6_UP, (void *) 0);
}
}
if ((new_state ^ port_b_prev_state) & 0x08) {
if (port_b_prev_state & 0x08) {
// Pin transitioned HIGH -> LOW (button pressed)
DBG_PRINT_PORTB_INT("Port B7 HIGH->LOW\r\n");
MQ_sendmsg_ToMainFromLow(0, MSGTYPE_PORTB_7_DOWN, (void *) 0);
} else {
// Pin transitioned LOW -> HIGH (button released)
DBG_PRINT_PORTB_INT("Port B7 LOW->HIGH\r\n");
MQ_sendmsg_ToMainFromLow(0, MSGTYPE_PORTB_7_UP, (void *) 0);
}
}
// Save the new state of pins
port_b_prev_state = new_state;
}
/PIC Projects/PIC_27J13/pwm.c
0,0 → 1,31
#include "maindefs.h"
#include "pwm.h"
#include <pwm.h>
 
void pwm_init() {
// Configure pins RC5 and RC7 as outputs
TRISCbits.TRISC0 = 0;
TRISCbits.TRISC1 = 0;
LATCbits.LATC0 = 0;
LATCbits.LATC1 = 0;
 
RPOR11 = 14; // Set RP11 to ECCP1 PWM Output Channel A
RPOR12 = 15; // Set RP12 to ECCP1 PWM Output Channel B
}
 
void pwm_start() {
OpenEPWM1(0xFF, ECCP_1_SEL_TMR12); // 38kHz Frequency
SetDCEPWM1(512); // 50% Duty Cycle
 
// Wait for completion of a full PWM cycle before enabling output mode
while(!PIR1bits.TMR2IF);
SetOutputEPWM1(SINGLE_OUT, PWM_MODE_1);
 
// Enable ECCP1 output channels A and B
PSTR1CONbits.STRA = 1;
PSTR1CONbits.STRB = 1;
}
 
void pwm_stop() {
CloseEPWM1();
}