First commit
This commit is contained in:
commit
561a8479b7
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.o
|
||||
*.d
|
||||
113
ChaloupeLora.X/Makefile
Normal file
113
ChaloupeLora.X/Makefile
Normal file
@ -0,0 +1,113 @@
|
||||
#
|
||||
# There exist several targets which are by default empty and which can be
|
||||
# used for execution of your targets. These targets are usually executed
|
||||
# before and after some main targets. They are:
|
||||
#
|
||||
# .build-pre: called before 'build' target
|
||||
# .build-post: called after 'build' target
|
||||
# .clean-pre: called before 'clean' target
|
||||
# .clean-post: called after 'clean' target
|
||||
# .clobber-pre: called before 'clobber' target
|
||||
# .clobber-post: called after 'clobber' target
|
||||
# .all-pre: called before 'all' target
|
||||
# .all-post: called after 'all' target
|
||||
# .help-pre: called before 'help' target
|
||||
# .help-post: called after 'help' target
|
||||
#
|
||||
# Targets beginning with '.' are not intended to be called on their own.
|
||||
#
|
||||
# Main targets can be executed directly, and they are:
|
||||
#
|
||||
# build build a specific configuration
|
||||
# clean remove built files from a configuration
|
||||
# clobber remove all built files
|
||||
# all build all configurations
|
||||
# help print help mesage
|
||||
#
|
||||
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
|
||||
# .help-impl are implemented in nbproject/makefile-impl.mk.
|
||||
#
|
||||
# Available make variables:
|
||||
#
|
||||
# CND_BASEDIR base directory for relative paths
|
||||
# CND_DISTDIR default top distribution directory (build artifacts)
|
||||
# CND_BUILDDIR default top build directory (object files, ...)
|
||||
# CONF name of current configuration
|
||||
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
|
||||
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
|
||||
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
|
||||
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
|
||||
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
|
||||
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
|
||||
#
|
||||
# NOCDDL
|
||||
|
||||
|
||||
# Environment
|
||||
MKDIR=mkdir
|
||||
CP=cp
|
||||
CCADMIN=CCadmin
|
||||
RANLIB=ranlib
|
||||
|
||||
|
||||
# build
|
||||
build: .build-post
|
||||
|
||||
.build-pre:
|
||||
# Add your pre 'build' code here...
|
||||
|
||||
.build-post: .build-impl
|
||||
# Add your post 'build' code here...
|
||||
|
||||
|
||||
# clean
|
||||
clean: .clean-post
|
||||
|
||||
.clean-pre:
|
||||
# Add your pre 'clean' code here...
|
||||
# WARNING: the IDE does not call this target since it takes a long time to
|
||||
# simply run make. Instead, the IDE removes the configuration directories
|
||||
# under build and dist directly without calling make.
|
||||
# This target is left here so people can do a clean when running a clean
|
||||
# outside the IDE.
|
||||
|
||||
.clean-post: .clean-impl
|
||||
# Add your post 'clean' code here...
|
||||
|
||||
|
||||
# clobber
|
||||
clobber: .clobber-post
|
||||
|
||||
.clobber-pre:
|
||||
# Add your pre 'clobber' code here...
|
||||
|
||||
.clobber-post: .clobber-impl
|
||||
# Add your post 'clobber' code here...
|
||||
|
||||
|
||||
# all
|
||||
all: .all-post
|
||||
|
||||
.all-pre:
|
||||
# Add your pre 'all' code here...
|
||||
|
||||
.all-post: .all-impl
|
||||
# Add your post 'all' code here...
|
||||
|
||||
|
||||
# help
|
||||
help: .help-post
|
||||
|
||||
.help-pre:
|
||||
# Add your pre 'help' code here...
|
||||
|
||||
.help-post: .help-impl
|
||||
# Add your post 'help' code here...
|
||||
|
||||
|
||||
|
||||
# include project implementation makefile
|
||||
include nbproject/Makefile-impl.mk
|
||||
|
||||
# include project make variables
|
||||
include nbproject/Makefile-variables.mk
|
||||
265
ChaloupeLora.X/Source/ADC.c
Normal file
265
ChaloupeLora.X/Source/ADC.c
Normal file
@ -0,0 +1,265 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2012 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
### 20120521 JFM
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
#include "ADC.h"
|
||||
#include "HallAcquisition.h"
|
||||
#include "digitalio.h"
|
||||
#include "PAStatus.h"
|
||||
|
||||
/* Globals */
|
||||
unsigned int guiADCMode;
|
||||
unsigned short egADCMotPhaseA;
|
||||
unsigned short egADCMotPhaseB;
|
||||
unsigned short egADCMotPhaseC;
|
||||
|
||||
/* Implementation */
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void InitADC(void)
|
||||
{
|
||||
//At boot, init ADC in normal mode...
|
||||
guiADCMode = ADC_NORMAL_MODE;
|
||||
|
||||
//configure input pins as analog inputs.
|
||||
TRISBbits.TRISB3 = 1;
|
||||
AD1PCFGbits.PCFG3 = 0;
|
||||
TRISBbits.TRISB4 = 1;
|
||||
AD1PCFGbits.PCFG4 = 0;
|
||||
TRISBbits.TRISB5 = 1;
|
||||
AD1PCFGbits.PCFG5 = 0;
|
||||
TRISBbits.TRISB8 = 1;
|
||||
AD1PCFGbits.PCFG8 = 0;
|
||||
TRISBbits.TRISB9 = 1;
|
||||
AD1PCFGbits.PCFG9 = 0;
|
||||
TRISBbits.TRISB11 = 1;
|
||||
AD1PCFGbits.PCFG11 = 0;
|
||||
TRISBbits.TRISB12 = 1;
|
||||
AD1PCFGbits.PCFG12 = 0;
|
||||
TRISBbits.TRISB13 = 1;
|
||||
AD1PCFGbits.PCFG13 = 0;
|
||||
|
||||
AD1CON1 = 0;
|
||||
AD1CON2 = 0;
|
||||
AD1CON3 = 0;
|
||||
|
||||
//configure output format (unsigned int 16 bits)
|
||||
AD1CON1bits.FORM = 0b000;
|
||||
//configure clock source and prescaling
|
||||
AD1CON3bits.ADRC = 0; //Use Peripheral clock
|
||||
AD1CON3bits.ADCS = 4; //Acording to datasheet TAD must be min 83.33ns --> minimal prescaler applied to TPBclk = 8 --> Conversion time ~= 100ns
|
||||
//AD1CON3bits.SAMC = 1; //Used in automatic sampling mode (scan mode). Shall be augmented if results are not accurate. See datasheet.
|
||||
AD1CON3bits.SAMC = 30; //Used in automatic sampling mode (scan mode). Shall be augmented if results are not accurate. See datasheet.
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int ADCEnterHallACQMode(void)
|
||||
{
|
||||
//configure ADC module
|
||||
AD1CON1bits.ON = 0; //stop ADC to reconfigure.
|
||||
IEC1bits.AD1IE = 0; //disable ADC interrupt for now
|
||||
|
||||
AD1CHS = 0; //Reset channel source since input source is controlled by hardware in scan mode.
|
||||
AD1CON2 = 0;
|
||||
AD1CSSL = 0;
|
||||
|
||||
AD1CON1bits.SSRC = 0b111; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
|
||||
// AD1CON1bits.SSRC = 0b000; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
|
||||
AD1CON1bits.CLRASAM = 1;
|
||||
AD1CON1bits.ASAM = 1;
|
||||
|
||||
//configure scan mode
|
||||
AD1CON2bits.CSCNA = 1; //enable scan mode
|
||||
AD1CON2bits.SMPI = 2; //Generate interrupt after the 3rd conversion.
|
||||
|
||||
AD1CSSLbits.CSSL11= 1; //select Phase A input in scan sequence
|
||||
AD1CSSLbits.CSSL12= 1; //select Phase B input in scan sequence
|
||||
AD1CSSLbits.CSSL13= 1; //select Phase C input in scan sequence
|
||||
AD1CON1bits.SAMP = 1 ;
|
||||
|
||||
|
||||
IPC6bits.AD1IP = 5;
|
||||
IPC6bits.AD1IS = 3;
|
||||
IFS1bits.AD1IF = 0;
|
||||
IEC1bits.AD1IE = 1; //enable ADC interrupt
|
||||
|
||||
AD1CON1bits.ON = 1; //enable ADC.
|
||||
|
||||
guiADCMode = ADC_HALL_ACQ_MODE;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int ADCEnterTracesMode(void)
|
||||
{
|
||||
//trick to reuse code but force the good mode :)
|
||||
ADCEnterHallACQMode();
|
||||
guiADCMode = ADC_TRACE_MODE;
|
||||
return 1;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
int ADCEnterCBITMode(void)
|
||||
{
|
||||
//configure ADC module
|
||||
AD1CON1bits.ON = 0; //stop ADC to reconfigure.
|
||||
IEC1bits.AD1IE = 0; //disable ADC interrupt for now
|
||||
|
||||
AD1CHS = 0; //Reset channel source since input source is controlled by hardware in scan mode.
|
||||
AD1CON2 = 0;
|
||||
AD1CSSL = 0;
|
||||
|
||||
AD1CON1bits.SSRC = 0b111; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
|
||||
// AD1CON1bits.SSRC = 0b000; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
|
||||
AD1CON1bits.CLRASAM = 1;
|
||||
AD1CON1bits.ASAM = 1;
|
||||
|
||||
//configure scan mode
|
||||
AD1CON2bits.CSCNA = 1; //enable scan mode
|
||||
AD1CON2bits.SMPI = 4; //Generate interrupt after the 5th conversion.
|
||||
|
||||
AD1CSSLbits.CSSL3= 1; //select Vref input in scan sequence
|
||||
AD1CSSLbits.CSSL4= 1; //select 5V input in scan sequence
|
||||
AD1CSSLbits.CSSL5= 1; //select 3.3V input in scan sequence
|
||||
AD1CSSLbits.CSSL8= 1; //select Motor Thermistor input in scan sequence
|
||||
AD1CSSLbits.CSSL9= 1; //select Drive Thermistor input in scan sequence
|
||||
AD1CON1bits.SAMP = 1;
|
||||
|
||||
|
||||
IPC6bits.AD1IP = 5;
|
||||
IPC6bits.AD1IS = 3;
|
||||
IFS1bits.AD1IF = 0;
|
||||
IEC1bits.AD1IE = 1; //enable ADC interrupt
|
||||
|
||||
AD1CON1bits.ON = 1; //enable ADC.
|
||||
|
||||
guiADCMode = ADC_CBIT_MODE;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Starts acquistion and conversion of the 3 phases. The 3 inputs are scanned
|
||||
// automatically by hardware and an interrupt is triggered when finished.
|
||||
//
|
||||
int ADCStartHallACQConversion(void)
|
||||
{
|
||||
AD1CON1bits.ASAM = 1;
|
||||
AD1CON1bits.SAMP = 1; //start sampling and start conversion. Interrupt will be generated when data is ready
|
||||
return 1;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int ADCStartTracesConversion(void)
|
||||
{
|
||||
AD1CON1bits.ASAM = 1;
|
||||
AD1CON1bits.SAMP = 1; //start sampling and start conversion. Interrupt will be generated when data is ready
|
||||
return 1;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
int ADCStartCBITConversion(void)
|
||||
{
|
||||
if(guiADCMode == ADC_CBIT_MODE)
|
||||
{
|
||||
AD1CON1bits.ASAM = 1;
|
||||
AD1CON1bits.SAMP = 1; //start sampling and start conversion. Interrupt will be generated when data is ready
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
int ADCStopConversion(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
int ADCGetMode(void)
|
||||
{
|
||||
return guiADCMode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void __ISR(_ADC_VECTOR, ipl5) ADCInterrupt(void)
|
||||
{
|
||||
switch(guiADCMode)
|
||||
{
|
||||
case ADC_NORMAL_MODE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case ADC_CBIT_MODE:
|
||||
{
|
||||
estPAStatus.gusVoltageVref = ADC1BUF0;
|
||||
estPAStatus.gusVoltage5V = ADC1BUF1;
|
||||
estPAStatus.gusVoltage33V = ADC1BUF2;
|
||||
estPAStatus.gusVoltageThermMot = ADC1BUF3;
|
||||
estPAStatus.gusVoltageThermDrv = ADC1BUF4;
|
||||
|
||||
estPAStatus.IsDataReady = 1;
|
||||
break;
|
||||
}
|
||||
case ADC_TRACE_MODE:
|
||||
{
|
||||
egADCMotPhaseA = ADC1BUF0;
|
||||
egADCMotPhaseB = ADC1BUF1;
|
||||
egADCMotPhaseC = ADC1BUF2;
|
||||
break;
|
||||
}
|
||||
case ADC_HALL_ACQ_MODE:
|
||||
{
|
||||
//Update data structure.
|
||||
if(gpstHallAcqDataPtr != 0 && gpstHallAcqDataPtr <= gpstHallAcqDataPtrEND)
|
||||
{
|
||||
gpstHallAcqDataPtr->MotPhaseA = ADC1BUF0;
|
||||
gpstHallAcqDataPtr->MotPhaseB = ADC1BUF1;
|
||||
gpstHallAcqDataPtr->MotPhaseC = ADC1BUF2;
|
||||
gpstHallAcqDataPtr->AnalogDataUpToDate = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
IFS1bits.AD1IF = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//EOF
|
||||
|
||||
73
ChaloupeLora.X/Source/ADC.h
Normal file
73
ChaloupeLora.X/Source/ADC.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2012 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ¤Revision:
|
||||
000 20120516 JFM,
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
#ifndef ADC_H
|
||||
#define ADC_H
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Externs */
|
||||
|
||||
extern unsigned short egADCMotPhaseA;
|
||||
extern unsigned short egADCMotPhaseB;
|
||||
extern unsigned short egADCMotPhaseC;
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
#define ADC_VOLT_PER_BIT (float)0.003222656
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
enum eADCModes
|
||||
{
|
||||
ADC_NORMAL_MODE,
|
||||
ADC_CBIT_MODE,
|
||||
ADC_TRACE_MODE,
|
||||
ADC_HALL_ACQ_MODE,
|
||||
ADC_MAX_MODE
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
void InitADC(void);
|
||||
|
||||
int ADCStopConversion(void);
|
||||
//Hall Acquisition Mode
|
||||
int ADCEnterHallACQMode(void);
|
||||
int ADCStartHallACQConversion(void);
|
||||
|
||||
//Traces Mode
|
||||
int ADCEnterTracesMode(void);
|
||||
int ADCStartTracesConversion(void);
|
||||
|
||||
//CBIT Mode
|
||||
int ADCEnterCBITMode(void);
|
||||
int ADCStartCBITConversion(void);
|
||||
|
||||
|
||||
int ADCGetMode(void);
|
||||
|
||||
|
||||
|
||||
#endif //#define ADC_H
|
||||
//EOF
|
||||
|
||||
188
ChaloupeLora.X/Source/BatteryMonitor.c
Normal file
188
ChaloupeLora.X/Source/BatteryMonitor.c
Normal file
@ -0,0 +1,188 @@
|
||||
//#include <proc/p32mx440f256h.h>
|
||||
|
||||
#include "BatteryMonitor.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "timer.h"
|
||||
#include "ina219.h"
|
||||
#include "WiFiCtrl.h"
|
||||
#include "I2C.h"
|
||||
|
||||
float mBatteryVoltage;
|
||||
int mBatteryCurrent;
|
||||
int mBatterySOC;
|
||||
|
||||
float mVoltageMeanSum;
|
||||
int mVoltageMeanCount;
|
||||
unsigned int mCurrentMeanSum;
|
||||
int mCurrentMeanCount;
|
||||
bool mCurrentModuleOK;
|
||||
|
||||
void InitBatteryMonitor()
|
||||
{
|
||||
mBatteryVoltage = 0;
|
||||
mBatteryCurrent = 0;
|
||||
mBatterySOC = 0;
|
||||
mVoltageMeanCount = 0;
|
||||
mCurrentMeanCount = 0;
|
||||
mCurrentModuleOK = true;
|
||||
|
||||
TimerStart(BATTERY_MONITOR_TIMER,100);
|
||||
|
||||
|
||||
//experimental stuff!
|
||||
mVoltageMeanSum = 0.0;
|
||||
mVoltageMeanCount = 0;
|
||||
|
||||
if(ina219Init() == RET_ERROR)
|
||||
{
|
||||
mCurrentModuleOK = false;
|
||||
}
|
||||
//ina219SetCalibration_16V_500mA();
|
||||
// ina219SetCalibration_16V_200mA();
|
||||
|
||||
}
|
||||
|
||||
void BatteryMonitorTick()
|
||||
{
|
||||
static int NetworkSendCounter; //Every second (10 counts) we want to send the battery data.
|
||||
if(IsTimerExpired(BATTERY_MONITOR_TIMER))
|
||||
{
|
||||
unsigned int adc;
|
||||
double conv, raw;
|
||||
|
||||
AD1CHSbits.CH0SA = 1; //AN1
|
||||
AD1CON1bits.SAMP = 0;
|
||||
while(AD1CON1bits.DONE == 0);
|
||||
adc = ADC1BUF0;
|
||||
AD1CON1bits.SAMP = 1;
|
||||
// adc &= 0xFFFE;
|
||||
conv = (float)adc / 1023;
|
||||
conv *= 3.36;
|
||||
raw = conv;
|
||||
conv *= 11;
|
||||
|
||||
//avoid rollovers in case the LORA network gets disconnected.
|
||||
//This could go for a long time but 5000 samples is too much anyways.
|
||||
if(mVoltageMeanCount >= 5000)
|
||||
{
|
||||
mVoltageMeanCount = 0;
|
||||
mVoltageMeanSum = conv;
|
||||
}
|
||||
else
|
||||
{
|
||||
mVoltageMeanCount++;
|
||||
mVoltageMeanSum += conv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
mBatteryVoltage = conv;
|
||||
|
||||
TimerStart(BATTERY_MONITOR_TIMER,100);
|
||||
|
||||
if(mCurrentModuleOK == true)
|
||||
{
|
||||
mBatteryCurrent = ina219GetCurrent_mA();
|
||||
if(I2CWasLastTransactionOK() == 0 )
|
||||
{
|
||||
mCurrentModuleOK = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int Ref = 0;
|
||||
AD1CHSbits.CH0SA = 0; //AN0
|
||||
AD1CON1bits.SAMP = 0;
|
||||
while(AD1CON1bits.DONE == 0);
|
||||
Ref = ADC1BUF0;
|
||||
AD1CON1bits.SAMP = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
AD1CHSbits.CH0SA = 2; //AN2
|
||||
AD1CON1bits.SAMP = 0;
|
||||
while(AD1CON1bits.DONE == 0);
|
||||
adc = ADC1BUF0;
|
||||
AD1CON1bits.SAMP = 1;
|
||||
// adc &= 0xFFFE;
|
||||
|
||||
adc -= Ref;
|
||||
|
||||
conv = (double)adc * 1.0;
|
||||
conv /= 1023;
|
||||
conv *= 3.3; //Volts
|
||||
conv /= 0.05; //Amps (50mV/A)
|
||||
|
||||
raw = conv;
|
||||
|
||||
//avoid rollovers in case the LORA network gets disconnected.
|
||||
//This could go for a long time but 5000 samples is too much anyways.
|
||||
if(mCurrentMeanCount >= 500)
|
||||
{
|
||||
mCurrentMeanCount = 1;
|
||||
mCurrentMeanSum = adc;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentMeanCount++;
|
||||
mCurrentMeanSum += adc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
mBatteryCurrent = adc;
|
||||
//mBatteryCurrent = mCurrentMeanSum / mCurrentMeanCount;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
float GetBatteryVoltage()
|
||||
{
|
||||
mBatteryVoltage = (mVoltageMeanSum/mVoltageMeanCount);
|
||||
mVoltageMeanSum = 0.0;
|
||||
mVoltageMeanCount = 0;
|
||||
|
||||
|
||||
return mBatteryVoltage;
|
||||
|
||||
}
|
||||
|
||||
int GetSolarPanelCurrent()
|
||||
{
|
||||
//mBatteryCurrent = (mCurrentMeanSum/mCurrentMeanCount);
|
||||
mVoltageMeanCount = 0;
|
||||
mCurrentMeanSum = 0.0;
|
||||
|
||||
return mBatteryCurrent;
|
||||
}
|
||||
|
||||
int GetBatterySOC()
|
||||
{
|
||||
return mBatterySOC;
|
||||
}
|
||||
|
||||
int SendNetworkBatteryData()
|
||||
{
|
||||
// int VoltageMilliVolts = (int)(mBatteryVoltage * 1000);
|
||||
// int BattCurrent = mBatteryCurrent;
|
||||
//
|
||||
// char BatData[10];
|
||||
// BatData[0] = (char)(VoltageMilliVolts & 0x000000FF); //Battery Voltage 1
|
||||
// VoltageMilliVolts >>= 8;
|
||||
// BatData[1] = (char)(VoltageMilliVolts & 0x000000FF); //Battery Voltage 2
|
||||
// BatData[2] = (char)(BattCurrent & 0x000000FF); //Solar panel Current 1
|
||||
// BattCurrent >>= 8;
|
||||
// BatData[3] = (char)(BattCurrent & 0x000000FF); //Solar panel Current 2
|
||||
//
|
||||
// SendNetworkData(BatData,4);
|
||||
|
||||
printf("Battery voltage: %f\n",mBatteryVoltage);
|
||||
|
||||
}
|
||||
|
||||
bool GetCurrentModuleOK()
|
||||
{
|
||||
return mCurrentModuleOK;
|
||||
}
|
||||
26
ChaloupeLora.X/Source/BatteryMonitor.h
Normal file
26
ChaloupeLora.X/Source/BatteryMonitor.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* File: ChaletPowerRelay.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 30, 2018, 7:33 PM
|
||||
*/
|
||||
|
||||
#ifndef BATTERYMONITOR_H
|
||||
#define BATTERYMONITOR_H
|
||||
#include "define.h"
|
||||
|
||||
|
||||
|
||||
|
||||
void InitBatteryMonitor();
|
||||
|
||||
void BatteryMonitorTick();
|
||||
float GetBatteryVoltage();
|
||||
int GetSolarPanelCurrent();
|
||||
int GetBatterySOC();
|
||||
int SendNetworkBatteryData();
|
||||
bool GetCurrentModuleOK();
|
||||
|
||||
|
||||
#endif /* BATTERYMONITOR_H */
|
||||
|
||||
49
ChaloupeLora.X/Source/BoardCfg.h
Normal file
49
ChaloupeLora.X/Source/BoardCfg.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* File: BoardCfg.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 26, 2018, 4:50 PM
|
||||
*/
|
||||
|
||||
#ifndef BOARDCFG_H
|
||||
#define BOARDCFG_H
|
||||
|
||||
#include "define.h"
|
||||
|
||||
static inline __attribute__((always_inline)) unsigned char SPICalculateBRG(unsigned int pb_clk, unsigned int spi_clk)
|
||||
{
|
||||
unsigned int brg;
|
||||
|
||||
brg = pb_clk / (2 * spi_clk);
|
||||
|
||||
if(pb_clk % (2 * spi_clk))
|
||||
brg++;
|
||||
|
||||
if(brg > 0x100)
|
||||
brg = 0x100;
|
||||
|
||||
if(brg)
|
||||
brg--;
|
||||
|
||||
return (unsigned char) brg;
|
||||
}
|
||||
//
|
||||
#ifdef FUBARINO_BRD
|
||||
#include "BoardCfg_Fubarino.h"
|
||||
#endif
|
||||
|
||||
//#ifdef PINGUINO_BRD
|
||||
//#include "BoardCfg_Pinguino.h"
|
||||
//#endif
|
||||
|
||||
#ifdef CHALETDUINO_BRD
|
||||
#include "BoardCfg_Chaletduino.h"
|
||||
#endif
|
||||
|
||||
#ifdef CHALETDUINO_V2_BRD
|
||||
#include "BoardCfg_ChaletduinoV2.h"
|
||||
#endif
|
||||
int InitBoard();
|
||||
|
||||
#endif /* BOARDCFG_H */
|
||||
|
||||
120
ChaloupeLora.X/Source/BoardCfg_Chaletduino.h
Normal file
120
ChaloupeLora.X/Source/BoardCfg_Chaletduino.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* File: DigitalIO_Chaletduino.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 24, 2018, 3:20 PM
|
||||
*/
|
||||
|
||||
#ifndef DIGITALIO_CHALETDUINO_H
|
||||
#define DIGITALIO_CHALETDUINO_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
//#include <plib.h>
|
||||
#define SYS_FREQ (80000000L) //Clock period = 12.5 ns
|
||||
#define PERIPHERAL_FREQ (80000000L)
|
||||
|
||||
|
||||
|
||||
//Output pins hardware definitions
|
||||
//
|
||||
#define HEARTBEAT_LED_2_PIN_DIR TRISEbits.TRISE6
|
||||
#define HEARTBEAT_LED_2_PIN LATEbits.LATE6
|
||||
#define HEARTBEAT_LED_2_TOGGLE_REG LATEINV
|
||||
#define HEARTBEAT_LED_2_SET_REG LATESET
|
||||
#define HEARTBEAT_LED_2_CLEAR_REG LATECLR
|
||||
#define HEARTBEAT_LED_2_TOGGLE_MASK _LATG_LATE6_MASK
|
||||
|
||||
#define HEARTBEAT_LED_1_PIN_DIR TRISEbits.TRISE5
|
||||
#define HEARTBEAT_LED_1_PIN LATEbits.LATE5
|
||||
#define HEARTBEAT_LED_1_TOGGLE_REG LATEINV
|
||||
#define HEARTBEAT_LED_1_SET_REG LATESET
|
||||
#define HEARTBEAT_LED_1_CLEAR_REG LATECLR
|
||||
#define HEARTBEAT_LED_1_TOGGLE_MASK _LATE_LATE5_MASK
|
||||
|
||||
#define LORA_ACTIVITY_LED_PIN_DIR TRISFbits.TRISF1
|
||||
#define LORA_ACTIVITY_LED_PIN LATFbits.LATF1
|
||||
#define LORA_ACTIVITY_LED_TOGGLE_REG LATFINV
|
||||
#define LORA_ACTIVITY_LED_SET_REG LATFSET
|
||||
#define LORA_ACTIVITY_LED_CLEAR_REG LATFCLR
|
||||
#define LORA_ACTIVITY_LED_TOGGLE_MASK _LATE_LATF1_MASK
|
||||
|
||||
// #define GP_DEBUG_1_PIN_DIR TRISEbits.TRISE5
|
||||
// #define GP_DEBUG_1_PIN LATEbits.LATE5
|
||||
// #define GP_DEBUG_2_PIN_DIR TRISEbits.TRISE6
|
||||
// #define GP_DEBUG_2_PIN LATEbits.LATE6
|
||||
|
||||
|
||||
// #define SD_CARD_DETECT_PIN_DIR TRISDbits.TRISD8
|
||||
// #define SD_CARD_DETECT_PIN LATDbits.LATD8
|
||||
|
||||
//SPI port defs
|
||||
#define SPI_SDO_PIN_DIR TRISGbits.TRISG8
|
||||
#define SPI_SDI_PIN_DIR TRISGbits.TRISG7
|
||||
#define SPI_SCK_PIN_DIR TRISGbits.TRISG6
|
||||
|
||||
//SD Card
|
||||
#define SD_SPI_SS_PIN_DIR TRISBbits.TRISB13
|
||||
#define SD_SPI_SS_PIN LATBbits.LATB13
|
||||
|
||||
//SPI Flash
|
||||
#define FLASH_SS_PIN_DIR TRISEbits.TRISE3
|
||||
#define FLASH_SS_PIN LATEbits.LATE3
|
||||
|
||||
|
||||
//Wifi (WINC3400 module)
|
||||
#define WIFI_SPI_SS_PIN_DIR TRISEbits.TRISE0
|
||||
#define WIFI_SPI_SS_PIN LATEbits.LATE0
|
||||
#define WIFI_IRQ_PIN_DIR TRISDbits.TRISD0
|
||||
#define WIFI_IRQ_PIN PORTDbits.RD0
|
||||
|
||||
// #define WIFI_SPI_CFG_PIN_DIR TRISEbits.TRISE1
|
||||
// #define WIFI_SPI_CFG_PIN LATEbits.LATE1
|
||||
#define WIFI_CHP_EN_PIN_DIR TRISEbits.TRISE2
|
||||
#define WIFI_CHP_EN_PIN LATEbits.LATE2
|
||||
#define WIFI_CHP_RST_PIN_DIR TRISEbits.TRISE4
|
||||
#define WIFI_CHP_RST_PIN LATEbits.LATE4
|
||||
|
||||
//Chalet power relay
|
||||
#define POWER_RELAY_ON_PIN_DIR TRISEbits.TRISE7
|
||||
#define POWER_RELAY_ON_PIN LATEbits.LATE7 //X2-3
|
||||
#define POWER_RELAY_OFF_PIN_DIR TRISGbits.TRISG9
|
||||
#define POWER_RELAY_OFF_PIN LATGbits.LATG9 //X3-5
|
||||
|
||||
//Harakiri relay
|
||||
#define HARAKIRI_RELAY_ON_PIN_DIR TRISBbits.TRISB0
|
||||
#define HARAKIRI_RELAY_ON_PIN LATBbits.LATB0 //X2-3
|
||||
|
||||
//12V presence detection input
|
||||
#define CHALET_12V_PRESENCE_PIN_DIR TRISBbits.TRISB15
|
||||
#define CHALET_12V_PRESENCE_PIN PORTBbits.RB15 //X2-3
|
||||
|
||||
//Battery voltage measurement (analog input)
|
||||
#define BATTERY_VOLTAGE_ANALOG_PIN_DIR TRISBbits.TRISB1
|
||||
|
||||
//Current sensor. Those pins tristate is controlled by the I2C module
|
||||
#define CURRENT_MODULE_I2C_SCL_PIN_DIR TRISDbits.TRISD3
|
||||
#define CURRENT_MODULE_I2C_SDA_PIN_DIR TRISDbits.TRISD2
|
||||
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
void InitDigitalIO(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DIGITALIO_PINGUINO_H */
|
||||
|
||||
170
ChaloupeLora.X/Source/BoardCfg_ChaletduinoV2.h
Normal file
170
ChaloupeLora.X/Source/BoardCfg_ChaletduinoV2.h
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* File: DigitalIO_Chaletduino.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 24, 2018, 3:20 PM
|
||||
*/
|
||||
|
||||
#ifndef DIGITALIO_CHALETDUINO_H
|
||||
#define DIGITALIO_CHALETDUINO_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
//#include <plib.h>
|
||||
#define SYS_FREQ (80000000L) //Clock period = 12.5 ns
|
||||
#define PERIPHERAL_FREQ (80000000L)
|
||||
|
||||
|
||||
|
||||
//Output pins hardware definitions
|
||||
//
|
||||
#define HEARTBEAT_LED_2_PIN_DIR TRISEbits.TRISE6
|
||||
#define HEARTBEAT_LED_2_PIN LATEbits.LATE6
|
||||
#define HEARTBEAT_LED_2_TOGGLE_REG LATEINV
|
||||
#define HEARTBEAT_LED_2_SET_REG LATESET
|
||||
#define HEARTBEAT_LED_2_CLEAR_REG LATECLR
|
||||
#define HEARTBEAT_LED_2_TOGGLE_MASK _LATG_LATE6_MASK
|
||||
|
||||
#define HEARTBEAT_LED_1_PIN_DIR TRISEbits.TRISE5
|
||||
#define HEARTBEAT_LED_1_PIN LATEbits.LATE5
|
||||
#define HEARTBEAT_LED_1_TOGGLE_REG LATEINV
|
||||
#define HEARTBEAT_LED_1_SET_REG LATESET
|
||||
#define HEARTBEAT_LED_1_CLEAR_REG LATECLR
|
||||
#define HEARTBEAT_LED_1_TOGGLE_MASK _LATE_LATE5_MASK
|
||||
|
||||
//#define LORA_ACTIVITY_LED_PIN_DIR TRISFbits.TRISF1
|
||||
//#define LORA_ACTIVITY_LED_PIN LATFbits.LATF1
|
||||
//#define LORA_ACTIVITY_LED_TOGGLE_REG LATFINV
|
||||
//#define LORA_ACTIVITY_LED_SET_REG LATFSET
|
||||
//#define LORA_ACTIVITY_LED_CLEAR_REG LATFCLR
|
||||
//#define LORA_ACTIVITY_LED_TOGGLE_MASK _LATE_LATF1_MASK
|
||||
|
||||
// #define GP_DEBUG_1_PIN_DIR TRISEbits.TRISE5
|
||||
// #define GP_DEBUG_1_PIN LATEbits.LATE5
|
||||
// #define GP_DEBUG_2_PIN_DIR TRISEbits.TRISE6
|
||||
// #define GP_DEBUG_2_PIN LATEbits.LATE6
|
||||
|
||||
|
||||
// #define SD_CARD_DETECT_PIN_DIR TRISDbits.TRISD8
|
||||
// #define SD_CARD_DETECT_PIN LATDbits.LATD8
|
||||
|
||||
//SPI port defs
|
||||
#define SPI_SDO_PIN_DIR TRISGbits.TRISG8
|
||||
#define SPI_SDI_PIN_DIR TRISGbits.TRISG7
|
||||
#define SPI_SCK_PIN_DIR TRISGbits.TRISG6
|
||||
|
||||
|
||||
|
||||
|
||||
//SD Card
|
||||
#define SD_SPI_SS_PIN_DIR TRISBbits.TRISB13
|
||||
#define SD_SPI_SS_PIN LATBbits.LATB13
|
||||
|
||||
//SPI Flash
|
||||
#define FLASH_SS_PIN_DIR TRISEbits.TRISE3
|
||||
#define FLASH_SS_PIN LATEbits.LATE3
|
||||
|
||||
|
||||
//Wifi (WINC3400 module)
|
||||
#define WIFI_SPI_SS_PIN_DIR TRISEbits.TRISE0
|
||||
#define WIFI_SPI_SS_PIN LATEbits.LATE0
|
||||
#define WIFI_IRQ_PIN_DIR TRISDbits.TRISD0
|
||||
#define WIFI_IRQ_PIN PORTDbits.RD0
|
||||
|
||||
// #define WIFI_SPI_CFG_PIN_DIR TRISEbits.TRISE1
|
||||
// #define WIFI_SPI_CFG_PIN LATEbits.LATE1
|
||||
#define WIFI_CHP_EN_PIN_DIR TRISEbits.TRISE2
|
||||
#define WIFI_CHP_EN_PIN LATEbits.LATE2
|
||||
#define WIFI_CHP_RST_PIN_DIR TRISEbits.TRISE4
|
||||
#define WIFI_CHP_RST_PIN LATEbits.LATE4
|
||||
|
||||
//Chalet power relay
|
||||
#define POWER_RELAY_ON_PIN_DIR TRISEbits.TRISE7
|
||||
#define POWER_RELAY_ON_PIN LATEbits.LATE7 //X2-
|
||||
#define POWER_RELAY_OFF_PIN_DIR TRISGbits.TRISG9
|
||||
#define POWER_RELAY_OFF_PIN LATGbits.LATG9 //X3-
|
||||
|
||||
//Harakiri relay
|
||||
#define HARAKIRI_RELAY_ON_PIN_DIR TRISDbits.TRISD6
|
||||
#define HARAKIRI_RELAY_ON_PIN LATDbits.LATD6
|
||||
|
||||
//12V presence detection input
|
||||
#define CHALET_12V_PRESENCE_PIN_DIR TRISBbits.TRISB15
|
||||
#define CHALET_12V_PRESENCE_PIN PORTBbits.RB15 //X2-
|
||||
|
||||
//Battery voltage measurement (analog input)
|
||||
#define BATTERY_VOLTAGE_ANALOG_PIN_DIR TRISBbits.TRISB1 //X2-7
|
||||
|
||||
// //Current sensor. Those pins tristate is controlled by the I2C module
|
||||
//#define CURRENT_MODULE_I2C_SCL_PIN_DIR TRISDbits.TRISD3
|
||||
//#define CURRENT_MODULE_I2C_SDA_PIN_DIR TRISDbits.TRISD2
|
||||
|
||||
//Onboard temperature sensor (SPI)
|
||||
#define TEMP_SENSOR_CS_PIN_DIR TRISDbits.TRISD4
|
||||
#define TEMP_SENSOR_CS_PIN LATDbits.LATD4
|
||||
#define TEMP_SENSOR_SPI_SDO_PIN_DIR TRISDbits.TRISD3
|
||||
#define TEMP_SENSOR_SPI_SDI_PIN_DIR TRISDbits.TRISD2
|
||||
#define TEMP_SENSOR_SPI_SCK_PIN_DIR TRISDbits.TRISD1
|
||||
|
||||
|
||||
//Analog (Hall effect) current sensor
|
||||
#define CURRENT_SENSOR_IN1_PIN_DIR TRISBbits.TRISB2
|
||||
#define CURRENT_SENSOR_IN2_PIN_DIR TRISBbits.TRISB0
|
||||
|
||||
//LoRa
|
||||
#define LORA_MODULE_RELAY_PIN_DIR TRISDbits.TRISD11
|
||||
#define LORA_MODULE_RELAY_PIN LATDbits.LATD11
|
||||
#define LORA_MODULE_M0_PIN_DIR TRISDbits.TRISD3 //V2
|
||||
#define LORA_MODULE_M0_PIN LATDbits.LATD3
|
||||
#define LORA_MODULE_M1_PIN_DIR TRISDbits.TRISD9
|
||||
#define LORA_MODULE_M1_PIN LATDbits.LATD9
|
||||
#define LORA_MODULE_INT_PIN_DIR TRISDbits.TRISD8
|
||||
#define LORA_MODULE_INT_PIN PORTDbits.RD8
|
||||
//#define LORA_MODULE_RX_LED_PIN_DIR TRISCbits.TRISC14
|
||||
//#define LORA_MODULE_RX_LED_PIN LATCbits.LATC14
|
||||
//#define LORA_MODULE_TX_LED_PIN_DIR TRISCbits.TRISC13
|
||||
//#define LORA_MODULE_TX_LED_PIN LATCbits.LATC13
|
||||
#define LORA_MODULE_RX_LED_PIN_DIR TRISBbits.TRISB4
|
||||
#define LORA_MODULE_RX_LED_PIN LATBbits.LATB4
|
||||
#define LORA_MODULE_TX_LED_PIN_DIR TRISFbits.TRISF1
|
||||
#define LORA_MODULE_TX_LED_PIN LATFbits.LATF1
|
||||
|
||||
|
||||
//LCD Screen
|
||||
#define LCD_RS_PIN_DIR TRISDbits.TRISD5
|
||||
#define LCD_RS_PIN LATDbits.LATD5
|
||||
#define LCD_RW_PIN_DIR TRISBbits.TRISB13
|
||||
#define LCD_RW_PIN LATBbits.LATB13
|
||||
#define LCD_E_PIN_DIR TRISBbits.TRISB12
|
||||
#define LCD_E_PIN LATBbits.LATB12
|
||||
#define LCD_DB4_PIN_DIR TRISBbits.TRISB3
|
||||
#define LCD_DB4_PIN LATBbits.LATB3
|
||||
#define LCD_DB5_PIN_DIR TRISBbits.TRISB9
|
||||
#define LCD_DB5_PIN LATBbits.LATB9
|
||||
#define LCD_DB6_PIN_DIR TRISBbits.TRISB10
|
||||
#define LCD_DB6_PIN LATBbits.LATB10
|
||||
#define LCD_DB7_PIN_DIR TRISBbits.TRISB11
|
||||
#define LCD_DB7_PIN LATBbits.LATB11
|
||||
#define LCD_SCROLL_BTN_PIN_DIR TRISBbits.TRISB5
|
||||
#define LCD_SCROLL_BTN_PIN PORTBbits.RB5
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
void InitDigitalIO(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DIGITALIO_PINGUINO_H */
|
||||
|
||||
58
ChaloupeLora.X/Source/BoardCfg_Fubarino.h
Normal file
58
ChaloupeLora.X/Source/BoardCfg_Fubarino.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* File: DigitalIO_Fubarino.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 24, 2018, 3:20 PM
|
||||
*/
|
||||
|
||||
#ifndef DIGITALIO_FUBARINO_H
|
||||
#define DIGITALIO_FUBARINO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
|
||||
#define SYS_FREQ (80000000L) //Clock period = 12.5 ns
|
||||
#define PERIPHERAL_FREQ (80000000L)
|
||||
|
||||
|
||||
|
||||
//Output pins hardware definitions
|
||||
//
|
||||
#define HEARTBEAT_LED_1_PIN_DIR TRISEbits.TRISE5
|
||||
#define HEARTBEAT_LED_1_PIN LATEbits.LATE5
|
||||
#define HEARTBEAT_LED_1_TOGGLE_REG LATEINV
|
||||
#define HEARTBEAT_LED_1_SET_REG LATESET
|
||||
#define HEARTBEAT_LED_1_CLEAR_REG LATECLR
|
||||
#define HEARTBEAT_LED_1_TOGGLE_MASK _LATE_LATE5_MASK
|
||||
|
||||
#define HEARTBEAT_LED_2_PIN_DIR TRISEbits.TRISE2
|
||||
#define HEARTBEAT_LED_2_PIN LATEbits.LATE2
|
||||
#define HEARTBEAT_LED_2_TOGGLE_REG LATEINV
|
||||
#define HEARTBEAT_LED_2_SET_REG LATESET
|
||||
#define HEARTBEAT_LED_2_CLEAR_REG LATECLR
|
||||
#define HEARTBEAT_LED_2_TOGGLE_MASK _LATE_LATE2_MASK
|
||||
|
||||
#define SD_SPI_SDO_PIN_DIR TRISGbits.TRISG8
|
||||
#define SD_SPI_CS_PIN_DIR TRISGbits.TRISG9
|
||||
#define SD_SPI_CS_PIN LATGbits.LATG9
|
||||
#define SD_SPI_SDI_PIN_DIR TRISGbits.TRISG7
|
||||
#define SD_SPI_SCK_PIN_DIR TRISGbits.TRISG6
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
void InitDigitalIO(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DIGITALIO_FUBARINO_H */
|
||||
|
||||
104
ChaloupeLora.X/Source/BoardCfg_Pinguino.h
Normal file
104
ChaloupeLora.X/Source/BoardCfg_Pinguino.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* File: DigitalIO_Pinguino.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 24, 2018, 3:20 PM
|
||||
*/
|
||||
|
||||
#ifndef DIGITALIO_PINGUINO_H
|
||||
#define DIGITALIO_PINGUINO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
|
||||
#define SYS_FREQ (80000000L) //Clock period = 12.5 ns
|
||||
#define PERIPHERAL_FREQ (80000000L)
|
||||
|
||||
|
||||
|
||||
//Output pins hardware definitions
|
||||
//
|
||||
// #define HEARTBEAT_LED_2_PIN_DIR TRISGbits.TRISG6
|
||||
// #define HEARTBEAT_LED_2_PIN LATGbits.LATG6
|
||||
// #define HEARTBEAT_LED_2_TOGGLE_REG LATGINV
|
||||
// #define HEARTBEAT_LED_2_SET_REG LATGSET
|
||||
// #define HEARTBEAT_LED_2_CLEAR_REG LATGCLR
|
||||
// #define HEARTBEAT_LED_2_TOGGLE_MASK _LATG_LATG6_MASK
|
||||
|
||||
#define HEARTBEAT_LED_1_PIN_DIR TRISDbits.TRISD1
|
||||
#define HEARTBEAT_LED_1_PIN LATDbits.LATD1
|
||||
#define HEARTBEAT_LED_1_TOGGLE_REG LATDINV
|
||||
#define HEARTBEAT_LED_1_SET_REG LATDSET
|
||||
#define HEARTBEAT_LED_1_CLEAR_REG LATDCLR
|
||||
#define HEARTBEAT_LED_1_TOGGLE_MASK _LATD_LATD1_MASK
|
||||
|
||||
|
||||
// #define SD_CARD_DETECT_PIN_DIR TRISDbits.TRISD8
|
||||
// #define SD_CARD_DETECT_PIN LATDbits.LATD8
|
||||
|
||||
//SPI port defs
|
||||
#define SPI_SDO_PIN_DIR TRISGbits.TRISG8
|
||||
#define SPI_SDI_PIN_DIR TRISGbits.TRISG7
|
||||
#define SPI_SCK_PIN_DIR TRISGbits.TRISG6
|
||||
|
||||
//SD Card
|
||||
#define SD_SPI_SS_PIN_DIR TRISBbits.TRISB13
|
||||
#define SD_SPI_SS_PIN LATBbits.LATB13
|
||||
|
||||
//Wifi (WINC3400 module)
|
||||
#define WIFI_SPI_SS_PIN_DIR TRISFbits.TRISF1
|
||||
#define WIFI_SPI_SS_PIN LATFbits.LATF1
|
||||
#define WIFI_IRQ_PIN_DIR TRISDbits.TRISD0
|
||||
#define WIFI_IRQ_PIN PORTDbits.RD0
|
||||
#define WIFI_WAKE_PIN_DIR TRISEbits.TRISE0
|
||||
#define WIFI_WAKE_PIN LATEbits.LATE0
|
||||
#define WIFI_SPI_CFG_PIN_DIR TRISEbits.TRISE1
|
||||
#define WIFI_SPI_CFG_PIN LATEbits.LATE1
|
||||
#define WIFI_CHP_EN_PIN_DIR TRISEbits.TRISE2
|
||||
#define WIFI_CHP_EN_PIN LATEbits.LATE2
|
||||
#define WIFI_CHP_RST_PIN_DIR TRISEbits.TRISE3
|
||||
#define WIFI_CHP_RST_PIN LATEbits.LATE3
|
||||
|
||||
//Control knob encoder
|
||||
#define KNOB_PH_A_PIN_DIR TRISDbits.TRISD8
|
||||
#define KNOB_PH_A_PIN PORTDbits.RD8
|
||||
#define KNOB_PH_B_PIN_DIR TRISDbits.TRISD7
|
||||
#define KNOB_PH_B_PIN PORTDbits.RD7
|
||||
#define KNOB_TGLE_BTN_PIN_DIR TRISDbits.TRISD11
|
||||
#define KNOB_TGLE_BTN_PIN PORTDbits.RD11
|
||||
|
||||
//Led controller PWM
|
||||
#define LED_PWM_PIN_DIR TRISDbits.TRISD2
|
||||
#define LED_PWM_PIN LATDbits.LATD2
|
||||
#define LED_PWM_VAL_REG OC3RS
|
||||
|
||||
|
||||
//Misc CPU or board related defines
|
||||
#define PWM_RANGE_MAX 16000
|
||||
|
||||
#define GP_DEBUG_1_PIN_DIR TRISEbits.TRISE5
|
||||
#define GP_DEBUG_1_PIN LATEbits.LATE5
|
||||
#define GP_DEBUG_2_PIN_DIR TRISEbits.TRISE6
|
||||
#define GP_DEBUG_2_PIN LATEbits.LATE6
|
||||
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
void InitDigitalIO(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DIGITALIO_PINGUINO_H */
|
||||
|
||||
985
ChaloupeLora.X/Source/BootloaderInterface.c
Normal file
985
ChaloupeLora.X/Source/BootloaderInterface.c
Normal file
@ -0,0 +1,985 @@
|
||||
//#include <proc/p32mx440f256h.h>
|
||||
|
||||
#include "BootloaderInterface.h"
|
||||
#include "BootloaderProtocol.h"
|
||||
#include "ProtocolDefs.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "timer.h"
|
||||
#include "WiFiCtrl.h"
|
||||
#include "SPI_Flash.h"
|
||||
#include "FlashMapping.h"
|
||||
#include "NetworkProtocol.h"
|
||||
#include "Syslog.h"
|
||||
#include "checksum.h"
|
||||
#include "FlashMapping.h"
|
||||
|
||||
|
||||
#define BOOTLOADER_FLASH_ERASE_POLL_TIMEOUT 25//100 //ms
|
||||
#define BOOTLOADER_FLASH_ERASE_MAX_POLL_COUNT 40//10 //One sector should not take more than 1s to erase...
|
||||
#define BOOTLOADER_FLASH_WRITE_POLL_TIMEOUT 25//100 //ms
|
||||
#define BOOTLOADER_FLASH_WRITE_MAX_POLL_COUNT 40//10 //One sector should not take more than 1s to erase...
|
||||
|
||||
|
||||
unsigned char BootloaderBuffer[300];
|
||||
int BootloaderInterfaceState;
|
||||
|
||||
|
||||
int DataChunkWritten;
|
||||
int CurDataChunkIndex;
|
||||
int FirmwareUploaded;
|
||||
int CurDataChunkSize;
|
||||
|
||||
int BooloaderFlashEraseState;
|
||||
int BootloaderFlashErased;
|
||||
unsigned int BootloaderCurFlashEraseAddress;
|
||||
int BooloaderFlashErasePollCount;
|
||||
|
||||
int BootloaderFlashWriteState;
|
||||
unsigned int BootloaderCurFlashWriteAddress;
|
||||
int BootloaderFlashWritePollCount;
|
||||
int BootloaderFirmwareChunkWriteCount;
|
||||
char* BootloaderFlashWriteDataPtr;
|
||||
|
||||
|
||||
int BootloaderInterfaceInit()
|
||||
{
|
||||
BootloaderProtocolInit();
|
||||
BootloaderResetStateMachine();
|
||||
BootloaderCheckFlashBootloaderData();
|
||||
update_crc_32(0,0); //Force to populate the CRC32 table...
|
||||
return 1;
|
||||
}
|
||||
|
||||
void BootloaderInterfaceTick()
|
||||
{
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_TICK_EVENT,0);
|
||||
}
|
||||
|
||||
void BootloaderExecuteCmd(char Cmd,bool CRCValid)
|
||||
{
|
||||
unsigned char *DataBufPtr = BootloaderProtocolGetDataBufferPtr();
|
||||
if(CRCValid == 0)
|
||||
{
|
||||
printf("Bootloader received a frame with invalid CRC\n");
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_INVALID_CRC_CMD);
|
||||
return;
|
||||
}
|
||||
switch(Cmd)
|
||||
{
|
||||
case BOOTLOADER_HEARTBEAT_REQUEST:
|
||||
{
|
||||
printf("Bootloader Heartbeat Request\n");
|
||||
*DataBufPtr = 1;
|
||||
BootloaderProtocolSendFrame(BOOTLOADER_HEARTBEAT_RESPONSE,1);
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_ERASE_BOOTLOADER_FLASH_REQUEST:
|
||||
{
|
||||
printf("BOOTLOADER_ERASE_BOOTLOADER_FLASH_REQUEST\n");
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_ERASE_FLASH_CMD);
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_INIT_UPLOAD_REQUEST:
|
||||
{
|
||||
printf("BOOTLOADER_INIT_UPLOAD_REQUEST\n");
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_INIT_UPLOAD_CMD);
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_GET_STATE_REQUEST:
|
||||
{
|
||||
printf("BOOTLOADER_GET_STATE_REQUEST\n");
|
||||
BootloaderProtocolSendBootloaderState((char)BootloaderInterfaceState);
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SEND_DATA_CHUNK_REQUEST:
|
||||
{
|
||||
// printf("BOOTLOADER_SEND_DATA_CHUNK_REQUEST\n");
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_NEW_DATA_CHUNK_CMD);
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_UPLOAD_FINISHED_REQUEST:
|
||||
{
|
||||
printf("BOOTLOADER_UPLOAD_FINISHED_REQUEST\n");
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_UPLOAD_FINISHED_CMD);
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_EXECUTE_UPGRAGE_REQUEST:
|
||||
{
|
||||
printf("BOOTLOADER_EXECUTE_UPGRAGE_REQUEST\n");
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_EXECUTE_UPGRAGE_CMD);
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_ABORT_OPERATION_REQUEST:
|
||||
{
|
||||
printf("BOOTLOADER_ABORT_OPERATION_REQUEST\n");
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_ABORT_CMD);
|
||||
}
|
||||
case BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_REQUEST:
|
||||
{
|
||||
printf("BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_REQUEST\n");
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_CHECK_FLASH_CMD);
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_GET_STORED_FIRMWARE_INFO_REQUEST:
|
||||
{
|
||||
printf("BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_REQUEST\n");
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_GET_FIRMWARE_DATA_CMD);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BootloaderCRCError(char Cmd, int RxCRC, int ExpectedCRC)
|
||||
{
|
||||
printf("BootloaderProtocol detected a CRC error. Cmd: %d, RxCRC:0x%x, Expected:[0x%x]\n",Cmd,RxCRC,ExpectedCRC);
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_INVALID_CRC_CMD);
|
||||
}
|
||||
|
||||
void BootloaderInterfaceStateMachine(int Event, int Param)
|
||||
{
|
||||
|
||||
switch(BootloaderInterfaceState)
|
||||
{
|
||||
case BOOTLOADER_STANDBY_STATE:
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case BOOTLOADER_TICK_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_NEW_CMD_EVENT:
|
||||
{
|
||||
if(Param == BOOTLOADER_SM_ACTIVATE_CMD)
|
||||
{
|
||||
BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE;
|
||||
printf("Bootloader Interface going into active state\n");
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_TIMEOUT_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_ACTIVE_STATE:
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case BOOTLOADER_TICK_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_NEW_CMD_EVENT:
|
||||
{
|
||||
switch(Param)
|
||||
{
|
||||
case BOOTLOADER_SM_ERASE_FLASH_CMD:
|
||||
{
|
||||
ResetBootloaderFlashEraseStateMachine(); //Setup the state machine
|
||||
BootloaderProtocolSendACK(BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESPONSE);
|
||||
BootloaderInterfaceState = BOOTLOADER_ERASE_FLASH_STATE;
|
||||
printf("Bootloader Interface going into Erase Flash state\n");
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SM_INIT_UPLOAD_CMD:
|
||||
{
|
||||
|
||||
if(BootloaderFlashErased == 0)
|
||||
{
|
||||
BootloaderProtocolSendInitUploadResponse(BOOTLOADEDR_INIT_TRANSFER_ERROR_FLASH_NOT_ERASED);
|
||||
}
|
||||
else
|
||||
{
|
||||
BootloaderProtocolSendInitUploadResponse(BOOTLOADEDR_INIT_TRANSFER_OK);
|
||||
|
||||
//TODO: Shall we prepare something before??
|
||||
BootloaderProtocolSendACK(BOOTLOADER_READY_FOR_DATA_RESPONSE);
|
||||
|
||||
BootloaderInterfaceState = BOOTLOADER_RECEIVING_FIRMWARE_STATE;
|
||||
printf("Bootloader Interface going into Firmware RX state\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SM_ABORT_CMD:
|
||||
{
|
||||
//TODO invalidate data in Flash
|
||||
printf("Aborting upload, going into STANDBY mode\n");
|
||||
BootloaderResetStateMachine();
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SM_EXECUTE_UPGRAGE_CMD:
|
||||
{
|
||||
if(BootloaderCheckFlashBootloaderData() == RET_OK)
|
||||
{
|
||||
BootloaderProtocolSendACK(BOOTLOADER_EXECUTE_UPGRADE_RESPONSE);
|
||||
printf("Bootloader will now upgrade and reboot!!\n");
|
||||
|
||||
char Flags[2];
|
||||
Flags[BOOTLOADER_FLAGS_ACTION_FLAG_INDEX] = BOOTLOADER_ACTION_FLASH_FIRMWARE_VALUE;
|
||||
Flags[BOOTLOADER_FLAGS_ACTION_VALIDATOR_INDEX] = BOOTLOADER_FLASH_FIRMWARE_VALIDATOR;
|
||||
SPIFlashWriteBuffer(Flags,2,FLASH_BTLDR_FLAGS_ADDRESS);
|
||||
|
||||
Sleep(100);
|
||||
TurnOFFWiFi();
|
||||
Sleep(100);
|
||||
SoftReset();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
BootloaderProtocolSendNACK(BOOTLOADER_EXECUTE_UPGRADE_RESPONSE);
|
||||
printf("Bootloader upgrade request denied: Firmware not uploaded\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SM_CHECK_FLASH_CMD:
|
||||
{
|
||||
if(BootloaderCheckFlashBootloaderData() == RET_OK)
|
||||
{
|
||||
BootloaderProtocolSendFlashCheckResult(FLASH_CHECK_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
BootloaderProtocolSendFlashCheckResult(FLASH_CHECK_FAILED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SM_GET_FIRMWARE_DATA_CMD:
|
||||
{
|
||||
char Response[21];
|
||||
memset(Response,0xFF,sizeof(Response));
|
||||
|
||||
if(BootloaderCheckFlashBootloaderData() != RET_OK)
|
||||
{
|
||||
Response[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Response[0] = 1;
|
||||
BootloaderIntToBytes(&Response[1],mStoredBootloaderInfo.Firmwareflags);
|
||||
BootloaderIntToBytes(&Response[5],mStoredBootloaderInfo.NbRecords);
|
||||
BootloaderIntToBytes(&Response[9],mStoredBootloaderInfo.FirmwareSize);
|
||||
BootloaderIntToBytes(&Response[13],mStoredBootloaderInfo.Versioncode);
|
||||
BootloaderIntToBytes(&Response[17],mStoredBootloaderInfo.DataCRC32);
|
||||
}
|
||||
|
||||
BootloaderProtocolSendStoredFirmwareInfoResponse(Response,sizeof(Response));
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//SEND NACK
|
||||
BootloaderProtocolSendNACK(Param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_TIMEOUT_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_ERASE_FLASH_STATE:
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case BOOTLOADER_TICK_EVENT:
|
||||
{
|
||||
int res = BootloaderFlashEraseStateMachine(BOOTLOADER_FLASH_ERASE_SM_TICK_EVENT);
|
||||
switch(res)
|
||||
{
|
||||
case BOOTLOADER_FLASH_ERASE_RUNNING_RES:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_ERASE_FINISHED_RES:
|
||||
{
|
||||
printf("Flash erase finished. Bootloader Interface going into Active state\n");
|
||||
BootloaderProtocolSendACK(BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESULT_RESPONSE); //TODO: send result instead
|
||||
BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE;
|
||||
BootloaderFlashErased = 1;
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_ERASE_ERROR_RES:
|
||||
{
|
||||
printf("Flash erase error. Bootloader Interface going into Active state\n");
|
||||
BootloaderProtocolSendNACK(BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESULT_RESPONSE); //TODO: send result instead
|
||||
BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE;
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_ERASE_ABORT_RES:
|
||||
{
|
||||
printf("Flash erase abort. Bootloader Interface going into Active state\n");
|
||||
BootloaderProtocolSendNACK(BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESULT_RESPONSE); //TODO: send result instead
|
||||
BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_NEW_CMD_EVENT:
|
||||
{
|
||||
switch(Param)
|
||||
{
|
||||
case BOOTLOADER_SM_ABORT_CMD:
|
||||
{
|
||||
//TODO: stop erasing and reset SM.
|
||||
//TODO invalidate data in Flash
|
||||
BootloaderFlashEraseStateMachine(BOOTLOADER_FLASH_ERASE_SM_ABORT_EVENT);
|
||||
printf("Aborting Flash erase, going into STANDBY mode\n");
|
||||
BootloaderResetStateMachine();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//SEND NACK
|
||||
BootloaderProtocolSendNACK(Param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_TIMEOUT_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_RECEIVING_FIRMWARE_STATE:
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case BOOTLOADER_TICK_EVENT:
|
||||
{
|
||||
int res = BootloaderFlashWriteStateMachine(BOOTLOADER_FLASH_WRITE_SM_TICK_EVENT);
|
||||
switch(res)
|
||||
{
|
||||
case BOOTLOADER_FLASH_WRITING_RES:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_WRITE_FINISHED_RES:
|
||||
{
|
||||
BootloaderProtocolSendDataChunkResult(BOOTLOADER_CHUNK_TRANSFER_SUCCESS,CurDataChunkIndex);
|
||||
printf("Bootloader Chunk %d successfuly written to flash\n",CurDataChunkIndex);
|
||||
CurDataChunkIndex++;
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_WRITE_ERROR_RES:
|
||||
{
|
||||
BootloaderProtocolSendDataChunkResult(BOOTLOADER_CHUNK_TRANSFER_ERROR_FLASH_ERROR,CurDataChunkIndex);
|
||||
BootloaderResetStateMachine();
|
||||
printf("Bootloader Flash write error. Aborting and going into STANDBY state\n");
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_WRITE_ABORT_RES:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_NEW_CMD_EVENT:
|
||||
{
|
||||
switch(Param)
|
||||
{
|
||||
case BOOTLOADER_SM_NEW_DATA_CHUNK_CMD:
|
||||
{
|
||||
|
||||
//TODO:Check data validity
|
||||
//TODO: Write data to flash
|
||||
|
||||
//Extract index from buffer
|
||||
unsigned int DataChunkIndex = 0;
|
||||
unsigned int DataChunkSize = 0;
|
||||
DataChunkSize = 0;
|
||||
|
||||
// DataChunkIndex = BootloaderBuffer[0];
|
||||
// DataChunkIndex <<= 8;
|
||||
// DataChunkIndex += BootloaderBuffer[1];
|
||||
// DataChunkIndex <<= 8;
|
||||
// DataChunkIndex += BootloaderBuffer[2];
|
||||
// DataChunkIndex <<= 8;
|
||||
// DataChunkIndex += BootloaderBuffer[3];
|
||||
DataChunkIndex = BootloaderBytesToInt(&BootloaderBuffer[0]);
|
||||
|
||||
// DataChunkSize = BootloaderBuffer[4];
|
||||
// DataChunkSize <<= 8;
|
||||
// DataChunkSize += BootloaderBuffer[5];
|
||||
// DataChunkSize <<= 8;
|
||||
// DataChunkSize += BootloaderBuffer[6];
|
||||
// DataChunkSize <<= 8;
|
||||
// DataChunkSize += BootloaderBuffer[7];
|
||||
DataChunkSize = BootloaderBytesToInt(&BootloaderBuffer[4]);
|
||||
|
||||
|
||||
BootloaderFlashWriteDataPtr = &BootloaderBuffer[8];
|
||||
|
||||
//Check CRC
|
||||
|
||||
|
||||
|
||||
if(CurDataChunkIndex != DataChunkIndex)
|
||||
{
|
||||
//Error... abort.
|
||||
BootloaderProtocolSendDataChunkResult(BOOTLOADER_CHUNK_TRANSFER_ERROR_INVALID_CHUNK_INDEX,CurDataChunkIndex);
|
||||
printf("Bootloader Interface ABORTING UPLOAD. Received invalid chunk index. Rx: [%d] - Expected: [%d]\n", DataChunkIndex,CurDataChunkIndex);
|
||||
ResetBootloaderFlashWriteStateMachine();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
CurDataChunkSize = DataChunkSize;
|
||||
BootloaderFlashWriteStateMachine(BOOTLOADER_FLASH_WRITE_SM_NEW_BUFFER_EVENT);
|
||||
printf("Bootloader Interface. Rx new data chunk. Writing to flash. Index: %d\n", DataChunkIndex);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SM_INVALID_CRC_CMD:
|
||||
{
|
||||
//BootloaderProtocol determined the CRC of the chunk was invalid.
|
||||
BootloaderProtocolSendDataChunkResult(BOOTLOADER_CHUNK_TRANSFER_ERROR_RESEND,CurDataChunkIndex);
|
||||
printf("Bootloader Interface invalid chunk CRC. Requesting resend chunk index [%d]\n", CurDataChunkIndex);
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SM_UPLOAD_FINISHED_CMD:
|
||||
{
|
||||
printf("Bootloader Interface firmware upload finished. Check flash integrity.\n");
|
||||
|
||||
if(BootloaderCheckFlashBootloaderData() == RET_OK)
|
||||
{
|
||||
BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE;
|
||||
//BootloaderProtocolSendACK(BOOTLOADER_UPLOAD_FINISHED_RESPONSE);
|
||||
BootloaderProtocolSendFirmwareUploadResult(BOOTLOADER_UPLOAD_SUCCESS);
|
||||
FirmwareUploaded = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Firmware integrity check failed. Going back to STANDBY state.\n");
|
||||
// BootloaderProtocolSendNACK(BOOTLOADER_UPLOAD_FINISHED_RESPONSE);
|
||||
BootloaderProtocolSendFirmwareUploadResult(BOOTLOADER_UPLOAD_FAILED_FLASH_VERIFICATION_ERROR);
|
||||
BootloaderResetStateMachine();
|
||||
FirmwareUploaded = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SM_ABORT_CMD:
|
||||
{
|
||||
//TODO invalidate data in Flash
|
||||
printf("Bootloader aborting firmware download. Going back to STANDBY state\n");
|
||||
BootloaderFlashWriteStateMachine(BOOTLOADER_FLASH_WRITE_SM_ABORT_EVENT);
|
||||
BootloaderResetStateMachine();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//WHAT TO DO???
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_TIMEOUT_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_SENDING_FIRMWARE_COPY_STATE:
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case BOOTLOADER_TICK_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_NEW_CMD_EVENT:
|
||||
{
|
||||
switch(Param)
|
||||
{
|
||||
case BOOTLOADER_SM_ABORT_CMD:
|
||||
{
|
||||
//TODO invalidate data in Flash
|
||||
printf("Aborting upload, going into STANDBY mode\n");
|
||||
BootloaderResetStateMachine();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//SEND NACK
|
||||
BootloaderProtocolSendNACK(Param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_TIMEOUT_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_PRINTING_FIRMWARE_STATE:
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case BOOTLOADER_TICK_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_NEW_CMD_EVENT:
|
||||
{
|
||||
switch(Param)
|
||||
{
|
||||
case BOOTLOADER_SM_ABORT_CMD:
|
||||
{
|
||||
//TODO invalidate data in Flash
|
||||
printf("Aborting upload, going into STANDBY mode\n");
|
||||
BootloaderResetStateMachine();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//SEND NACK
|
||||
BootloaderProtocolSendNACK(Param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_TIMEOUT_EVENT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BootloaderResetStateMachine()
|
||||
{
|
||||
BootloaderInterfaceState = BOOTLOADER_STANDBY_STATE;
|
||||
DataChunkWritten = 0;
|
||||
CurDataChunkIndex = 0;
|
||||
FirmwareUploaded = 0;
|
||||
CurDataChunkIndex = 0;
|
||||
FirmwareUploaded = 0;
|
||||
CurDataChunkSize = 0;
|
||||
|
||||
|
||||
ResetBootloaderFlashEraseStateMachine();
|
||||
ResetBootloaderFlashWriteStateMachine();
|
||||
|
||||
CloseBootloaderServer();
|
||||
}
|
||||
|
||||
void BootloaderActivateBootloader()
|
||||
{
|
||||
OpenBootloaderServer();
|
||||
BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_ACTIVATE_CMD);
|
||||
}
|
||||
void BootloaderDeactivateBootloader()
|
||||
{
|
||||
BootloaderResetStateMachine();
|
||||
// CloseBootloaderServer();
|
||||
// BootloaderIterfaceStateMachine(BOOTLOADER_SM_ABORT_CMD,0);
|
||||
}
|
||||
|
||||
int BootloaderFlashEraseStateMachine(int event)
|
||||
{
|
||||
if(event == BOOTLOADER_FLASH_ERASE_SM_ABORT_EVENT)
|
||||
{
|
||||
ResetBootloaderFlashEraseStateMachine();
|
||||
return BOOTLOADER_FLASH_ERASE_ABORT_RES;
|
||||
}
|
||||
|
||||
switch(BooloaderFlashEraseState)
|
||||
{
|
||||
case BOOTLOADER_FLASH_ERASE_SECTOR_STATE:
|
||||
{
|
||||
if(SPIFlashErase64KSector(BootloaderCurFlashEraseAddress,0) == RET_ERROR)
|
||||
{
|
||||
|
||||
printf("Bootloader Interface Erasing sector %0x%x\n", BootloaderCurFlashEraseAddress);
|
||||
BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_ERROR_STATE;
|
||||
return BOOTLOADER_FLASH_ERASE_ERROR_RES;
|
||||
}
|
||||
BooloaderFlashErasePollCount = 0;
|
||||
TimerStart(BOOTLOADER_FLASH_POLL_TIMER,BOOTLOADER_FLASH_ERASE_POLL_TIMEOUT);
|
||||
BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_WAIT_FOR_SECTOR_DONE;
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_ERASE_WAIT_FOR_SECTOR_DONE:
|
||||
{
|
||||
if(IsTimerExpired(BOOTLOADER_FLASH_POLL_TIMER) == 1)
|
||||
{
|
||||
if(SPIFlashCheckBusy() == 0) //sector erased
|
||||
{
|
||||
if(BootloaderCurFlashEraseAddress == FLASH_BTLDR_FIRMWARE_LAST_64K_SECTOR_ADD)
|
||||
{
|
||||
//Whole bootloader partition is erased.
|
||||
printf("Bootloader Interface: Last sector 0x%x erased after %d polls\n",BootloaderCurFlashEraseAddress,BooloaderFlashErasePollCount);
|
||||
BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_FINISHED_STATE;
|
||||
return BOOTLOADER_FLASH_ERASE_FINISHED_RES;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Bootloader Interface sector 0x%x erased after %d polls\n",BootloaderCurFlashEraseAddress,BooloaderFlashErasePollCount);
|
||||
BootloaderCurFlashEraseAddress += SPI_FLASH_64K_SECTOR_SIZE;
|
||||
BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_SECTOR_STATE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BooloaderFlashErasePollCount >= BOOTLOADER_FLASH_ERASE_MAX_POLL_COUNT)
|
||||
{
|
||||
printf("Bootloader Interface Flash erase error. Max poll count reached : %d!!!\n",BooloaderFlashErasePollCount);
|
||||
BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_ERROR_STATE;
|
||||
return BOOTLOADER_FLASH_ERASE_ERROR_RES;
|
||||
}
|
||||
else
|
||||
{
|
||||
TimerStart(BOOTLOADER_FLASH_POLL_TIMER,BOOTLOADER_FLASH_ERASE_POLL_TIMEOUT);
|
||||
BooloaderFlashErasePollCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_ERASE_CHECKBACK_STATE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_ERASE_FINISHED_STATE:
|
||||
{
|
||||
return BOOTLOADER_FLASH_ERASE_FINISHED_RES;
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_ERASE_ERROR_STATE:
|
||||
{
|
||||
return BOOTLOADER_FLASH_ERASE_ERROR_RES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return BOOTLOADER_FLASH_ERASE_RUNNING_RES;
|
||||
}
|
||||
|
||||
int ResetBootloaderFlashEraseStateMachine()
|
||||
{
|
||||
BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_SECTOR_STATE;
|
||||
BootloaderCurFlashEraseAddress = FLASH_BTLDR_FIRMWARE_START_ADDRESS;
|
||||
BooloaderFlashErasePollCount = 0;
|
||||
BootloaderFlashErased = 0;
|
||||
}
|
||||
|
||||
int BootloaderFlashWriteStateMachine(int event)
|
||||
{
|
||||
switch(BootloaderFlashWriteState)
|
||||
{
|
||||
case BOOTLOADER_FLASH_WRITE_STANDBY_STATE:
|
||||
{
|
||||
if(event == BOOTLOADER_FLASH_WRITE_SM_TICK_EVENT)
|
||||
{
|
||||
//TODO: timeout
|
||||
// return BOOTLOADER_FLASH_WRITE_ERROR_RES;
|
||||
}
|
||||
else if(event == BOOTLOADER_FLASH_WRITE_SM_NEW_BUFFER_EVENT)
|
||||
{
|
||||
// printf("Starting writing data to Flash\nFlash Address : Data\n");
|
||||
BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_BUFFER_STATE;
|
||||
BootloaderFirmwareChunkWriteCount = 0;
|
||||
return BOOTLOADER_FLASH_WRITING_RES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_WRITE_BUFFER_STATE:
|
||||
{
|
||||
if(BootloaderFlashWriteDataPtr == 0)
|
||||
{
|
||||
ResetBootloaderFlashWriteStateMachine();
|
||||
return BOOTLOADER_FLASH_WRITE_ERROR_RES;
|
||||
}
|
||||
|
||||
while(BootloaderFirmwareChunkWriteCount < CurDataChunkSize)
|
||||
{
|
||||
|
||||
//printf("%d : 0x%x\n",(BootloaderCurFlashWriteAddress-FLASH_BTLDR_FIRMWARE_START_ADDRESS),(unsigned int)*BootloaderFlashWriteDataPtr);
|
||||
if(SPIFlashWriteByte(BootloaderCurFlashWriteAddress++,*BootloaderFlashWriteDataPtr++,1) == RET_ERROR)
|
||||
{
|
||||
printf("Bootloader flash error. Aborting and going back to STANDBY\n");
|
||||
BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_ERROR_STATE;
|
||||
return BOOTLOADER_FLASH_WRITE_ERROR_RES;
|
||||
}
|
||||
|
||||
|
||||
int cnt = 0;
|
||||
while(1)
|
||||
{
|
||||
if(SPIFlashCheckBusy() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(cnt++ > 200)
|
||||
{
|
||||
printf("Bootloader flash write timeout error. Aborting and going back to STANDBY\n");
|
||||
BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_ERROR_STATE;
|
||||
return BOOTLOADER_FLASH_WRITE_ERROR_RES;
|
||||
}
|
||||
}
|
||||
|
||||
BootloaderFirmwareChunkWriteCount++;
|
||||
}
|
||||
|
||||
BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_WAIT_FOR_BYTE_DONE;
|
||||
return BOOTLOADER_FLASH_WRITING_RES;
|
||||
|
||||
// BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_STANDBY_STATE;
|
||||
// return BOOTLOADER_FLASH_WRITE_FINISHED_RES;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_WRITE_WAIT_FOR_BYTE_DONE:
|
||||
{
|
||||
if(event == BOOTLOADER_FLASH_WRITE_SM_TICK_EVENT)
|
||||
{
|
||||
BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_STANDBY_STATE;
|
||||
return BOOTLOADER_FLASH_WRITE_FINISHED_RES;
|
||||
// if(SyslogIsBufferEmpty() == RET_OK)
|
||||
// {
|
||||
// BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_STANDBY_STATE;
|
||||
// return BOOTLOADER_FLASH_WRITE_FINISHED_RES;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return BOOTLOADER_FLASH_WRITING_RES;
|
||||
// }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_WRITE_CHECKBACK_STATE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_WRITE_FINISHED_STATE:
|
||||
{
|
||||
return BOOTLOADER_FLASH_WRITE_FINISHED_RES;
|
||||
break;
|
||||
}
|
||||
case BOOTLOADER_FLASH_WRITE_ERROR_STATE:
|
||||
{
|
||||
return BOOTLOADER_FLASH_WRITE_ERROR_RES;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int BootloaderPrintFlashData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int BootloaderCheckFlashBootloaderData()
|
||||
{
|
||||
|
||||
unsigned char FlashData[700];
|
||||
unsigned int FlashAddress = FLASH_BTLDR_FIRMWARE_START_ADDRESS;
|
||||
unsigned int FileHeaderCode, FirmwareFlags, NbRecords, FirmwareSize, VersionCode, CRC32;
|
||||
unsigned int ComputedCRC32 = CRC_START_32;
|
||||
|
||||
//SPIFlashReadBuffer(FlashData,700,FlashAddress);
|
||||
|
||||
|
||||
printf("Checking Flash bootloader data integrity... \n");
|
||||
SPIFlashReadBuffer(FlashData,FLASH_BTLDR_HEADER_SIZE,FlashAddress);
|
||||
|
||||
FileHeaderCode = BootloaderBytesToInt(FlashData);
|
||||
FirmwareFlags = BootloaderBytesToInt(&FlashData[4]);
|
||||
NbRecords = BootloaderBytesToInt(&FlashData[8]);
|
||||
FirmwareSize = BootloaderBytesToInt(&FlashData[12]);
|
||||
VersionCode = BootloaderBytesToInt(&FlashData[16]);
|
||||
CRC32 = BootloaderBytesToInt(&FlashData[20]);
|
||||
|
||||
mStoredBootloaderInfo.Firmwareflags = FirmwareFlags;
|
||||
mStoredBootloaderInfo.NbRecords = NbRecords;
|
||||
mStoredBootloaderInfo.FirmwareSize = FirmwareSize;
|
||||
mStoredBootloaderInfo.Versioncode = VersionCode;
|
||||
mStoredBootloaderInfo.DataCRC32 = CRC32;
|
||||
|
||||
//printf("File Header: Code:[0x%x] - Flags:[0x%x] - Nb Records:[%d] - Firmware Size:[%d] - Version:[0x%x] - CRC32:[0x%x]\n",FileHeaderCode,FirmwareFlags,NbRecords,FirmwareSize,VersionCode,CRC32);
|
||||
|
||||
|
||||
if(FileHeaderCode != BOOTLOADER_FILE_HEADER_CODE)
|
||||
{
|
||||
// printf("Invalid file header code, aborting\n");
|
||||
return RET_ERROR;
|
||||
}
|
||||
if(NbRecords == 0)
|
||||
{
|
||||
// printf("No records in file (NbRecords = 0), aborting\n");
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
FlashAddress += FLASH_BTLDR_HEADER_SIZE; //point to the start of bootloader data
|
||||
|
||||
int CurRecord = 0;
|
||||
bool Done = false;
|
||||
int RecHeader, RecSize, RecStartAddress;
|
||||
|
||||
//Check the header of each sector.
|
||||
while(Done == false)
|
||||
{
|
||||
SPIFlashReadBuffer(FlashData,12,FlashAddress);
|
||||
RecHeader = BootloaderBytesToInt(FlashData);
|
||||
RecSize = BootloaderBytesToInt(&FlashData[4]);
|
||||
RecStartAddress = BootloaderBytesToInt(&FlashData[8]);
|
||||
FlashAddress += 12;
|
||||
|
||||
|
||||
if(RecHeader != BOOTLOADER_RECORD_HEADER_CODE)
|
||||
{
|
||||
// printf("Error in record #%d. Invalid header code : [0x%x]\n",CurRecord,RecHeader);
|
||||
return RET_ERROR;
|
||||
}
|
||||
if(RecSize == 0)
|
||||
{
|
||||
// printf("Error in record #%d. Invalid record size (RecordSize = 0) \n");
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
// printf("Record #%d OK! Header:[0x%x] - Size:[%d] - Start Address:[0x%x]\n",CurRecord,RecHeader,RecSize,RecStartAddress);
|
||||
// while(SyslogIsBufferEmpty() == RET_ERROR)
|
||||
// {
|
||||
// SyslogTick();
|
||||
// TickWiFi();
|
||||
// }
|
||||
|
||||
CurRecord++;
|
||||
if(CurRecord == NbRecords)
|
||||
{
|
||||
// Done = true;
|
||||
// printf("All records checked OK! Computing CRC...\n");
|
||||
Done = true;
|
||||
break;
|
||||
//return RET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
FlashAddress += RecSize;
|
||||
}
|
||||
}
|
||||
|
||||
//Now, compute whole data CRC
|
||||
FlashAddress = FLASH_BTLDR_FIRMWARE_START_ADDRESS + FLASH_BTLDR_HEADER_SIZE;
|
||||
char Byte;
|
||||
int i;
|
||||
for(i = 0; i < FirmwareSize; i++)
|
||||
{
|
||||
SPIFlashReadBuffer(&Byte,1,FlashAddress++);
|
||||
ComputedCRC32 = update_crc_32(ComputedCRC32,Byte);
|
||||
}
|
||||
ComputedCRC32 ^= 0xffffffffL;
|
||||
|
||||
if(ComputedCRC32 == CRC32)
|
||||
{
|
||||
// printf("CRC32 matches. Computed:[0x%x] - Expected:[0x%x]\n",ComputedCRC32,CRC32);
|
||||
// printf("Flash check success. Firmware is valid\n");
|
||||
return RET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("CRC32 mismatch. Computed:[0x%x] - Expected:[0x%x]\n",ComputedCRC32,CRC32);
|
||||
// printf("Flash check failed.\n");
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return RET_OK;
|
||||
|
||||
}
|
||||
|
||||
int ResetBootloaderFlashWriteStateMachine()
|
||||
{
|
||||
BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_STANDBY_STATE;
|
||||
BootloaderCurFlashWriteAddress = FLASH_BTLDR_FIRMWARE_START_ADDRESS;
|
||||
BootloaderFlashWritePollCount = 0;
|
||||
BootloaderFirmwareChunkWriteCount = 0;
|
||||
BootloaderFlashWriteDataPtr = 0;
|
||||
BootloaderFirmwareChunkWriteCount = 0;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int BootloaderBytesToInt(unsigned char *Bytes)
|
||||
{
|
||||
if(Bytes == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Output = Bytes[0];
|
||||
Output <<= 8;
|
||||
Output += Bytes[1];
|
||||
Output <<= 8;
|
||||
Output += Bytes[2];
|
||||
Output <<= 8;
|
||||
Output += Bytes[3];
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
int BootloaderIntToBytes(unsigned char *Buf, unsigned int Input)
|
||||
{
|
||||
if(Buf == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Buf[3] = (unsigned char)(Input & 0xFF);
|
||||
Input >>= 8;
|
||||
Buf[2] = (unsigned char)(Input & 0xFF);
|
||||
Input >>= 8;
|
||||
Buf[1] = (unsigned char)(Input & 0xFF);
|
||||
Input >>= 8;
|
||||
Buf[0] = (unsigned char)(Input & 0xFF);
|
||||
Input >>= 8;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
182
ChaloupeLora.X/Source/BootloaderInterface.h
Normal file
182
ChaloupeLora.X/Source/BootloaderInterface.h
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* File: ChaletPowerRelay.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 30, 2018, 7:33 PM
|
||||
*/
|
||||
|
||||
#ifndef BOOTLOADERINTERFACE_H
|
||||
#define BOOTLOADERINTERFACE_H
|
||||
#include "define.h"
|
||||
|
||||
|
||||
#define BOOTLOADER_FILE_HEADER_CODE (int)0xBAADBEEF
|
||||
#define BOOTLOADER_RECORD_HEADER_CODE (int)0xDEADBEEF
|
||||
#define BOOTLOADER_FLASH_FIRMWARE_VALIDATOR 0xA8
|
||||
#define BOOTLOADER_ENTER_UPLOAD_MODE_VALIDATOR 0x5A
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char BootloaderAction;
|
||||
unsigned char BootloaderActionValidator;
|
||||
|
||||
}stBootloaderFlags_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int Firmwareflags;
|
||||
unsigned int NbRecords;
|
||||
unsigned int FirmwareSize;
|
||||
unsigned int Versioncode;
|
||||
unsigned int DataCRC32;
|
||||
}stStoredBootloaderInfo;
|
||||
|
||||
extern stBootloaderFlags_t mBootloaderFlags;
|
||||
stStoredBootloaderInfo mStoredBootloaderInfo;
|
||||
|
||||
enum eBootloaderFlagsIndex
|
||||
{
|
||||
BOOTLOADER_FLAGS_ACTION_FLAG_INDEX = 0,
|
||||
BOOTLOADER_FLAGS_ACTION_VALIDATOR_INDEX,
|
||||
|
||||
|
||||
BOOTLOADER_FLAGS_MAX_INDEX = 12
|
||||
};
|
||||
|
||||
enum eBootloaderActionFlagValues
|
||||
{
|
||||
BOOTLOADER_ACTION_JUMP_TO_APP_VALUE = 0,
|
||||
BOOTLOADER_ACTION_FLASH_FIRMWARE_VALUE = 1,
|
||||
BOOTLOADER_ACTION_ENTER_UPDATE_MODE_VALUE = 2,
|
||||
|
||||
BOOTLOADER_ACTION_MAX_VALUE
|
||||
|
||||
};
|
||||
|
||||
|
||||
enum eBootloaderStates
|
||||
{
|
||||
BOOTLOADER_STANDBY_STATE,
|
||||
BOOTLOADER_ACTIVE_STATE,
|
||||
BOOTLOADER_ERASE_FLASH_STATE,
|
||||
BOOTLOADER_RECEIVING_FIRMWARE_STATE,
|
||||
BOOTLOADER_SENDING_FIRMWARE_COPY_STATE,
|
||||
BOOTLOADER_PRINTING_FIRMWARE_STATE,
|
||||
|
||||
BOOTLOADER_MAX_STATE
|
||||
};
|
||||
|
||||
enum eBootloaderStateMachineEvents
|
||||
{
|
||||
BOOTLOADER_TICK_EVENT,
|
||||
BOOTLOADER_NEW_CMD_EVENT,
|
||||
BOOTLOADER_TIMEOUT_EVENT,
|
||||
|
||||
BOOTLOADER_MAX_EVENT
|
||||
};
|
||||
|
||||
enum eBootloaderFlashEraseStates
|
||||
{
|
||||
BOOTLOADER_FLASH_ERASE_SECTOR_STATE,
|
||||
BOOTLOADER_FLASH_ERASE_WAIT_FOR_SECTOR_DONE,
|
||||
BOOTLOADER_FLASH_ERASE_CHECKBACK_STATE,
|
||||
BOOTLOADER_FLASH_ERASE_FINISHED_STATE,
|
||||
BOOTLOADER_FLASH_ERASE_ERROR_STATE,
|
||||
|
||||
BOOTLOADER_FLASH_ERASE_MAX_STATE
|
||||
};
|
||||
|
||||
enum eBootloaderFlashEraseResults
|
||||
{
|
||||
BOOTLOADER_FLASH_ERASE_RUNNING_RES,
|
||||
BOOTLOADER_FLASH_ERASE_FINISHED_RES,
|
||||
BOOTLOADER_FLASH_ERASE_ERROR_RES,
|
||||
BOOTLOADER_FLASH_ERASE_ABORT_RES,
|
||||
|
||||
BOOTLOADER_FLASH_ERASE_MAX_RES
|
||||
};
|
||||
|
||||
enum eBootloaderFlahsEraseSMEvents
|
||||
{
|
||||
BOOTLOADER_FLASH_ERASE_SM_TICK_EVENT,
|
||||
BOOTLOADER_FLASH_ERASE_SM_ABORT_EVENT,
|
||||
|
||||
BOOTLOADER_FLASH_ERASE_SM_MAX_EVENT
|
||||
};
|
||||
|
||||
enum eBootloaderFlashWriteStates
|
||||
{
|
||||
BOOTLOADER_FLASH_WRITE_STANDBY_STATE,
|
||||
BOOTLOADER_FLASH_WRITE_BUFFER_STATE,
|
||||
BOOTLOADER_FLASH_WRITE_WAIT_FOR_BYTE_DONE,
|
||||
BOOTLOADER_FLASH_WRITE_CHECKBACK_STATE,
|
||||
BOOTLOADER_FLASH_WRITE_FINISHED_STATE,
|
||||
BOOTLOADER_FLASH_WRITE_ERROR_STATE,
|
||||
|
||||
BOOTLOADER_FLASH_WRITE_MAX_STATE
|
||||
};
|
||||
|
||||
enum eBootloaderFlashWriteResults
|
||||
{
|
||||
BOOTLOADER_FLASH_WRITING_RES,
|
||||
BOOTLOADER_FLASH_WRITE_FINISHED_RES,
|
||||
BOOTLOADER_FLASH_WRITE_ERROR_RES,
|
||||
BOOTLOADER_FLASH_WRITE_ABORT_RES,
|
||||
|
||||
BOOTLOADER_FLASH_WRITE_MAX_RES
|
||||
};
|
||||
|
||||
enum eBootloaderFlahsWriteSMEvents
|
||||
{
|
||||
BOOTLOADER_FLASH_WRITE_SM_TICK_EVENT,
|
||||
BOOTLOADER_FLASH_WRITE_SM_NEW_BUFFER_EVENT,
|
||||
BOOTLOADER_FLASH_WRITE_SM_ABORT_EVENT,
|
||||
|
||||
BOOTLOADER_FLASH_WRITE_SM_MAX_EVENT
|
||||
};
|
||||
|
||||
|
||||
enum eBootloaderStateMachineCmds
|
||||
{
|
||||
BOOTLOADER_SM_ACTIVATE_CMD,
|
||||
BOOTLOADER_SM_ABORT_CMD,
|
||||
BOOTLOADER_SM_ERASE_FLASH_CMD,
|
||||
BOOTLOADER_SM_INIT_UPLOAD_CMD,
|
||||
BOOTLOADER_SM_NEW_DATA_CHUNK_CMD,
|
||||
BOOTLOADER_SM_UPLOAD_FINISHED_CMD,
|
||||
BOOTLOADER_SM_EXECUTE_UPGRAGE_CMD,
|
||||
BOOTLOADER_SM_INVALID_CRC_CMD,
|
||||
BOOTLOADER_SM_CHECK_FLASH_CMD,
|
||||
BOOTLOADER_SM_GET_FIRMWARE_DATA_CMD
|
||||
};
|
||||
|
||||
|
||||
extern unsigned char BootloaderBuffer[300];
|
||||
|
||||
int BootloaderInterfaceInit();
|
||||
void BootloaderExecuteCmd(char Cmd,bool CRCValid);
|
||||
void BootloaderCRCError(char Cmd, int RxCRC, int ExpectedCRC);
|
||||
|
||||
|
||||
void BootloaderInterfaceTick();
|
||||
void BootloaderInterfaceStateMachine(int Event, int Param);
|
||||
void BootloaderResetStateMachine();
|
||||
void BootloaderActivateBootloader();
|
||||
void BootloaderDeactivateBootloader();
|
||||
|
||||
int BootloaderFlashEraseStateMachine(int event);
|
||||
int ResetBootloaderFlashEraseStateMachine();
|
||||
|
||||
int BootloaderFlashWriteStateMachine(int event);
|
||||
int ResetBootloaderFlashWriteStateMachine();
|
||||
|
||||
int BootloaderCheckFlashBootloaderData();
|
||||
int BootloaderPrintFlashData();
|
||||
|
||||
int BootloaderBytesToInt(unsigned char *Bytes);
|
||||
int BootloaderIntToBytes(unsigned char *Buf, unsigned int Input);
|
||||
|
||||
|
||||
|
||||
#endif /* BOOTLOADERINTERFACE_H */
|
||||
|
||||
427
ChaloupeLora.X/Source/BootloaderProtocol.c
Normal file
427
ChaloupeLora.X/Source/BootloaderProtocol.c
Normal file
@ -0,0 +1,427 @@
|
||||
/**********************************************************************
|
||||
Project: Automatic cat feeder
|
||||
Date: march 19 2006
|
||||
Author: Jean-Fran<EFBFBD>ois Martel
|
||||
Target: PIC 18F252
|
||||
Compiler: Microchip mcc18
|
||||
Filename: Protocol.c
|
||||
|
||||
File description: Communication protocol implementation.
|
||||
|
||||
|
||||
jean-francois.martel@polymtl.ca
|
||||
**********************************************************************/
|
||||
#include "define.h"
|
||||
#include <string.h>
|
||||
#include "ProtocolDefs.h"
|
||||
#include "BootloaderProtocol.h"
|
||||
#include "BootloaderInterface.h"
|
||||
#include "WiFiCtrl.h"
|
||||
#include "checksum.h"
|
||||
|
||||
|
||||
//test
|
||||
unsigned int BootloaderHeader = 0;
|
||||
unsigned int BootloaderDataSize = 0;
|
||||
unsigned int BootloaderDataCtr = 0;
|
||||
unsigned int BootloaderBufPtr = 0;
|
||||
unsigned int BootloaderCRC = 0;
|
||||
unsigned int BtldrComputedCRC = CRC_START_32;
|
||||
unsigned char *BootloaderRxPtr;
|
||||
unsigned char BootloaderCommand = 0;
|
||||
unsigned char BootloaderState = RxHeader1;
|
||||
const unsigned char *BootloaderDataStartPtr = &BootloaderBuffer[9];
|
||||
|
||||
|
||||
static char MyDeviceID = ID_SPRINKLER_DEVICE;
|
||||
|
||||
void BootloaderProtocolInit(void)
|
||||
{
|
||||
BootloaderProtocolResetStateMachine();
|
||||
|
||||
}
|
||||
|
||||
void BootloaderProtocolStateMachine(unsigned char Data)
|
||||
{
|
||||
switch(BootloaderState)
|
||||
{
|
||||
case Initialization: //Reset all pointers and data...
|
||||
{
|
||||
BootloaderDataSize = 0;
|
||||
BootloaderBufPtr = 0;
|
||||
BootloaderCommand = 0;
|
||||
BootloaderCRC = 0;
|
||||
BootloaderState = RxHeader1;
|
||||
BtldrComputedCRC = CRC_START_32;
|
||||
break;
|
||||
}
|
||||
case RxHeader1: //Wait for data header...
|
||||
{
|
||||
BootloaderHeader <<= 8;
|
||||
BootloaderHeader += Data; //0xDE
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
|
||||
if(Data == BOOTLOADER_FRAME_HEADER_1)
|
||||
{
|
||||
BootloaderState = RxHeader2;
|
||||
}
|
||||
else
|
||||
{
|
||||
BootloaderProtocolResetStateMachine();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RxHeader2: //Wait for data header...
|
||||
{
|
||||
BootloaderHeader <<= 8;
|
||||
BootloaderHeader += Data; //0xAD
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
|
||||
if(Data == BOOTLOADER_FRAME_HEADER_2)
|
||||
{
|
||||
BootloaderState = RxHeader3;
|
||||
}
|
||||
else
|
||||
{
|
||||
BootloaderProtocolResetStateMachine();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RxHeader3: //Wait for data header...
|
||||
{
|
||||
BootloaderHeader <<= 8;
|
||||
BootloaderHeader += Data; //0xBE
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
|
||||
if(Data == BOOTLOADER_FRAME_HEADER_3)
|
||||
{
|
||||
BootloaderState = RxHeader4;
|
||||
}
|
||||
else
|
||||
{
|
||||
BootloaderProtocolResetStateMachine();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RxHeader4: //Wait for data header...
|
||||
{
|
||||
BootloaderHeader <<= 8;
|
||||
BootloaderHeader += Data; //0xEF
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
|
||||
if(BootloaderHeader != BOOTLOADER_FRAME_HEADER)
|
||||
{
|
||||
//TODO, send NACK?
|
||||
BootloaderProtocolResetStateMachine();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
BootloaderState = RxCmd;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RxCmd:
|
||||
{
|
||||
BootloaderCommand = Data;
|
||||
BootloaderState = RxPayloadSize1;
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
break;
|
||||
}
|
||||
case RxPayloadSize1:
|
||||
{
|
||||
BootloaderDataSize = Data;
|
||||
BootloaderState = RxPayloadSize2;
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
break;
|
||||
}
|
||||
case RxPayloadSize2:
|
||||
{
|
||||
BootloaderDataSize <<= 8;
|
||||
BootloaderDataSize += Data;
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
|
||||
BootloaderState = RxPayloadSize3;
|
||||
break;
|
||||
}
|
||||
case RxPayloadSize3:
|
||||
{
|
||||
BootloaderDataSize <<= 8;
|
||||
BootloaderDataSize += Data;
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
|
||||
BootloaderState = RxPayloadSize4;
|
||||
break;
|
||||
}
|
||||
case RxPayloadSize4:
|
||||
{
|
||||
BootloaderDataSize <<= 8;
|
||||
BootloaderDataSize += Data;
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
|
||||
if(BootloaderDataSize > MAX_BOOTLOADER_PAYLOAD_SIZE+8) //+8 bytes for the size and index data
|
||||
{
|
||||
//TODO, send NACK?
|
||||
BootloaderProtocolResetStateMachine();
|
||||
break;
|
||||
}
|
||||
|
||||
if(BootloaderDataSize == 0)
|
||||
{
|
||||
BootloaderState = RxCRC1;
|
||||
}
|
||||
else
|
||||
{
|
||||
BootloaderState = RxPayload;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RxPayload: //Data size
|
||||
{
|
||||
*BootloaderRxPtr = Data;
|
||||
BootloaderRxPtr++;
|
||||
|
||||
BootloaderDataCtr++;
|
||||
BtldrComputedCRC = update_crc_32(BtldrComputedCRC,Data);
|
||||
|
||||
if(BootloaderDataCtr == BootloaderDataSize)
|
||||
{
|
||||
BootloaderState = RxCRC1;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RxCRC1: //Data size
|
||||
{
|
||||
BootloaderCRC = Data;
|
||||
BootloaderState = RxCRC2;
|
||||
break;
|
||||
}
|
||||
case RxCRC2: //Data size
|
||||
{
|
||||
BootloaderCRC <<= 8;
|
||||
BootloaderCRC += Data;
|
||||
BootloaderState = RxCRC3;
|
||||
break;
|
||||
}
|
||||
case RxCRC3: //Data size
|
||||
{
|
||||
BootloaderCRC <<= 8;
|
||||
BootloaderCRC += Data;
|
||||
BootloaderState = RxCRC4;
|
||||
break;
|
||||
}
|
||||
case RxCRC4: //Data size
|
||||
{
|
||||
BootloaderCRC <<= 8;
|
||||
BootloaderCRC += Data;
|
||||
|
||||
//TODO: Compute and Compare CRC.
|
||||
|
||||
BtldrComputedCRC ^= 0xffffffffL;
|
||||
//if(BootloaderCRC != 0xBAADCAFE)
|
||||
if(BootloaderCRC != BtldrComputedCRC)
|
||||
{
|
||||
BootloaderExecuteCmd(BootloaderCommand,0);
|
||||
BootloaderProtocolResetStateMachine();
|
||||
return;
|
||||
}
|
||||
|
||||
BootloaderExecuteCmd(BootloaderCommand,1);
|
||||
BootloaderProtocolResetStateMachine();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
BootloaderProtocolResetStateMachine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BootloaderProtocolProtocolAnalyzeNewData(unsigned char *DataBuf, int size)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
BootloaderProtocolStateMachine(*DataBuf++);
|
||||
}
|
||||
}
|
||||
|
||||
void BootloaderProtocolResetStateMachine()
|
||||
{
|
||||
BootloaderDataSize = 0;
|
||||
BootloaderHeader = 0;
|
||||
BootloaderBufPtr = 0;
|
||||
BootloaderCommand = 0;
|
||||
BootloaderCRC = 0;
|
||||
BootloaderState = RxHeader1;
|
||||
BootloaderDataCtr = 0;
|
||||
BtldrComputedCRC = CRC_START_32;
|
||||
BootloaderRxPtr = &BootloaderBuffer[0];
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendFrame(unsigned char Cmd, int Size)
|
||||
{
|
||||
//Header
|
||||
BootloaderBuffer[0] = BOOTLOADER_FRAME_HEADER_1; //Header
|
||||
BootloaderBuffer[1] = BOOTLOADER_FRAME_HEADER_2;
|
||||
BootloaderBuffer[2] = BOOTLOADER_FRAME_HEADER_3;
|
||||
BootloaderBuffer[3] = BOOTLOADER_FRAME_HEADER_4;
|
||||
|
||||
BootloaderBuffer[4] = Cmd;
|
||||
|
||||
char nibble = (char)((Size >> 24) &0x000000FF);
|
||||
BootloaderBuffer[5] = nibble;
|
||||
|
||||
nibble = (char)((Size >> 16) &0x000000FF);
|
||||
BootloaderBuffer[6] = nibble;
|
||||
|
||||
nibble = (char)((Size >> 8) &0x000000FF);
|
||||
BootloaderBuffer[7] = nibble;
|
||||
|
||||
nibble = (char)(Size &0x000000FF);
|
||||
BootloaderBuffer[8] = nibble;
|
||||
|
||||
unsigned int CRC = CRC_START_32;
|
||||
CRC = crc_32((const unsigned char*)BootloaderBuffer,Size+9);
|
||||
|
||||
unsigned char* CRCPtr = (unsigned char*)BootloaderDataStartPtr + Size;
|
||||
|
||||
nibble = (char)((CRC >> 24) &0x000000FF);
|
||||
*CRCPtr++ = nibble;
|
||||
|
||||
nibble = (char)((CRC >> 16) &0x000000FF);
|
||||
*CRCPtr++ = nibble;
|
||||
|
||||
nibble = (char)((CRC >> 8) &0x000000FF);
|
||||
*CRCPtr++ = nibble;
|
||||
|
||||
nibble = (char)(CRC &0x000000FF);
|
||||
*CRCPtr++ = nibble;
|
||||
|
||||
// *CRCPtr++ = 0xBA;
|
||||
// *CRCPtr++ = 0xAD;
|
||||
// *CRCPtr++ = 0xCA;
|
||||
// *CRCPtr++ = 0xFE;
|
||||
|
||||
SendBootloaderData(&BootloaderBuffer[0],Size + PROTOCOL_INFO_DATA_SIZE);
|
||||
}
|
||||
|
||||
unsigned char *BootloaderProtocolGetDataBufferPtr()
|
||||
{
|
||||
return (unsigned char*)BootloaderDataStartPtr;
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendHeartbeat()
|
||||
{
|
||||
*BootloaderProtocolGetDataBufferPtr() = BOOTLOADER_ACK;
|
||||
BootloaderProtocolSendFrame(BOOTLOADER_HEARTBEAT_RESPONSE,1);
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendACK(unsigned char Cmd)
|
||||
{
|
||||
*BootloaderProtocolGetDataBufferPtr() = BOOTLOADER_ACK;
|
||||
BootloaderProtocolSendFrame(Cmd,1);
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendNACK(unsigned char Cmd)
|
||||
{
|
||||
*BootloaderProtocolGetDataBufferPtr() = 0;
|
||||
BootloaderProtocolSendFrame(Cmd,1);
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendInitUploadResponse(char result)
|
||||
{
|
||||
int MaxSize = MAX_BOOTLOADER_PAYLOAD_SIZE;
|
||||
char* DataPtr = BootloaderProtocolGetDataBufferPtr();
|
||||
|
||||
*DataPtr++ = result;
|
||||
if(result == 1)
|
||||
{
|
||||
char nibble = (char)((MaxSize >> 24) &0x000000FF);
|
||||
*DataPtr++ = nibble;
|
||||
|
||||
nibble = (char)((MaxSize >> 16) &0x000000FF);
|
||||
*DataPtr++ = nibble;
|
||||
|
||||
nibble = (char)((MaxSize >> 8) &0x000000FF);
|
||||
*DataPtr++ = nibble;
|
||||
|
||||
nibble = (char)(MaxSize &0x000000FF);
|
||||
*DataPtr++ = nibble;
|
||||
}
|
||||
else
|
||||
{
|
||||
*DataPtr++ = 0;
|
||||
*DataPtr++ = 0;
|
||||
*DataPtr++ = 0;
|
||||
*DataPtr++ = 0;
|
||||
}
|
||||
|
||||
BootloaderProtocolSendFrame(BOOTLOADER_INIT_UPLOAD_RESPONSE,5);
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendDataChunkResult(char ErrorCode, int ChunkValue)
|
||||
{
|
||||
char* DataPtr = BootloaderProtocolGetDataBufferPtr();
|
||||
|
||||
*DataPtr++ = ErrorCode;
|
||||
|
||||
char nibble = (char)((ChunkValue >> 24) &0x000000FF);
|
||||
*DataPtr++ = nibble;
|
||||
|
||||
nibble = (char)((ChunkValue >> 16) &0x000000FF);
|
||||
*DataPtr++ = nibble;
|
||||
|
||||
nibble = (char)((ChunkValue >> 8) &0x000000FF);
|
||||
*DataPtr++ = nibble;
|
||||
|
||||
nibble = (char)(ChunkValue &0x000000FF);
|
||||
*DataPtr++ = nibble;
|
||||
|
||||
BootloaderProtocolSendFrame(BOOTLOADER_SEND_DATA_CHUNK_RESPONSE,5);
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendBootloaderState(char State)
|
||||
{
|
||||
char* DataPtr = BootloaderProtocolGetDataBufferPtr();
|
||||
|
||||
*DataPtr++ = State;
|
||||
|
||||
BootloaderProtocolSendFrame(BOOTLOADER_GET_STATE_RESPONSE,1);
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendFirmwareUploadResult(char Result)
|
||||
{
|
||||
char* DataPtr = BootloaderProtocolGetDataBufferPtr();
|
||||
|
||||
*DataPtr++ = Result;
|
||||
|
||||
BootloaderProtocolSendFrame(BOOTLOADER_UPLOAD_FINISHED_RESPONSE,1);
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendFlashCheckResult(char Result)
|
||||
{
|
||||
char* DataPtr = BootloaderProtocolGetDataBufferPtr();
|
||||
|
||||
*DataPtr++ = Result;
|
||||
|
||||
BootloaderProtocolSendFrame(BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_RESPONSE,1);
|
||||
}
|
||||
|
||||
void BootloaderProtocolSendStoredFirmwareInfoResponse(unsigned char* FirmwareData, int size)
|
||||
{
|
||||
char* DataPtr = BootloaderProtocolGetDataBufferPtr();
|
||||
|
||||
int i = 0;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
*DataPtr++ = *FirmwareData++;
|
||||
}
|
||||
|
||||
|
||||
BootloaderProtocolSendFrame(BOOTLOADER_GET_STORED_FIRMWARE_INFO_RESPONSE,size);
|
||||
}
|
||||
123
ChaloupeLora.X/Source/BootloaderProtocol.h
Normal file
123
ChaloupeLora.X/Source/BootloaderProtocol.h
Normal file
@ -0,0 +1,123 @@
|
||||
/**********************************************************************
|
||||
Project: Automatic cat feeder
|
||||
Date: march 19 2006
|
||||
Author: Jean-Fran<EFBFBD>ois Martel
|
||||
Target: PIC 18F252
|
||||
Compiler: Microchip mcc18
|
||||
Filename: Protocol.h
|
||||
|
||||
File description: Communication protocol implementation.
|
||||
|
||||
|
||||
jean-francois.martel@polymtl.ca
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#ifndef BOOTLOADERPROTOCOL_H
|
||||
#define BOOTLOADERPROTOCOL_H
|
||||
|
||||
//Protocol buffer specific definitions
|
||||
|
||||
#define MAX_BOOTLOADER_PAYLOAD_SIZE 150
|
||||
#define BOOTLOADER_FRAME_HEADER 0xDEADBEEF
|
||||
#define BOOTLOADER_FRAME_HEADER_1 0xDE
|
||||
#define BOOTLOADER_FRAME_HEADER_2 0xAD
|
||||
#define BOOTLOADER_FRAME_HEADER_3 0xBE
|
||||
#define BOOTLOADER_FRAME_HEADER_4 0xEF
|
||||
#define PROTOCOL_INFO_DATA_SIZE 13 //Header + Cmd + Size + CRC = 13 bytes
|
||||
//State Machine states
|
||||
enum States
|
||||
{
|
||||
Initialization,
|
||||
RxHeader1,
|
||||
RxHeader2,
|
||||
RxHeader3,
|
||||
RxHeader4,
|
||||
RxCmd,
|
||||
RxPayloadSize1,
|
||||
RxPayloadSize2,
|
||||
RxPayloadSize3,
|
||||
RxPayloadSize4,
|
||||
RxPayload,
|
||||
RxCRC1,
|
||||
RxCRC2,
|
||||
RxCRC3,
|
||||
RxCRC4
|
||||
};
|
||||
|
||||
enum eBootloaderProtocolDataTransferError
|
||||
{
|
||||
BOOTLOADER_CHUNK_TRANSFER_SUCCESS = 1,
|
||||
BOOTLOADER_CHUNK_TRANSFER_ERROR_RESEND = 2,
|
||||
BOOTLOADER_CHUNK_TRANSFER_ERROR_FLASH_FAILURE = 3,
|
||||
BOOTLOADER_CHUNK_TRANSFER_ERROR_INVALID_CHUNK_INDEX = 4,
|
||||
BOOTLOADER_CHUNK_TRANSFER_ERROR_FLASH_ERROR = 5,
|
||||
|
||||
BOOTLOADER_CHUNK_TRANSFER_MAX_ERROR
|
||||
};
|
||||
|
||||
enum eBootloaderProtocolInitTransferError
|
||||
{
|
||||
BOOTLOADEDR_INIT_TRANSFER_ERROR = 0,
|
||||
BOOTLOADEDR_INIT_TRANSFER_OK = 1,
|
||||
BOOTLOADEDR_INIT_TRANSFER_ERROR_FLASH_NOT_ERASED,
|
||||
|
||||
BOOTLOADEDR_INIT_TRANSFER_MAX_ERROR
|
||||
};
|
||||
|
||||
enum eBootloaderUploadResult
|
||||
{
|
||||
BOOTLOADER_UPLOAD_FAILED_UNKNOWN_ERROR = 0,
|
||||
BOOTLOADER_UPLOAD_SUCCESS = 1,
|
||||
BOOTLOADER_UPLOAD_FAILED_FLASH_VERIFICATION_ERROR = 2,
|
||||
|
||||
BOOTLOADER_UPLOAD_MAX_ERROR
|
||||
};
|
||||
|
||||
enum eFlashCheckResult
|
||||
{
|
||||
FLASH_CHECK_FAILED = 0,
|
||||
FLASH_CHECK_SUCCESS = 1,
|
||||
|
||||
FLASH_CHECK_MAX_RESULT
|
||||
};
|
||||
|
||||
//enum DEVICES_IDS
|
||||
//{
|
||||
// ID_MASTER, //Master Controller
|
||||
// ID_CONSOLE, //LCD Console
|
||||
// ID_PC, //PC
|
||||
// ID_AV_MUX, //Audio Video Multiplexer
|
||||
// ID_IR_REMOTE,
|
||||
// ID_DEADBOLT
|
||||
//};
|
||||
|
||||
//enum MESSAGE_IDS
|
||||
//{
|
||||
// TX_NETWORK_ACK = 1,
|
||||
// RX_GET_STATUS,
|
||||
// TX_DEADBOLT_STATUS,
|
||||
//
|
||||
// MAX_NETWORK_CMD
|
||||
//};
|
||||
|
||||
//State machine states definition
|
||||
|
||||
void BootloaderProtocolInit(void);
|
||||
void BootloaderProtocolStateMachine(unsigned char STATE);
|
||||
void BootloaderProtocolResetStateMachine(void);
|
||||
void BootloaderProtocolProtocolAnalyzeNewData(unsigned char *DataBuf, int size);
|
||||
void BootloaderProtocolSendFrame(unsigned char Cmd, int size);
|
||||
unsigned char *BootloaderProtocolGetDataBufferPtr();
|
||||
|
||||
void BootloaderProtocolSendHeartbeat();
|
||||
void BootloaderProtocolSendACK(unsigned char Cmd);
|
||||
void BootloaderProtocolSendNACK(unsigned char Cmd);
|
||||
void BootloaderProtocolSendInitUploadResponse(char result);
|
||||
void BootloaderProtocolSendDataChunkResult(char ErrorCode, int ChunkValue);
|
||||
void BootloaderProtocolSendBootloaderState(char State);
|
||||
void BootloaderProtocolSendFirmwareUploadResult(char Result);
|
||||
void BootloaderProtocolSendFlashCheckResult(char Result);
|
||||
void BootloaderProtocolSendStoredFirmwareInfoResponse(unsigned char* FirmwareData, int size);
|
||||
|
||||
#endif
|
||||
79
ChaloupeLora.X/Source/ChaletPowerRelay.c
Normal file
79
ChaloupeLora.X/Source/ChaletPowerRelay.c
Normal file
@ -0,0 +1,79 @@
|
||||
//#include <proc/p32mx440f256h.h>
|
||||
|
||||
#include "ChaletPowerRelay.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define PIN_ACTIVE 1
|
||||
#define PIN_INACTIVE 0
|
||||
|
||||
bool PowerRelayState;
|
||||
|
||||
void InitChaletPowerRelay()
|
||||
{
|
||||
POWER_RELAY_ON_PIN = PIN_INACTIVE;
|
||||
POWER_RELAY_OFF_PIN = PIN_INACTIVE;
|
||||
PowerRelayState = CHALET_POWER_RELAY_UNKNOWN_STATE;
|
||||
TimerStop(CHALET_POWER_RELAY_COIL_TIMER);
|
||||
}
|
||||
|
||||
void ChaletPowerRelayTick()
|
||||
{
|
||||
if(CHALET_12V_PRESENCE_PIN == CHALET_12V_POWER_STATE_ON)
|
||||
{
|
||||
if(PowerRelayState == CHALET_POWER_RELAY_OFF_STATE)
|
||||
{
|
||||
printf("Inverter turned ON\n");
|
||||
}
|
||||
PowerRelayState = CHALET_POWER_RELAY_ON_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(PowerRelayState == CHALET_POWER_RELAY_ON_STATE)
|
||||
{
|
||||
printf("Inverter turned OFF\n");
|
||||
}
|
||||
PowerRelayState = CHALET_POWER_RELAY_OFF_STATE;
|
||||
}
|
||||
|
||||
if(IsTimerRunning(CHALET_POWER_RELAY_COIL_TIMER) == true)
|
||||
{
|
||||
if(IsTimerExpired(CHALET_POWER_RELAY_COIL_TIMER))
|
||||
{
|
||||
POWER_RELAY_ON_PIN = PIN_INACTIVE;
|
||||
POWER_RELAY_OFF_PIN = PIN_INACTIVE;
|
||||
TimerStop(CHALET_POWER_RELAY_COIL_TIMER);
|
||||
}
|
||||
}
|
||||
|
||||
if(IsTimerExpired(CHALET_POWER_RELAY_AUTOTURNOFF_TIMER))
|
||||
{
|
||||
ChaletPowerRelayTurnOff();
|
||||
}
|
||||
}
|
||||
|
||||
void ChaletPowerRelayKickTimer()
|
||||
{
|
||||
TimerStartSeconds(CHALET_POWER_RELAY_AUTOTURNOFF_TIMER,CHALET_OFFLINE_POWER_RELAY_RESET_TIMEOUT);
|
||||
}
|
||||
|
||||
bool ChaletPowerRelayTurnOn()
|
||||
{
|
||||
POWER_RELAY_ON_PIN = PIN_ACTIVE;
|
||||
TimerStart(CHALET_POWER_RELAY_COIL_TIMER,CHALET_POWER_RELAY_COIL_TIMEOUT);
|
||||
// PowerRelayState = CHALET_POWER_RELAY_ON_STATE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChaletPowerRelayTurnOff()
|
||||
{
|
||||
POWER_RELAY_OFF_PIN = PIN_ACTIVE;
|
||||
TimerStart(CHALET_POWER_RELAY_COIL_TIMER,CHALET_POWER_RELAY_COIL_TIMEOUT);
|
||||
// PowerRelayState = CHALET_POWER_RELAY_OFF_STATE;
|
||||
return true;
|
||||
}
|
||||
|
||||
char GetChaletPowerRelayState()
|
||||
{
|
||||
return (char)PowerRelayState;
|
||||
}
|
||||
37
ChaloupeLora.X/Source/ChaletPowerRelay.h
Normal file
37
ChaloupeLora.X/Source/ChaletPowerRelay.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* File: ChaletPowerRelay.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 30, 2018, 7:33 PM
|
||||
*/
|
||||
|
||||
#ifndef CHALETPOWERRELAY_H
|
||||
#define CHALETPOWERRELAY_H
|
||||
#include "define.h"
|
||||
|
||||
#define CHALET_OFFLINE_POWER_RELAY_RESET_TIMEOUT 43200 //43,200 = 12 hours in seconds
|
||||
|
||||
enum eChaletPowerRelayState
|
||||
{
|
||||
CHALET_POWER_RELAY_OFF_STATE = 0,
|
||||
CHALET_POWER_RELAY_ON_STATE,
|
||||
CHALET_POWER_RELAY_UNKNOWN_STATE
|
||||
};
|
||||
|
||||
#define CHALET_12V_POWER_STATE_ON 0
|
||||
#define CHALET_12V_POWER_STATE_OFF 1
|
||||
|
||||
#define CHALET_POWER_RELAY_COIL_TIMEOUT 200 //ms
|
||||
|
||||
void InitChaletPowerRelay();
|
||||
|
||||
void ChaletPowerRelayTick();
|
||||
bool ChaletPowerRelayTurnOn();
|
||||
bool ChaletPowerRelayTurnOff();
|
||||
char GetChaletPowerRelayState();
|
||||
void ChaletPowerRelayKickTimer();
|
||||
|
||||
|
||||
|
||||
#endif /* CHALETPOWERRELAY_H */
|
||||
|
||||
130
ChaloupeLora.X/Source/ChaletduinoBoard.c
Normal file
130
ChaloupeLora.X/Source/ChaletduinoBoard.c
Normal file
@ -0,0 +1,130 @@
|
||||
#include "BoardCfg.h"
|
||||
|
||||
int InitBoard()
|
||||
{
|
||||
HEARTBEAT_LED_1_PIN_DIR = PIN_OUTPUT;
|
||||
HEARTBEAT_LED_2_PIN_DIR = PIN_OUTPUT;
|
||||
|
||||
HEARTBEAT_LED_2_PIN = LED_OFF;
|
||||
HEARTBEAT_LED_1_PIN = LED_ON;
|
||||
|
||||
LORA_ACTIVITY_LED_PIN_DIR = PIN_OUTPUT;
|
||||
LORA_ACTIVITY_LED_PIN = LED_OFF;
|
||||
|
||||
// GP_DEBUG_1_PIN_DIR = PIN_OUTPUT;
|
||||
// GP_DEBUG_1_PIN = 0;
|
||||
// GP_DEBUG_2_PIN_DIR = PIN_OUTPUT;
|
||||
// GP_DEBUG_2_PIN = 0;
|
||||
|
||||
|
||||
SPI_SDI_PIN_DIR = PIN_INPUT;
|
||||
SD_SPI_SS_PIN_DIR = PIN_OUTPUT;
|
||||
SPI_SDO_PIN_DIR = PIN_OUTPUT;
|
||||
SPI_SCK_PIN_DIR = PIN_OUTPUT;
|
||||
|
||||
FLASH_SS_PIN_DIR = PIN_OUTPUT;
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
|
||||
//Wifi (WINC1500 module)
|
||||
WIFI_SPI_SS_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_SPI_SS_PIN = 1;
|
||||
WIFI_IRQ_PIN_DIR = PIN_INPUT;
|
||||
// WIFI_SPI_CFG_PIN_DIR = PIN_OUTPUT;
|
||||
// WIFI_SPI_CFG_PIN = 0;
|
||||
WIFI_CHP_EN_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_CHP_EN_PIN = 0;
|
||||
WIFI_CHP_RST_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_CHP_RST_PIN = 0;
|
||||
|
||||
// DOOR_PAD_D0_PIN_DIR = PIN_INPUT;
|
||||
// DOOR_PAD_D1_PIN_DIR
|
||||
// DOOR_PAD_D1_PIN
|
||||
|
||||
//Wifi chip IRQ
|
||||
IEC0bits.INT0IE = 0;
|
||||
IFS0bits.INT0IF = 0;
|
||||
INTCONbits.INT0EP = 0; //Falling edge
|
||||
IPC0bits.INT0IP = 3;
|
||||
IPC0bits.INT0IS = 0;
|
||||
IEC0bits.INT0IE = 1;
|
||||
|
||||
//Wifi chip SPI
|
||||
SPI2CON = 0;
|
||||
SPI2CONbits.MSTEN = 1;
|
||||
SPI2CONbits.CKE = 1;
|
||||
SPI2CONbits.SMP = 0;
|
||||
SPI2CONbits.CKP = 0;
|
||||
SPI2BRG = SPICalculateBRG(PERIPHERAL_FREQ, 1000000);
|
||||
// SPI2BRG = SPICalculateBRG(PERIPHERAL_FREQ, 50000);
|
||||
SPI2CONbits.ON = 1;
|
||||
|
||||
|
||||
//Chalet inverter power relay
|
||||
POWER_RELAY_ON_PIN_DIR = PIN_OUTPUT;
|
||||
POWER_RELAY_OFF_PIN_DIR = PIN_OUTPUT;
|
||||
POWER_RELAY_ON_PIN = 0;
|
||||
POWER_RELAY_OFF_PIN = 0;
|
||||
|
||||
//Harakiri relay
|
||||
HARAKIRI_RELAY_ON_PIN_DIR = PIN_OUTPUT;
|
||||
HARAKIRI_RELAY_ON_PIN= 0;
|
||||
|
||||
//12V presence detection input
|
||||
CHALET_12V_PRESENCE_PIN_DIR = PIN_INPUT;
|
||||
|
||||
//Battery voltage measurement (analog input)
|
||||
BATTERY_VOLTAGE_ANALOG_PIN_DIR = PIN_INPUT;
|
||||
|
||||
IEC0bits.INT1IE = 0;
|
||||
IFS0bits.INT1IF = 0;
|
||||
INTCONbits.INT1EP = 1; //Rising edge
|
||||
IPC1bits.INT1IP = 2;
|
||||
IPC1bits.INT1IS = 1;
|
||||
// IEC0bits.INT1IE = 1;
|
||||
|
||||
|
||||
// OC3CON = 0;
|
||||
// OC3R = 0;
|
||||
// OC3RS = 2000; //50% PWM
|
||||
// OC3CONbits.OCTSEL = 0;
|
||||
// OC3CONbits.OCM = 0b110; //PWM mode, no fault protection
|
||||
|
||||
//#ifdef __32MX330F064H__
|
||||
// RPD2Rbits.RPD2R = 0b1011; //RD2 peripheral selection = OC3
|
||||
//#endif
|
||||
//
|
||||
// T2CONbits.TON = 0; // Disable Timer
|
||||
// // T2CONbits.TCS = 0; // Select internal instruction cycle clock
|
||||
// T2CONbits.TGATE = 0; // Disable Gated Timer mode
|
||||
// T2CONbits.TCKPS = 0b011; // Select 1:1 Prescaler
|
||||
// TMR2 = 0x00; // Clear timer register
|
||||
//
|
||||
//
|
||||
// IPC2bits.T2IP = 0x01; // Set Timer 2 Interrupt Priority Level
|
||||
// IFS0bits.T2IF = 0; // Clear Timer 2 Interrupt Flag
|
||||
// IEC0bits.T2IE = 0; // Disable Timer 2 interrupt
|
||||
// T2CONbits.TON = 1; // Start Timer
|
||||
//
|
||||
// OC3CONbits.ON = 1;
|
||||
|
||||
|
||||
//ADC test
|
||||
|
||||
AD1PCFG = 0xFFFF; //Sart with I/O pins configured as digital I/O
|
||||
AD1PCFGbits.PCFG1 = 0;
|
||||
TRISBbits.TRISB1 = PIN_INPUT;
|
||||
|
||||
AD1CON1 = 0;
|
||||
AD1CON2 = 0;
|
||||
AD1CON3 = 0;
|
||||
|
||||
AD1CHS = 0;
|
||||
AD1CHSbits.CH0SA = 1; //AN1
|
||||
AD1CON3bits.ADCS = 0xF0;
|
||||
AD1CON3bits.SAMC = 0x01;
|
||||
AD1CON1bits.ON = 1;
|
||||
AD1CON1bits.SAMP = 1;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
204
ChaloupeLora.X/Source/ChaletduinoV2Board.c
Normal file
204
ChaloupeLora.X/Source/ChaletduinoV2Board.c
Normal file
@ -0,0 +1,204 @@
|
||||
#include "BoardCfg.h"
|
||||
|
||||
int InitBoard()
|
||||
{
|
||||
HEARTBEAT_LED_1_PIN_DIR = PIN_OUTPUT;
|
||||
HEARTBEAT_LED_2_PIN_DIR = PIN_OUTPUT;
|
||||
|
||||
HEARTBEAT_LED_2_PIN = LED_OFF;
|
||||
HEARTBEAT_LED_1_PIN = LED_ON;
|
||||
|
||||
// LORA_ACTIVITY_LED_PIN_DIR = PIN_OUTPUT;
|
||||
// LORA_ACTIVITY_LED_PIN = LED_OFF;
|
||||
|
||||
// GP_DEBUG_1_PIN_DIR = PIN_OUTPUT;
|
||||
// GP_DEBUG_1_PIN = 0;
|
||||
// GP_DEBUG_2_PIN_DIR = PIN_OUTPUT;
|
||||
// GP_DEBUG_2_PIN = 0;
|
||||
|
||||
|
||||
SPI_SDI_PIN_DIR = PIN_INPUT;
|
||||
SD_SPI_SS_PIN_DIR = PIN_OUTPUT;
|
||||
SPI_SDO_PIN_DIR = PIN_OUTPUT;
|
||||
SPI_SCK_PIN_DIR = PIN_OUTPUT;
|
||||
|
||||
|
||||
//////////////// SPI FLASH //////////////////
|
||||
|
||||
FLASH_SS_PIN_DIR = PIN_OUTPUT;
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
/////////////////////////// WIFI ///////////////////
|
||||
//Wifi (WINC1500 module)
|
||||
WIFI_SPI_SS_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_SPI_SS_PIN = 1;
|
||||
WIFI_IRQ_PIN_DIR = PIN_INPUT;
|
||||
// WIFI_SPI_CFG_PIN_DIR = PIN_OUTPUT;
|
||||
// WIFI_SPI_CFG_PIN = 0;
|
||||
WIFI_CHP_EN_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_CHP_EN_PIN = 0;
|
||||
WIFI_CHP_RST_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_CHP_RST_PIN = 0;
|
||||
|
||||
//Wifi chip IRQ
|
||||
IEC0bits.INT0IE = 0;
|
||||
IFS0bits.INT0IF = 0;
|
||||
INTCONbits.INT0EP = 0; //Falling edge
|
||||
IPC0bits.INT0IP = 3;
|
||||
IPC0bits.INT0IS = 0;
|
||||
IEC0bits.INT0IE = 1;
|
||||
|
||||
//Wifi chip SPI
|
||||
SPI2CON = 0;
|
||||
SPI2CONbits.MSTEN = 1;
|
||||
SPI2CONbits.CKE = 1;
|
||||
SPI2CONbits.SMP = 0;
|
||||
SPI2CONbits.CKP = 0;
|
||||
SPI2BRG = SPICalculateBRG(PERIPHERAL_FREQ, 1000000);
|
||||
// SPI2BRG = SPICalculateBRG(PERIPHERAL_FREQ, 50000);
|
||||
SPI2CONbits.ON = 1;
|
||||
|
||||
|
||||
//////////////// INVERTER RELAY //////////////////
|
||||
//Chalet inverter power relay
|
||||
POWER_RELAY_ON_PIN_DIR = PIN_OUTPUT;
|
||||
POWER_RELAY_OFF_PIN_DIR = PIN_OUTPUT;
|
||||
POWER_RELAY_ON_PIN = 0;
|
||||
POWER_RELAY_OFF_PIN = 0;
|
||||
|
||||
|
||||
//////////////// HARAKIRI RELAY //////////////////
|
||||
//Harakiri relay
|
||||
HARAKIRI_RELAY_ON_PIN_DIR = PIN_OUTPUT;
|
||||
HARAKIRI_RELAY_ON_PIN= 0;
|
||||
|
||||
//12V presence detection input
|
||||
CHALET_12V_PRESENCE_PIN_DIR = PIN_INPUT;
|
||||
|
||||
|
||||
//////////////// BATTERY MONITOR //////////////////
|
||||
//Battery voltage measurement (analog input)
|
||||
BATTERY_VOLTAGE_ANALOG_PIN_DIR = PIN_INPUT;
|
||||
|
||||
//ADC Config
|
||||
|
||||
AD1PCFG = 0xFFFF; //Sart with I/O pins configured as digital I/O
|
||||
AD1PCFGbits.PCFG1 = 0;
|
||||
AD1PCFGbits.PCFG2 = 0;
|
||||
TRISBbits.TRISB1 = PIN_INPUT;
|
||||
TRISBbits.TRISB2 = PIN_INPUT;
|
||||
|
||||
AD1CON1 = 0;
|
||||
AD1CON2 = 0;
|
||||
AD1CON3 = 0;
|
||||
|
||||
AD1CHS = 0;
|
||||
AD1CHSbits.CH0SA = 1; //AN1
|
||||
AD1CON3bits.ADCS = 0xF0;
|
||||
AD1CON3bits.SAMC = 0x01;
|
||||
AD1CON1bits.ON = 1;
|
||||
AD1CON1bits.SAMP = 1;
|
||||
|
||||
|
||||
//////////////// TEMPERATURE SENSOR //////////////////
|
||||
//Onboard temperature sensor (SPI)
|
||||
TEMP_SENSOR_CS_PIN_DIR = PIN_OUTPUT;
|
||||
TEMP_SENSOR_CS_PIN = 1;
|
||||
TEMP_SENSOR_SPI_SDO_PIN_DIR = PIN_OUTPUT;
|
||||
TEMP_SENSOR_SPI_SDI_PIN_DIR = PIN_INPUT;
|
||||
TEMP_SENSOR_SPI_SCK_PIN_DIR = PIN_OUTPUT;
|
||||
SPI3CON = 0;
|
||||
SPI3CONbits.MSTEN = 1;
|
||||
SPI3CONbits.CKE = 1;
|
||||
SPI3CONbits.SMP = 0;
|
||||
SPI3CONbits.CKP = 0;
|
||||
SPI3BRG = SPICalculateBRG(PERIPHERAL_FREQ, 1000000);
|
||||
SPI3CONbits.ON = 1;
|
||||
|
||||
//////////////// CURRENT SENSOR //////////////////
|
||||
//Analog (Hall effect) current sensor
|
||||
CURRENT_SENSOR_IN1_PIN_DIR = PIN_INPUT; //AN2
|
||||
CURRENT_SENSOR_IN2_PIN_DIR = PIN_INPUT; //AN0
|
||||
|
||||
//TODO
|
||||
// AD1CHS = 0;
|
||||
// AD1CHSbits.CH0SA = 1; //AN2
|
||||
// AD1CON3bits.ADCS = 0xF0;
|
||||
// AD1CON3bits.SAMC = 0x01;
|
||||
// AD1CON1bits.ON = 1;
|
||||
// AD1CON1bits.SAMP = 1;
|
||||
|
||||
|
||||
//////////////// LORA //////////////////
|
||||
LORA_MODULE_RELAY_PIN_DIR = PIN_OUTPUT;
|
||||
LORA_MODULE_RELAY_PIN = 0;
|
||||
// LORA_MODULE_M0_PIN_DIR = PIN_INPUT;
|
||||
// LORA_MODULE_M0_PIN = 0;
|
||||
// LORA_MODULE_M1_PIN_DIR = PIN_INPUT;
|
||||
// LORA_MODULE_M1_PIN = 0;
|
||||
LORA_MODULE_INT_PIN_DIR = PIN_INPUT;
|
||||
LORA_MODULE_RX_LED_PIN_DIR = PIN_OUTPUT;
|
||||
LORA_MODULE_RX_LED_PIN = LED_OFF;
|
||||
LORA_MODULE_TX_LED_PIN_DIR = PIN_OUTPUT;
|
||||
LORA_MODULE_TX_LED_PIN = LED_OFF;
|
||||
|
||||
//////////////// LCD SCREEN //////////////////
|
||||
//LCD Screen
|
||||
LCD_RS_PIN_DIR = PIN_OUTPUT;
|
||||
LCD_RS_PIN = 0;
|
||||
LCD_RW_PIN_DIR = PIN_OUTPUT;
|
||||
LCD_RW_PIN = 0;
|
||||
LCD_E_PIN_DIR = PIN_OUTPUT;
|
||||
LCD_E_PIN = 0;
|
||||
LCD_DB4_PIN_DIR = PIN_OUTPUT;
|
||||
LCD_DB4_PIN = 0;
|
||||
LCD_DB5_PIN_DIR = PIN_OUTPUT;
|
||||
LCD_DB5_PIN = 0;
|
||||
LCD_DB6_PIN_DIR = PIN_OUTPUT;
|
||||
LCD_DB6_PIN = 0;
|
||||
LCD_DB7_PIN_DIR = PIN_OUTPUT;
|
||||
LCD_DB7_PIN = 0;
|
||||
|
||||
LCD_SCROLL_BTN_PIN_DIR = PIN_INPUT;
|
||||
|
||||
|
||||
|
||||
|
||||
////// MISC UNUSED STUFF ///////////
|
||||
// IEC0bits.INT1IE = 0;
|
||||
// IFS0bits.INT1IF = 0;
|
||||
// INTCONbits.INT1EP = 1; //Rising edge
|
||||
// IPC1bits.INT1IP = 2;
|
||||
// IPC1bits.INT1IS = 1;
|
||||
// IEC0bits.INT1IE = 1;
|
||||
|
||||
|
||||
// OC3CON = 0;
|
||||
// OC3R = 0;
|
||||
// OC3RS = 2000; //50% PWM
|
||||
// OC3CONbits.OCTSEL = 0;
|
||||
// OC3CONbits.OCM = 0b110; //PWM mode, no fault protection
|
||||
|
||||
//#ifdef __32MX330F064H__
|
||||
// RPD2Rbits.RPD2R = 0b1011; //RD2 peripheral selection = OC3
|
||||
//#endif
|
||||
//
|
||||
// T2CONbits.TON = 0; // Disable Timer
|
||||
// // T2CONbits.TCS = 0; // Select internal instruction cycle clock
|
||||
// T2CONbits.TGATE = 0; // Disable Gated Timer mode
|
||||
// T2CONbits.TCKPS = 0b011; // Select 1:1 Prescaler
|
||||
// TMR2 = 0x00; // Clear timer register
|
||||
//
|
||||
//
|
||||
// IPC2bits.T2IP = 0x01; // Set Timer 2 Interrupt Priority Level
|
||||
// IFS0bits.T2IF = 0; // Clear Timer 2 Interrupt Flag
|
||||
// IEC0bits.T2IE = 0; // Disable Timer 2 interrupt
|
||||
// T2CONbits.TON = 1; // Start Timer
|
||||
//
|
||||
// OC3CONbits.ON = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
15
ChaloupeLora.X/Source/CurrentSensor.c
Normal file
15
ChaloupeLora.X/Source/CurrentSensor.c
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
#include "define.h"
|
||||
#include "CurrentSensor.h"
|
||||
#include "ina219.h"
|
||||
|
||||
int CurrentSensorInit()
|
||||
{
|
||||
ina219SetCalibration_16V_200mA();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int GetSolarPanelCurrent()
|
||||
{
|
||||
return ina219GetCurrent();
|
||||
}
|
||||
16
ChaloupeLora.X/Source/CurrentSensor.h
Normal file
16
ChaloupeLora.X/Source/CurrentSensor.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* File: SPI.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on December 2, 2018, 3:36 PM
|
||||
*/
|
||||
|
||||
#ifndef CURRENTSENSOR_H
|
||||
#define CURRENTSENSOR_H
|
||||
|
||||
int CurrentSensorInit();
|
||||
|
||||
int GetSolarPanelCurrent();
|
||||
|
||||
#endif /* CURRENTSENSOR_H */
|
||||
|
||||
42
ChaloupeLora.X/Source/DigitalIO.c
Normal file
42
ChaloupeLora.X/Source/DigitalIO.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C code file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ¤Revision:
|
||||
000 20100616 JFM,
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "DigitalIO.h"
|
||||
//#include "define.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void InitDigitalIO(void)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//EOF
|
||||
|
||||
|
||||
36
ChaloupeLora.X/Source/DigitalIO.h
Normal file
36
ChaloupeLora.X/Source/DigitalIO.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ¤Revision:
|
||||
000 20100616 JFM,
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
#ifndef DIGITAL_IO_H
|
||||
#define DIGITAL_IO_H
|
||||
#include "BoardCfg.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
//EOF
|
||||
|
||||
|
||||
225
ChaloupeLora.X/Source/FatFS/diskio.c
Normal file
225
ChaloupeLora.X/Source/FatFS/diskio.c
Normal file
@ -0,0 +1,225 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* If a working storage control module is available, it should be */
|
||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||
/* This is an example of glue functions to attach various exsisting */
|
||||
/* storage control modules to the FatFs module with a defined API. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define DEV_RAM 1 /* Example: Map Ramdisk to physical drive 0 */
|
||||
#define DEV_MMC 0 /* Example: Map MMC/SD card to physical drive 1 */
|
||||
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
DSTATUS stat;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case DEV_RAM :
|
||||
// result = RAM_disk_status();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
|
||||
case DEV_MMC :
|
||||
// result = MMC_disk_status();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
|
||||
case DEV_USB :
|
||||
// result = USB_disk_status();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
}
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
DSTATUS stat;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case DEV_RAM :
|
||||
//result = RAM_disk_initialize();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
|
||||
case DEV_MMC :
|
||||
// result = MMC_disk_initialize();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
|
||||
case DEV_USB :
|
||||
// result = USB_disk_initialize();
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return stat;
|
||||
}
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case DEV_RAM :
|
||||
// translate the arguments here
|
||||
|
||||
// result = RAM_disk_read(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
|
||||
case DEV_MMC :
|
||||
// translate the arguments here
|
||||
|
||||
// result = MMC_disk_read(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
|
||||
case DEV_USB :
|
||||
// translate the arguments here
|
||||
|
||||
// result = USB_disk_read(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case DEV_RAM :
|
||||
// translate the arguments here
|
||||
|
||||
// result = RAM_disk_write(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
|
||||
case DEV_MMC :
|
||||
// translate the arguments here
|
||||
|
||||
// result = MMC_disk_write(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
|
||||
case DEV_USB :
|
||||
// translate the arguments here
|
||||
|
||||
// result = USB_disk_write(buff, sector, count);
|
||||
|
||||
// translate the reslut code here
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
int result;
|
||||
|
||||
switch (pdrv) {
|
||||
case DEV_RAM :
|
||||
|
||||
// Process of the command for the RAM drive
|
||||
|
||||
return res;
|
||||
|
||||
case DEV_MMC :
|
||||
|
||||
// Process of the command for the MMC/SD card
|
||||
|
||||
return res;
|
||||
|
||||
case DEV_USB :
|
||||
|
||||
// Process of the command the USB drive
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
101
ChaloupeLora.X/Source/FatFS/diskio.h
Normal file
101
ChaloupeLora.X/Source/FatFS/diskio.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
#define _USE_WRITE 1
|
||||
#define _USE_IOCTL 1
|
||||
|
||||
#define _USE
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
void disk_timerproc(void);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
||||
|
||||
///* Generic command (Not used by FatFs) */
|
||||
//#define CTRL_POWER 5 /* Get/Set power status */
|
||||
//#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
//#define CTRL_EJECT 7 /* Eject media */
|
||||
//#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_FORMAT 5 /* Create physical format on the media */
|
||||
#define CTRL_POWER_IDLE 6 /* Put the device idle state */
|
||||
#define CTRL_POWER_OFF 7 /* Put the device off state */
|
||||
#define CTRL_LOCK 8 /* Lock media removal */
|
||||
#define CTRL_UNLOCK 9 /* Unlock media removal */
|
||||
#define CTRL_EJECT 10 /* Eject media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* MMC card type flags (MMC_GET_TYPE) */
|
||||
#define CT_MMC 0x01 /* MMC ver 3 */
|
||||
#define CT_SD1 0x02 /* SD ver 1 */
|
||||
#define CT_SD2 0x04 /* SD ver 2 */
|
||||
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
|
||||
#define CT_BLOCK 0x08 /* Block addressing */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
6555
ChaloupeLora.X/Source/FatFS/ff.c
Normal file
6555
ChaloupeLora.X/Source/FatFS/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
366
ChaloupeLora.X/Source/FatFS/ff.h
Normal file
366
ChaloupeLora.X/Source/FatFS/ff.h
Normal file
@ -0,0 +1,366 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13a /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 89352 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 2)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* Filesystem type (0:N/A) */
|
||||
BYTE pdrv; /* Physical drive number */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
#endif
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||
DWORD fsize; /* Size of an FAT [sectors] */
|
||||
DWORD volbase; /* Volume base sector */
|
||||
DWORD fatbase; /* FAT base sector */
|
||||
DWORD dirbase; /* Root directory base sector/cluster */
|
||||
DWORD database; /* Data base sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||
WORD id; /* Hosting volume mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||
#endif
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access mode and open method flags (3rd argument of f_open) */
|
||||
#define FA_READ 0x01
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA_OPEN_APPEND 0x30
|
||||
|
||||
/* Fast seek controls (2nd argument of f_lseek) */
|
||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||
|
||||
/* Format options (2nd argument of f_mkfs) */
|
||||
#define FM_FAT 0x01
|
||||
#define FM_FAT32 0x02
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_EXFAT 4
|
||||
|
||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FF_DEFINED */
|
||||
283
ChaloupeLora.X/Source/FatFS/ffconf.h
Normal file
283
ChaloupeLora.X/Source/FatFS/ffconf.h
Normal file
@ -0,0 +1,283 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - Configuration file
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 89352 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 0
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 437
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 0
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#define FF_LFN_UNICODE 0
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
/* FF_STR_VOLUME_ID switches string support for volume ID.
|
||||
/ When FF_STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the drive ID strings for each
|
||||
/ logical drives. Number of items must be equal to FF_VOLUMES. Valid characters for
|
||||
/ the drive ID strings are: A-Z and 0-9. */
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 0
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 0
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ When enable exFAT, also LFN needs to be enabled.
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 1
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2017
|
||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
/* #include <windows.h> // O/S definitions */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
171
ChaloupeLora.X/Source/FatFS/ffsystem.c
Normal file
171
ChaloupeLora.X/Source/FatFS/ffsystem.c
Normal file
@ -0,0 +1,171 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C)ChaN, 2017 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free (nothing to do for null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object for the volume, such as semaphore and mutex.
|
||||
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
//const osMutexDef_t Mutex[FF_VOLUMES]; /* CMSIS-RTOS */
|
||||
|
||||
|
||||
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
|
||||
BYTE vol, /* Corresponding volume (logical drive number) */
|
||||
FF_SYNC_t *sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL);
|
||||
return (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
/* uITRON */
|
||||
// T_CSEM csem = {TA_TPRI,1,1};
|
||||
// *sobj = acre_sem(&csem);
|
||||
// return (int)(*sobj > 0);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// *sobj = OSMutexCreate(0, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// *sobj = xSemaphoreCreateMutex();
|
||||
// return (int)(*sobj != NULL);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// *sobj = osMutexCreate(Mutex + vol);
|
||||
// return (int)(*sobj != NULL);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to delete a synchronization
|
||||
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
|
||||
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)CloseHandle(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(del_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// vSemaphoreDelete(sobj);
|
||||
// return 1;
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexDelete(sobj) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on entering file functions to lock the volume.
|
||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
||||
FF_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(wai_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
FF_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
ReleaseMutex(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// sig_sem(sobj);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OSMutexPost(sobj);
|
||||
|
||||
/* FreeRTOS */
|
||||
// xSemaphoreGive(sobj);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// osMutexRelease(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
15586
ChaloupeLora.X/Source/FatFS/ffunicode.c
Normal file
15586
ChaloupeLora.X/Source/FatFS/ffunicode.c
Normal file
File diff suppressed because it is too large
Load Diff
38
ChaloupeLora.X/Source/FatFS/integer.h
Normal file
38
ChaloupeLora.X/Source/FatFS/integer.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef FF_INTEGER
|
||||
#define FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types MUST be 16-bit or 32-bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* This type MUST be 8-bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types MUST be 16-bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
660
ChaloupeLora.X/Source/FatFS/mmc_drv.c
Normal file
660
ChaloupeLora.X/Source/FatFS/mmc_drv.c
Normal file
@ -0,0 +1,660 @@
|
||||
/*------------------------------------------------------------------------/
|
||||
/ MMCv3/SDv1/SDv2+ (in SPI mode) control module
|
||||
/-------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2014, ChaN, all right reserved.
|
||||
/
|
||||
/ * This software is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
//#include <p24FJ64GA002.h>
|
||||
//#include <plib.h>
|
||||
#include "DigitalIO.h"
|
||||
#include "diskio.h"
|
||||
|
||||
static inline __attribute__((always_inline)) unsigned char SPICalculateBRG(unsigned int pb_clk, unsigned int spi_clk);
|
||||
static void set_fast_clk(void);
|
||||
static void set_slow_clk(void);
|
||||
|
||||
|
||||
/* Socket controls (Platform dependent) */
|
||||
#define CS_LOW() SD_SPI_CS_PIN = 0 /* MMC CS = L */
|
||||
#define CS_HIGH() SD_SPI_CS_PIN = 1 /* MMC CS = H */
|
||||
#define MMC_CD (true) /* Card detected (yes:true, no:false, default:true) */
|
||||
#define MMC_WP (false) /* Write protected (yes:true, no:false, default:false) */
|
||||
|
||||
/* SPI bit rate controls */
|
||||
#define FCLK_SLOW() set_slow_clk() /* Set slow clock for card initialization (100k-400k) */
|
||||
#define FCLK_FAST() set_fast_clk() /* Set fast clock for generic read/write */
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Module Private Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Definitions for MMC/SDC command */
|
||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
||||
#define CMD1 (1) /* SEND_OP_COND */
|
||||
#define ACMD41 (41|0x80) /* SEND_OP_COND (SDC) */
|
||||
#define CMD8 (8) /* SEND_IF_COND */
|
||||
#define CMD9 (9) /* SEND_CSD */
|
||||
#define CMD10 (10) /* SEND_CID */
|
||||
#define CMD12 (12) /* STOP_TRANSMISSION */
|
||||
#define ACMD13 (13|0x80) /* SD_STATUS (SDC) */
|
||||
#define CMD16 (16) /* SET_BLOCKLEN */
|
||||
#define CMD17 (17) /* READ_SINGLE_BLOCK */
|
||||
#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
|
||||
#define CMD23 (23) /* SET_BLOCK_COUNT */
|
||||
#define ACMD23 (23|0x80) /* SET_WR_BLK_ERASE_COUNT (SDC) */
|
||||
#define CMD24 (24) /* WRITE_BLOCK */
|
||||
#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
|
||||
#define CMD41 (41) /* SEND_OP_COND (ACMD) */
|
||||
#define CMD55 (55) /* APP_CMD */
|
||||
#define CMD58 (58) /* READ_OCR */
|
||||
|
||||
|
||||
static volatile
|
||||
DSTATUS Stat = STA_NOINIT; /* Disk status */
|
||||
|
||||
static volatile
|
||||
UINT Timer1, Timer2; /* 1000Hz decrement timer */
|
||||
|
||||
static
|
||||
UINT CardType;
|
||||
|
||||
|
||||
|
||||
static inline __attribute__((always_inline)) unsigned char SPICalculateBRG(unsigned int pb_clk, unsigned int spi_clk)
|
||||
{
|
||||
unsigned int brg;
|
||||
|
||||
brg = pb_clk / (2 * spi_clk);
|
||||
|
||||
if(pb_clk % (2 * spi_clk))
|
||||
brg++;
|
||||
|
||||
if(brg > 0x100)
|
||||
brg = 0x100;
|
||||
|
||||
if(brg)
|
||||
brg--;
|
||||
|
||||
return (unsigned char) brg;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Interface Controls (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* When the target system does not support socket power control, there */
|
||||
/* is nothing to do in these functions. */
|
||||
|
||||
static void power_on (void)
|
||||
{
|
||||
SPI2CON = 0;
|
||||
SPI2CONbits.MSTEN = 1;
|
||||
SPI2CONbits.CKE = 0;
|
||||
SPI2CONbits.CKP = 1;
|
||||
|
||||
FCLK_SLOW();
|
||||
|
||||
SPI2CONbits.ON = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void power_off (void)
|
||||
{
|
||||
SPI2CONbits.ON = 0; /* Disable SPI2 */
|
||||
}
|
||||
|
||||
static void set_slow_clk(void)
|
||||
{
|
||||
unsigned WasON = SPI2CONbits.ON;
|
||||
|
||||
SPI2CONbits.ON = 0;
|
||||
SPI2BRG = SPICalculateBRG(80000000,40000);
|
||||
|
||||
SPI2CONbits.ON = WasON;
|
||||
}
|
||||
|
||||
static void set_fast_clk(void)
|
||||
{
|
||||
unsigned WasON = SPI2CONbits.ON;
|
||||
SPI2CONbits.ON = 0;
|
||||
|
||||
SPI2BRG = SPICalculateBRG(80000000,20000000);
|
||||
|
||||
SPI2CONbits.ON = WasON;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SPI Transactions (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
/* Single byte SPI transaction */
|
||||
static BYTE xchg_spi (BYTE dat)
|
||||
{
|
||||
|
||||
#ifndef USE_PINGUINO
|
||||
while( SPI2STATbits.SPITBF == 1 )
|
||||
{
|
||||
}
|
||||
#endif
|
||||
// ----------------
|
||||
// sending data
|
||||
// ----------------
|
||||
SPI2BUF = dat;
|
||||
|
||||
while(SPI2STATbits.SPIRBF == 0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
return (BYTE)SPI2BUF; /* Get received byte */
|
||||
}
|
||||
|
||||
|
||||
/* Multi-byte SPI transaction (transmit) */
|
||||
static
|
||||
void xmit_spi_multi (
|
||||
const BYTE* buff, /* Data to be sent */
|
||||
UINT cnt /* Number of bytes to send */
|
||||
)
|
||||
{
|
||||
do {
|
||||
SPI2BUF = *buff++; /* Initiate an SPI transaction */
|
||||
while (SPI2STATbits.SPIRBF == 0) ; /* Wait for end of the SPI transaction */
|
||||
SPI2BUF; /* Discard received byte */
|
||||
SPI2BUF = *buff++;
|
||||
while (SPI2STATbits.SPIRBF == 0) ;
|
||||
SPI2BUF;
|
||||
} while (cnt -= 2);
|
||||
}
|
||||
|
||||
|
||||
/* Multi-byte SPI transaction (receive) */
|
||||
static
|
||||
void rcvr_spi_multi (
|
||||
BYTE* buff, /* Buffer to store received data */
|
||||
UINT cnt /* Number of bytes to receive */
|
||||
)
|
||||
{
|
||||
do {
|
||||
SPI2BUF = 0xFF; /* Initiate an SPI transaction */
|
||||
while (SPI2STATbits.SPIRBF == 0) ; /* Wait for end of the SPI transaction */
|
||||
*buff++ = SPI2BUF; /* Get received byte */
|
||||
SPI2BUF = 0xFF;
|
||||
while (SPI2STATbits.SPIRBF == 0) ;
|
||||
*buff++ = SPI2BUF;
|
||||
} while (cnt -= 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Wait for card ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int wait_ready (void)
|
||||
{
|
||||
BYTE d;
|
||||
|
||||
Timer2 = 500; /* Wait for ready in timeout of 500ms */
|
||||
do {
|
||||
d = xchg_spi(0xFF);
|
||||
} while ((d != 0xFF) && Timer2);
|
||||
|
||||
return (d == 0xFF) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Deselect the card and release SPI bus */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void deselect (void)
|
||||
{
|
||||
CS_HIGH(); /* Set CS# high */
|
||||
xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Select the card and wait ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int select (void) /* 1:Successful, 0:Timeout */
|
||||
{
|
||||
CS_LOW(); /* Set CS# low */
|
||||
xchg_spi(0xFF); /* Dummy clock (force DO enabled) */
|
||||
|
||||
if (wait_ready()) return 1; /* Wait for card ready */
|
||||
|
||||
deselect();
|
||||
return 0; /* Timeout */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Receive a data packet from MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int rcvr_datablock ( /* 1:OK, 0:Failed */
|
||||
BYTE *buff, /* Data buffer to store received data */
|
||||
UINT btr /* Byte count (must be multiple of 4) */
|
||||
)
|
||||
{
|
||||
BYTE token;
|
||||
|
||||
|
||||
Timer1 = 100;
|
||||
do { /* Wait for data packet in timeout of 100ms */
|
||||
token = xchg_spi(0xFF);
|
||||
} while ((token == 0xFF) && Timer1);
|
||||
|
||||
if(token != 0xFE) return 0; /* If not valid data token, retutn with error */
|
||||
|
||||
rcvr_spi_multi(buff, btr); /* Receive the data block into buffer */
|
||||
xchg_spi(0xFF); /* Discard CRC */
|
||||
xchg_spi(0xFF);
|
||||
|
||||
return 1; /* Return with success */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a data packet to MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
static
|
||||
int xmit_datablock ( /* 1:OK, 0:Failed */
|
||||
const BYTE *buff, /* 512 byte data block to be transmitted */
|
||||
BYTE token /* Data token */
|
||||
)
|
||||
{
|
||||
BYTE resp;
|
||||
|
||||
|
||||
if (!wait_ready()) return 0;
|
||||
|
||||
xchg_spi(token); /* Xmit a token */
|
||||
if (token != 0xFD) { /* Not StopTran token */
|
||||
xmit_spi_multi(buff, 512); /* Xmit the data block to the MMC */
|
||||
xchg_spi(0xFF); /* CRC (Dummy) */
|
||||
xchg_spi(0xFF);
|
||||
resp = xchg_spi(0xFF); /* Receive a data response */
|
||||
if ((resp & 0x1F) != 0x05) return 0; /* If not accepted, return with error */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a command packet to MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BYTE send_cmd (
|
||||
BYTE cmd, /* Command byte */
|
||||
DWORD arg /* Argument */
|
||||
)
|
||||
{
|
||||
BYTE n, res;
|
||||
|
||||
|
||||
if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
|
||||
cmd &= 0x7F;
|
||||
res = send_cmd(CMD55, 0);
|
||||
if (res > 1) return res;
|
||||
}
|
||||
|
||||
/* Select the card and wait for ready except to stop multiple block read */
|
||||
if (cmd != CMD12) {
|
||||
deselect();
|
||||
if (!select()) return 0xFF;
|
||||
}
|
||||
|
||||
/* Send command packet */
|
||||
xchg_spi(0x40 | cmd); /* Start + Command index */
|
||||
xchg_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
|
||||
xchg_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
|
||||
xchg_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
|
||||
xchg_spi((BYTE)arg); /* Argument[7..0] */
|
||||
n = 0x01; /* Dummy CRC + Stop */
|
||||
if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) + Stop */
|
||||
if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) + Stop */
|
||||
xchg_spi(n);
|
||||
|
||||
/* Receive command response */
|
||||
if (cmd == CMD12) xchg_spi(0xFF); /* Skip a stuff byte on stop to read */
|
||||
n = 10; /* Wait for a valid response in timeout of 10 attempts */
|
||||
do {
|
||||
res = xchg_spi(0xFF);
|
||||
} while ((res & 0x80) && --n);
|
||||
|
||||
return res; /* Return with the response value */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Public Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Disk Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
if (pdrv != 0) return STA_NOINIT; /* Supports only single drive */
|
||||
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize Disk Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
BYTE n, cmd, ty, ocr[4];
|
||||
|
||||
|
||||
if (pdrv != 0) return STA_NOINIT; /* Supports only single drive */
|
||||
if (Stat & STA_NODISK) return Stat; /* No card in the socket */
|
||||
|
||||
power_on(); /* Initialize memory card interface */
|
||||
FCLK_SLOW();
|
||||
for (n = 10; n; n--) xchg_spi(0xFF); /* 80 dummy clocks */
|
||||
|
||||
ty = 0;
|
||||
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
|
||||
Timer1 = 1000; /* Initialization timeout of 1000 msec */
|
||||
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */
|
||||
for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); /* Get trailing return value of R7 resp */
|
||||
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
|
||||
while (Timer1 && send_cmd(ACMD41, 0x40000000)); /* Wait for leaving idle state (ACMD41 with HCS bit) */
|
||||
if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
|
||||
for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
|
||||
ty = (ocr[0] & 0x40) ? CT_SD2|CT_BLOCK : CT_SD2; /* SDv2+ */
|
||||
}
|
||||
}
|
||||
} else { /* SDv1 or MMCv3 */
|
||||
if (send_cmd(ACMD41, 0) <= 1) {
|
||||
ty = CT_SD1; cmd = ACMD41; /* SDv1 */
|
||||
} else {
|
||||
ty = CT_MMC; cmd = CMD1; /* MMCv3 */
|
||||
}
|
||||
while (Timer1 && send_cmd(cmd, 0)); /* Wait for leaving idle state */
|
||||
if (!Timer1 || send_cmd(CMD16, 512) != 0) ty = 0; /* Set read/write block length to 512 */
|
||||
}
|
||||
}
|
||||
CardType = ty;
|
||||
deselect();
|
||||
|
||||
if (ty) { /* Function succeded */
|
||||
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
|
||||
FCLK_FAST();
|
||||
} else { /* Function failed */
|
||||
power_off(); /* Deinitialize interface */
|
||||
}
|
||||
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE pdrv, /* Physical drive nmuber (0) */
|
||||
BYTE *buff, /* Pointer to the data buffer to store read data */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
UINT count /* Sector count (1..128) */
|
||||
)
|
||||
{
|
||||
if (pdrv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
|
||||
|
||||
if (count == 1) { /* Single block read */
|
||||
if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
|
||||
&& rcvr_datablock(buff, 512)) {
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
else { /* Multiple block read */
|
||||
if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
|
||||
do {
|
||||
if (!rcvr_datablock(buff, 512)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
|
||||
}
|
||||
}
|
||||
deselect();
|
||||
|
||||
return count ? RES_ERROR : RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber (0) */
|
||||
const BYTE *buff, /* Pointer to the data to be written */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
UINT count /* Sector count (1..128) */
|
||||
)
|
||||
{
|
||||
if (pdrv || !count) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
if (Stat & STA_PROTECT) return RES_WRPRT;
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
|
||||
|
||||
if (count == 1) { /* Single block write */
|
||||
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
|
||||
&& xmit_datablock(buff, 0xFE)) {
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
else { /* Multiple block write */
|
||||
if (CardType & CT_SDC) send_cmd(ACMD23, count);
|
||||
if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
|
||||
do {
|
||||
if (!xmit_datablock(buff, 0xFC)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
if (!xmit_datablock(0, 0xFD)) count = 1; /* STOP_TRAN token */
|
||||
}
|
||||
}
|
||||
deselect();
|
||||
|
||||
return count ? RES_ERROR : RES_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive data block */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
BYTE n, csd[16], *ptr = buff;
|
||||
DWORD csz;
|
||||
|
||||
|
||||
if (pdrv) return RES_PARERR;
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
||||
|
||||
res = RES_ERROR;
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC : /* Flush write-back cache, Wait for end of internal process */
|
||||
if (select()) res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (WORD) */
|
||||
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
|
||||
if ((csd[0] >> 6) == 1) { /* SDv2? */
|
||||
csz = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
|
||||
*(DWORD*)buff = csz << 10;
|
||||
} else { /* SDv1 or MMCv3 */
|
||||
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
|
||||
csz = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
|
||||
*(DWORD*)buff = csz << (n - 9);
|
||||
}
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in unit of sectors (DWORD) */
|
||||
if (CardType & CT_SD2) { /* SDv2+? */
|
||||
if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
|
||||
xchg_spi(0xFF);
|
||||
if (rcvr_datablock(csd, 16)) { /* Read partial block */
|
||||
for (n = 64 - 16; n; n--) xchg_spi(0xFF); /* Purge trailing data */
|
||||
*(DWORD*)buff = 16UL << (csd[10] >> 4);
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
} else { /* SDv1 or MMCv3 */
|
||||
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
|
||||
if (CardType & CT_SD1) { /* SDv1 */
|
||||
*(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
|
||||
} else { /* MMCv3 */
|
||||
*(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
|
||||
}
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MMC_GET_TYPE : /* Get card type flags (1 byte) */
|
||||
*ptr = CardType;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
|
||||
if ((send_cmd(CMD9, 0) == 0) /* READ_CSD */
|
||||
&& rcvr_datablock(buff, 16))
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
|
||||
if ((send_cmd(CMD10, 0) == 0) /* READ_CID */
|
||||
&& rcvr_datablock(buff, 16))
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
|
||||
if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
|
||||
for (n = 0; n < 4; n++)
|
||||
*((BYTE*)buff+n) = xchg_spi(0xFF);
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */
|
||||
if ((CardType & CT_SD2) && send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
|
||||
xchg_spi(0xFF);
|
||||
if (rcvr_datablock(buff, 64)) res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_POWER_OFF : /* Power off */
|
||||
power_off();
|
||||
Stat |= STA_NOINIT;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
res = RES_PARERR;
|
||||
}
|
||||
|
||||
deselect();
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Device Timer Driven Procedure */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* This function must be called by timer interrupt in period of 1ms */
|
||||
|
||||
void disk_timerproc (void)
|
||||
{
|
||||
BYTE s;
|
||||
UINT n;
|
||||
|
||||
|
||||
n = Timer1; /* 1000Hz decrement timer with zero stopped */
|
||||
if (n) Timer1 = --n;
|
||||
n = Timer2;
|
||||
if (n) Timer2 = --n;
|
||||
|
||||
|
||||
/* Update socket status */
|
||||
|
||||
s = Stat;
|
||||
if (MMC_WP) {
|
||||
s |= STA_PROTECT;
|
||||
} else {
|
||||
s &= ~STA_PROTECT;
|
||||
}
|
||||
if (MMC_CD) {
|
||||
s &= ~STA_NODISK;
|
||||
} else {
|
||||
s |= (STA_NODISK | STA_NOINIT);
|
||||
}
|
||||
Stat = s;
|
||||
}
|
||||
|
||||
34
ChaloupeLora.X/Source/FlashMapping.h
Normal file
34
ChaloupeLora.X/Source/FlashMapping.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* File: ChaletPowerRelay.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 30, 2018, 7:33 PM
|
||||
*/
|
||||
|
||||
#ifndef FLASHMAPPING_H
|
||||
#define FLASHMAPPING_H
|
||||
#include "define.h"
|
||||
|
||||
/*
|
||||
0x180000 Firmware flags
|
||||
0x180004 Nb Records
|
||||
0x180008 Firmware Size
|
||||
0x18000C Version code
|
||||
*/
|
||||
|
||||
#define FLASH_END_ADDRESS 180000
|
||||
|
||||
#define FLASH_BTLDR_FIRMWARE_START_ADDRESS 0x180000
|
||||
#define FLASH_BTLDR_FIRMWARE_LAST_64K_SECTOR_ADD 0x1F0000
|
||||
#define FLASH_BTLDR_FLAGS_ADDRESS 0x000000
|
||||
#define FLASH_WIFI_IP_ADDRESS 0X00000C
|
||||
#define FLASH_WIFI_GATEWAY_ADDRESS 0x000010
|
||||
|
||||
|
||||
|
||||
|
||||
#define FLASH_BTLDR_HEADER_SIZE 24
|
||||
|
||||
|
||||
|
||||
#endif /* HARAKIRIRELAY_H */
|
||||
6
ChaloupeLora.X/Source/FubarinoBoard.c
Normal file
6
ChaloupeLora.X/Source/FubarinoBoard.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "BoardCfg.h"
|
||||
|
||||
int InitBoard()
|
||||
{
|
||||
return RET_OK;
|
||||
}
|
||||
21
ChaloupeLora.X/Source/HarakiriRelay.c
Normal file
21
ChaloupeLora.X/Source/HarakiriRelay.c
Normal file
@ -0,0 +1,21 @@
|
||||
//#include <proc/p32mx440f256h.h>
|
||||
|
||||
#include "HarakiriRelay.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define PIN_ACTIVE 1
|
||||
#define PIN_INACTIVE 0
|
||||
|
||||
|
||||
void InitHarakiriRelay()
|
||||
{
|
||||
HARAKIRI_RELAY_ON_PIN = PIN_INACTIVE; //Very important!!
|
||||
}
|
||||
|
||||
|
||||
bool HarakiriRelayTurnOff()
|
||||
{
|
||||
HARAKIRI_RELAY_ON_PIN = PIN_ACTIVE; //Just wait for the power to be killed...
|
||||
return true;
|
||||
}
|
||||
19
ChaloupeLora.X/Source/HarakiriRelay.h
Normal file
19
ChaloupeLora.X/Source/HarakiriRelay.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* File: ChaletPowerRelay.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 30, 2018, 7:33 PM
|
||||
*/
|
||||
|
||||
#ifndef HARAKIRIRELAY_H
|
||||
#define HARAKIRIRELAY_H
|
||||
#include "define.h"
|
||||
|
||||
|
||||
void InitHarakiriRelay();
|
||||
|
||||
bool HarakiriRelayTurnOff();
|
||||
|
||||
|
||||
#endif /* HARAKIRIRELAY_H */
|
||||
|
||||
171
ChaloupeLora.X/Source/I2C.c
Normal file
171
ChaloupeLora.X/Source/I2C.c
Normal file
@ -0,0 +1,171 @@
|
||||
#include "define.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "I2C.h"
|
||||
|
||||
int mLastTransactionOK;
|
||||
int mI2CWaitCounter;
|
||||
|
||||
int I2CInit()
|
||||
{
|
||||
//SPI and I2C BRG work the same way. So let's reuse some code!
|
||||
// int BaudRateGenerator = SPICalculateBRG(80000000,100000); //PBclk is 80MHz, I2C clk = 100KHz
|
||||
int BaudRateGenerator = 398;
|
||||
|
||||
I2C3CON = 0;
|
||||
|
||||
I2C3CONbits.DISSLW = 1; //disable slew rate control since we are only at 100KHz
|
||||
I2C3BRG = BaudRateGenerator;
|
||||
|
||||
I2C3CONbits.ON = 1;
|
||||
|
||||
mLastTransactionOK = 0;
|
||||
mI2CWaitCounter = 0;
|
||||
}
|
||||
|
||||
|
||||
int I2CWrite(unsigned char* OutBuf, unsigned char length)
|
||||
{
|
||||
int RET = RET_OK;
|
||||
int i;
|
||||
|
||||
//Emit start event
|
||||
I2C3CONbits.SEN = 1;
|
||||
while(I2C3CONbits.SEN == 1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if(I2C3STATbits.BCL == 1)
|
||||
{
|
||||
mLastTransactionOK = false;
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
{
|
||||
I2C3TRN = OutBuf[i];
|
||||
mI2CWaitCounter = 0;
|
||||
while(I2C3STATbits.TRSTAT == 1)
|
||||
{
|
||||
if(I2C3STATbits.BCL == 1 || mI2CWaitCounter++ > I2C_TRANSACTION_TIMEOUT_COUNT)
|
||||
{
|
||||
mLastTransactionOK = false;
|
||||
RET = RET_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if(I2C3STATbits.ACKSTAT == 1)
|
||||
// {
|
||||
// RET = RET_ERROR;
|
||||
// }
|
||||
}
|
||||
|
||||
//Emit stop event
|
||||
I2C3CONbits.PEN = 1;
|
||||
mI2CWaitCounter = 0;
|
||||
while(I2C3CONbits.PEN == 1)
|
||||
{
|
||||
if(I2C3STATbits.BCL == 1 || mI2CWaitCounter++ > I2C_TRANSACTION_TIMEOUT_COUNT)
|
||||
{
|
||||
mLastTransactionOK = false;
|
||||
RET = RET_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mLastTransactionOK = true;
|
||||
return RET;
|
||||
}
|
||||
|
||||
int I2CTransmitByte(unsigned char Byte)
|
||||
{
|
||||
|
||||
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
int I2CRead(unsigned char SlaveAddress,unsigned char* InputBuf,unsigned char length)
|
||||
{
|
||||
int RET = RET_OK;
|
||||
int i;
|
||||
//Emit start event
|
||||
|
||||
I2C3CONbits.SEN = 1;
|
||||
mI2CWaitCounter = 0;
|
||||
while(I2C3CONbits.SEN == 1)
|
||||
|
||||
if(I2C3STATbits.BCL == 1)
|
||||
{
|
||||
mLastTransactionOK = false;
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
//Transmit slave address and write bit
|
||||
I2C3TRN = SlaveAddress;
|
||||
mI2CWaitCounter = 0;
|
||||
while(I2C3STATbits.TRSTAT == 1)
|
||||
{
|
||||
|
||||
if(I2C3STATbits.BCL == 1 || mI2CWaitCounter++ > I2C_TRANSACTION_TIMEOUT_COUNT)
|
||||
{
|
||||
mLastTransactionOK = false;
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
{
|
||||
//
|
||||
I2C3CONbits.RCEN = 1;
|
||||
mI2CWaitCounter = 0;
|
||||
while(I2C3CONbits.RCEN == 1)
|
||||
{
|
||||
|
||||
if(I2C3STATbits.BCL == 1 || mI2CWaitCounter++ > I2C_TRANSACTION_TIMEOUT_COUNT)
|
||||
{
|
||||
mLastTransactionOK = false;
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
InputBuf[i] = I2C3RCV;
|
||||
|
||||
//Acknowledge reception
|
||||
I2C3CONbits.ACKDT = 1;
|
||||
I2C3CONbits.ACKEN = 1;
|
||||
mI2CWaitCounter = 0;
|
||||
while(I2C3CONbits.ACKEN == 1)
|
||||
{
|
||||
|
||||
if(I2C3STATbits.BCL == 1 || mI2CWaitCounter++ > I2C_TRANSACTION_TIMEOUT_COUNT)
|
||||
{
|
||||
mLastTransactionOK = false;
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Emit stop event
|
||||
I2C3CONbits.PEN = 1;
|
||||
mI2CWaitCounter = 0;
|
||||
while(I2C3CONbits.PEN == 1)
|
||||
{
|
||||
|
||||
if(I2C3STATbits.BCL == 1 || mI2CWaitCounter++ > I2C_TRANSACTION_TIMEOUT_COUNT)
|
||||
{
|
||||
mLastTransactionOK = false;
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mLastTransactionOK = true;
|
||||
return RET;
|
||||
}
|
||||
|
||||
bool I2CWasLastTransactionOK()
|
||||
{
|
||||
return mLastTransactionOK;
|
||||
}
|
||||
21
ChaloupeLora.X/Source/I2C.h
Normal file
21
ChaloupeLora.X/Source/I2C.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* File: SPI.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on December 2, 2018, 3:36 PM
|
||||
*/
|
||||
|
||||
#ifndef I2C_H
|
||||
#define I2C_H
|
||||
|
||||
#define I2C_BUFSIZE 10
|
||||
#define I2C_TRANSACTION_TIMEOUT_COUNT 800000 //around 10ms
|
||||
|
||||
int I2CInit();
|
||||
int I2CWrite(unsigned char* OutBuf, unsigned char length);
|
||||
int I2CRead(unsigned char SlaveAddress, unsigned char* InputBuf,unsigned char length);
|
||||
|
||||
bool I2CWasLastTransactionOK();
|
||||
|
||||
#endif /* SPI_H */
|
||||
|
||||
597
ChaloupeLora.X/Source/InternalUart.c
Normal file
597
ChaloupeLora.X/Source/InternalUart.c
Normal file
@ -0,0 +1,597 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C code file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ¤Revision:
|
||||
000 20100616 JFM,
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
#include "InternalUart.h"
|
||||
#include "uart.h"
|
||||
#include <stdio.h>
|
||||
//#include "Watchdog.h"
|
||||
#include "digitalio.h"
|
||||
#include "NetworkProtocol.h"
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Local variables */
|
||||
char acIntUartRxBuff[MAX_INTERNAL_UART_PORT][INTERNAL_UART_BUFFER_DEPTH]; //Rx Buffers
|
||||
stInternalUartData astInternalUartData[MAX_INTERNAL_UART_PORT]; //port management data
|
||||
|
||||
unsigned int LoraData = 0;
|
||||
|
||||
void process(void);
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void InternalUartInit(void)
|
||||
{
|
||||
//Setup port 1
|
||||
//
|
||||
// U1MODEbits.ON = 0; //disable module
|
||||
// U1STA = 0;
|
||||
// U1STAbits.UTXEN = 0; //disable transmitter
|
||||
// IPC6bits.U1IP = 7; //priority 7
|
||||
// IPC6bits.U1IS = 3; //sub-priority 3
|
||||
// U1STAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
|
||||
//// U1STAbits.UTXSEL = 0b01; // //JFM 2012-08-27
|
||||
// IFS0bits.U1TXIF = 0; //clear interrupt flag
|
||||
// IEC0bits.U1TXIE = 1; //enable tx interrupt
|
||||
// U1STAbits.URXISEL = 0b00; //interrupt for each character received
|
||||
// IFS0bits.U1RXIF = 0;
|
||||
//#ifdef POLL_UART1_RX
|
||||
// IEC0bits.U1RXIE = 0; //disable rx interrupts
|
||||
//#else
|
||||
// IEC0bits.U1RXIE = 1; //enable rx interrupts
|
||||
//#endif
|
||||
// U1STAbits.URXEN = 1; //enable receiver
|
||||
// U1MODEbits.ON = 0; //disable module
|
||||
|
||||
//Setup port 2
|
||||
//
|
||||
U2MODEbits.ON = 0; //disable module
|
||||
U2STA = 0;
|
||||
U2STAbits.UTXEN = 0; //disable transmitter
|
||||
IPC8bits.U2IP = 7; //priority 7
|
||||
IPC8bits.U2IS = 0; //sub-priority 2
|
||||
U2STAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
|
||||
IFS1bits.U2TXIF = 0; //clear interrupt flag
|
||||
IEC1bits.U2TXIE = 0; //enable tx interrupt
|
||||
U2STAbits.URXISEL = 0b00; //interrupt for each character received
|
||||
IFS1bits.U2RXIF = 0;
|
||||
#ifdef POLL_UART2_RX
|
||||
IEC1bits.U2RXIE = 0; //disable rx interrupts
|
||||
#else
|
||||
IEC1bits.U2RXIE = 1; //enable rx interrupts
|
||||
#endif
|
||||
U2STAbits.URXEN = 1; //enable receiver
|
||||
U2STAbits.UTXEN = 1;
|
||||
U2MODEbits.ON = 0; //disable module
|
||||
|
||||
|
||||
int i;
|
||||
for(i = 0; i < MAX_INTERNAL_UART_PORT; i++)
|
||||
{
|
||||
astInternalUartData[i].pcTxDataPtr = 0;
|
||||
astInternalUartData[i].iNbFIFOPendingBytes = 0;
|
||||
astInternalUartData[i].iTxDataSize = 0;
|
||||
astInternalUartData[i].iTxDataCounter = 0;
|
||||
astInternalUartData[i].iIsBusy = 0;
|
||||
astInternalUartData[i].iIsOpened = 0;
|
||||
astInternalUartData[i].iUartHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//int SetIntalUartInterrupts(int p_iUartPort, int p_iRxInterrupt,int p_iTxInterrupt)
|
||||
//{
|
||||
// if(p_iUartPort > MAX_INTERNAL_UART_PORT)
|
||||
// return UART_INVALID_PORT;
|
||||
//
|
||||
// switch(p_iUartPort)
|
||||
// {
|
||||
// case INTERNAL_UART_PORT_1:
|
||||
// {
|
||||
// if(p_iTxInterrupt)
|
||||
// {
|
||||
// IFS0bits.U1TXIF = 0; //clear interrupt flag
|
||||
// IEC0bits.U1TXIE = 1; //enable tx interrupt
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// IEC0bits.U1TXIE = 0; //disable tx interrupt
|
||||
// U1STAbits.UTXEN = 1; //This bit must be set when working without interrupts
|
||||
// }
|
||||
// if(p_iRxInterrupt)
|
||||
// {
|
||||
// IFS0bits.U1RXIF = 0;
|
||||
// IEC0bits.U1RXIE = 1; //enable rx interrupt
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// IEC0bits.U1RXIE = 0; //disable rx interrupt
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// case INTERNAL_UART_PORT_2:
|
||||
// {
|
||||
// if(p_iTxInterrupt)
|
||||
// {
|
||||
// IFS1bits.U2TXIF = 0; //clear interrupt flag
|
||||
// IEC1bits.U2TXIE = 1; //enable tx interrupt
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// IEC1bits.U2TXIE = 0; //disable tx interrupt
|
||||
// U2STAbits.UTXEN = 1; //This bit must be set when working without interrupts
|
||||
// }
|
||||
// if(p_iRxInterrupt)
|
||||
// {
|
||||
// IFS1bits.U2RXIF = 0;
|
||||
// IEC1bits.U2RXIE = 1; //enable rx interrupt
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// IEC1bits.U2RXIE = 0; //disable rx interrupt
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// {
|
||||
// return UART_INVALID_PORT;
|
||||
// }
|
||||
// }
|
||||
// return UART_OK;
|
||||
//}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int OpenInternalPort(int p_iUartPort,int p_iUartHandle,char *p_pcHeadPtr, char *p_pcTailPtr, int p_iBaudRate, int p_iNbStopBits, int p_iParityEnable)
|
||||
{
|
||||
if(p_iUartPort > MAX_INTERNAL_UART_PORT)
|
||||
return UART_INVALID_PORT;
|
||||
|
||||
int iBRG = (PERIPHERAL_FREQ/(4*p_iBaudRate)) - 1;
|
||||
int iMask = 0;
|
||||
|
||||
switch(p_iNbStopBits)
|
||||
{
|
||||
case INT_UART_ONE_STOP_BIT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case INT_UART_TWO_STOP_BITS:
|
||||
{
|
||||
iMask |= 0x00000001;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
astInternalUartData[p_iUartPort].iUartHandle = p_iUartHandle;
|
||||
|
||||
switch(p_iParityEnable)
|
||||
{
|
||||
case INT_UART_NO_PARITY:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case INT_UART_EVEN_PARITY:
|
||||
{
|
||||
iMask |= 0x00000002;
|
||||
break;
|
||||
}
|
||||
case INT_UART_ODD_PARITY:
|
||||
{
|
||||
iMask |= 0x00000004;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(p_iUartPort)
|
||||
{
|
||||
case INTERNAL_UART_PORT_1:
|
||||
{
|
||||
INTERNAL_UART1_TX_PIN_DIR = PIN_OUTPUT;
|
||||
INTERNAL_UART1_TX_PIN = 1;
|
||||
U1MODE = iMask;
|
||||
U1MODEbits.BRGH = 1;
|
||||
U1BRG = iBRG;
|
||||
U1MODEbits.ON = 1; //enable module
|
||||
break;
|
||||
}
|
||||
case INTERNAL_UART_PORT_2:
|
||||
{
|
||||
INTERNAL_UART2_TX_PIN_DIR = PIN_OUTPUT;
|
||||
INTERNAL_UART2_TX_PIN = 1;
|
||||
U2MODE = iMask;
|
||||
U2MODEbits.BRGH = 1;
|
||||
U2BRG = iBRG;
|
||||
U2MODEbits.ON = 1; //enable module
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
astInternalUartData[p_iUartPort].iIsOpened = 1;
|
||||
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int SendInternalUartData(char *p_pcDataBuf, int p_iDataSize, int p_iUartPort, char *p_pcSourceBufferHead, char *p_pcSourceBufferTail)
|
||||
{
|
||||
int iBufSize;
|
||||
int iAvailableBufSize;
|
||||
char *p_cDataPointer;
|
||||
int i;
|
||||
stInternalUartData *p_stUartDataPtr = &astInternalUartData[p_iUartPort];
|
||||
|
||||
if(p_stUartDataPtr->iIsOpened == 0)
|
||||
return UART_PORT_NOT_OPENED;
|
||||
|
||||
//We use a FIFO stack that must be empty before a new transaction can occur
|
||||
//if(p_stUartDataPtr->iNbFIFOPendingBytes != 0) //If FIFO not empty
|
||||
if(p_stUartDataPtr->iIsBusy == 1)
|
||||
return UART_PORT_BUSY; //no space is available so flag the port as BUSY...
|
||||
|
||||
iBufSize = p_iDataSize;
|
||||
if(iBufSize > INTERNAL_UART_BUFFER_DEPTH)
|
||||
iBufSize = INTERNAL_UART_BUFFER_DEPTH;
|
||||
|
||||
p_cDataPointer = p_stUartDataPtr->pcTxDataPtr = &p_stUartDataPtr->acIntUartTxFIFO[0];
|
||||
p_stUartDataPtr->iNbFIFOPendingBytes = iBufSize;
|
||||
|
||||
//Fill FIFO with data;
|
||||
for(i = 0; i< iBufSize; i++)
|
||||
{
|
||||
*p_cDataPointer++ = *p_pcDataBuf++;
|
||||
|
||||
if(p_pcDataBuf > p_pcSourceBufferTail) //check for wrapping of source data circular buffer.
|
||||
p_pcDataBuf = p_pcSourceBufferHead;
|
||||
}
|
||||
|
||||
p_stUartDataPtr->iIsBusy = 1; //informative flag to know we are TXing.
|
||||
|
||||
//Begin Transmission
|
||||
//A TX interrupt will be generated immediately after setting UTXEN
|
||||
switch(p_iUartPort)
|
||||
{
|
||||
case INTERNAL_UART_PORT_1:
|
||||
{
|
||||
if(IEC0bits.U1TXIE)
|
||||
{
|
||||
//We consider at this point that the data has been sent for the upper layer.
|
||||
DataSentNotification(p_stUartDataPtr->iUartHandle,iBufSize);
|
||||
U1STAbits.UTXEN = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < iBufSize; i++)
|
||||
{
|
||||
// KickWatchdog();
|
||||
U1TXREG = *p_stUartDataPtr->pcTxDataPtr++;
|
||||
while(U1STAbits.TRMT == 0);
|
||||
}
|
||||
p_stUartDataPtr->iIsBusy = 0;
|
||||
DataSentNotification(p_stUartDataPtr->iUartHandle,iBufSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INTERNAL_UART_PORT_2:
|
||||
{
|
||||
if(IEC1bits.U2TXIE)
|
||||
{
|
||||
//We consider at this point that the data has been sent for the upper layer.
|
||||
DataSentNotification(p_stUartDataPtr->iUartHandle,iBufSize);
|
||||
U2STAbits.UTXEN = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < iBufSize; i++)
|
||||
{
|
||||
// KickWatchdog();
|
||||
U2TXREG = *p_stUartDataPtr->pcTxDataPtr++;
|
||||
while(U2STAbits.TRMT == 0);
|
||||
LORA_MODULE_TX_LED_PIN = ~ LORA_MODULE_TX_LED_PIN;
|
||||
}
|
||||
p_stUartDataPtr->iIsBusy = 0;
|
||||
DataSentNotification(p_stUartDataPtr->iUartHandle,iBufSize);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
int SendInternalUartDataBlocking(char *p_pcDataBuf, int p_iDataSize, int p_iUartPort)
|
||||
{
|
||||
int i;
|
||||
int temp = IEC1;
|
||||
IEC1bits.U2TXIE = 0;
|
||||
for(i = 0; i < p_iDataSize; i++)
|
||||
{
|
||||
LORA_MODULE_TX_LED_PIN = ~ LORA_MODULE_TX_LED_PIN;
|
||||
U2TXREG = *p_pcDataBuf++;
|
||||
while(U2STAbits.TRMT == 0);
|
||||
}
|
||||
LORA_MODULE_TX_LED_PIN = LED_OFF;
|
||||
IFS1bits.U2TXIF = 0;
|
||||
IEC1 = temp;
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
void TickInternalUart(void)
|
||||
{
|
||||
#ifdef POLL_UART1_RX
|
||||
|
||||
if(U1STAbits.URXDA == 1)
|
||||
{
|
||||
if(U1STAbits.OERR) //Buffer overrun error. Data is lost.
|
||||
{
|
||||
U1STAbits.OERR = 0;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while(U1STAbits.URXDA && i < INTERNAL_UART_BUFFER_DEPTH)
|
||||
{
|
||||
char NewByte = U1RXREG;
|
||||
// DriveProtocolRxData(&NewByte,1);
|
||||
acIntUartRxBuff[INTERNAL_UART_PORT_1][i++] = NewByte;
|
||||
}
|
||||
// UartReceiveData(UART_1,&acIntUartRxBuff[INTERNAL_UART_PORT_1][0], i);
|
||||
// DriveProtocolRxData(&acIntUartRxBuff[INTERNAL_UART_PORT_1][0], i);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef POLL_UART2_RX
|
||||
if(U2STAbits.URXDA == 1)
|
||||
{
|
||||
int i = 0;
|
||||
while(U2STAbits.URXDA == 1 && i < INTERNAL_UART_BUFFER_DEPTH)
|
||||
{
|
||||
char NewByte = U2RXREG;
|
||||
// acIntUartRxBuff[INTERNAL_UART_PORT_2][i++] = NewByte;
|
||||
LORA_MODULE_RX_LED_PIN = ~LORA_MODULE_RX_LED_PIN;
|
||||
ProtocolAnalyzeNewData(NewByte);
|
||||
|
||||
|
||||
// LoraData <<= 8;
|
||||
// unsigned int toto = NewByte;
|
||||
// toto &= 0x000000FF;
|
||||
// LoraData |= toto;
|
||||
//
|
||||
// if(LoraData == 0xDEADBEEF)
|
||||
// {
|
||||
// HEARTBEAT_LED_1_PIN = ~HEARTBEAT_LED_1_PIN;
|
||||
// LORA_ACTIVITY_LED_PIN = ~LORA_ACTIVITY_LED_PIN;
|
||||
// LoraData = 0;
|
||||
// }
|
||||
// HEARTBEAT_LED_2_PIN = ~HEARTBEAT_LED_2_PIN;
|
||||
}
|
||||
if(U2STAbits.OERR) //Buffer overrun error. Data is lost.
|
||||
{
|
||||
U2STAbits.OERR = 0;
|
||||
printf("Overrun\n");
|
||||
}
|
||||
// UartReceiveData(UART_2,&acIntUartRxBuff[INTERNAL_UART_PORT_2][0], i);
|
||||
// CUProtocolRxData(&acIntUartRxBuff[INTERNAL_UART_PORT_2][0], i);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void __ISR(_UART_1_VECTOR, ipl7) InternalUart1AInterrupt(void)
|
||||
{
|
||||
stInternalUartData *p_acUartDataPtr = &astInternalUartData[INTERNAL_UART_PORT_1];
|
||||
|
||||
if(IFS0bits.U1TXIF && IEC0bits.U1TXIE)
|
||||
{
|
||||
IFS0bits.U1TXIF = 0;
|
||||
|
||||
//Check if there is still data to send in FIFO
|
||||
if(p_acUartDataPtr->iNbFIFOPendingBytes == 0)
|
||||
{
|
||||
U1STAbits.UTXEN = 0; //all data sent, stop transmitter
|
||||
p_acUartDataPtr->iIsBusy = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
U1TXREG = *p_acUartDataPtr->pcTxDataPtr++; //send data
|
||||
p_acUartDataPtr->iNbFIFOPendingBytes--;
|
||||
|
||||
}
|
||||
while((U1STAbits.UTXBF == 0) && //while there is space in buffer
|
||||
(p_acUartDataPtr->iNbFIFOPendingBytes != 0)); //and data to send
|
||||
|
||||
// HCAM
|
||||
// if(p_acUartDataPtr->iNbFIFOPendingBytes == 0)
|
||||
// {
|
||||
// // U1STAbits.UTXEN = 0; //all data sent, stop transmitter
|
||||
// p_acUartDataPtr->iIsBusy = 0;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if(IFS0bits.U1RXIF && IEC0bits.U1RXIE)
|
||||
{
|
||||
char NewByte;
|
||||
int i;
|
||||
|
||||
IFS0bits.U1RXIF = 0;
|
||||
|
||||
if(U1STAbits.OERR) //Buffer overrun error. Data is lost.
|
||||
{
|
||||
U1STAbits.OERR = 0;
|
||||
IFS0bits.U1RXIF = 0;
|
||||
printf("UART1 OERR\n");
|
||||
return;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while(U1STAbits.URXDA)
|
||||
{
|
||||
NewByte = U1RXREG;
|
||||
acIntUartRxBuff[INTERNAL_UART_PORT_1][i++] = NewByte;
|
||||
}
|
||||
|
||||
UartReceiveData(p_acUartDataPtr->iUartHandle,&acIntUartRxBuff[INTERNAL_UART_PORT_1][0], i);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void __ISR(_UART_2_VECTOR, ipl7) InternalUart2Interrupt(void)
|
||||
{
|
||||
stInternalUartData *p_acUartDataPtr = &astInternalUartData[INTERNAL_UART_PORT_2];
|
||||
if(IFS1bits.U2TXIF && IEC1bits.U2TXIE)
|
||||
{
|
||||
IFS1bits.U2TXIF = 0;
|
||||
//Check if there is still data to send in FIFO
|
||||
if(p_acUartDataPtr->iNbFIFOPendingBytes == 0)
|
||||
{
|
||||
U2STAbits.UTXEN = 0; //all data sent, stop transmitter
|
||||
p_acUartDataPtr->iIsBusy = 0;
|
||||
//LORA_MODULE_TX_LED_PIN = LED_OFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
U2TXREG = *p_acUartDataPtr->pcTxDataPtr++; //send data
|
||||
p_acUartDataPtr->iNbFIFOPendingBytes--;
|
||||
LORA_MODULE_TX_LED_PIN = ~ LORA_MODULE_TX_LED_PIN;
|
||||
}
|
||||
while((U2STAbits.UTXBF == 0) && //while there is space in buffer
|
||||
(p_acUartDataPtr->iNbFIFOPendingBytes != 0)); //and data to send
|
||||
}
|
||||
|
||||
}
|
||||
if(IFS1bits.U2RXIF && IEC1bits.U2RXIE)
|
||||
{
|
||||
IFS1bits.U2RXIF = 0;
|
||||
char NewByte;
|
||||
int i;
|
||||
|
||||
if(U2STAbits.OERR) //Buffer overrun error. Data is lost.
|
||||
{
|
||||
U2STAbits.OERR = 0;
|
||||
IFS1bits.U2RXIF = 0;
|
||||
printf("UART2 OERR\n");
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while(U2STAbits.URXDA)
|
||||
{
|
||||
NewByte = U2RXREG;
|
||||
acIntUartRxBuff[INTERNAL_UART_PORT_2][i++] = NewByte;
|
||||
LORA_MODULE_RX_LED_PIN = ~LORA_MODULE_RX_LED_PIN;
|
||||
}
|
||||
UartReceiveData(p_acUartDataPtr->iUartHandle,&acIntUartRxBuff[INTERNAL_UART_PORT_2][0], i);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Resets UART1 without closing it. Used when comm crashes.
|
||||
void ResetUart1(void)
|
||||
{
|
||||
U1MODEbits.ON = 0; //disable module
|
||||
|
||||
U1STAbits.UTXEN = 0; //disable transmitter
|
||||
|
||||
IEC0bits.U1TXIE = 0; //disable tx interrupt
|
||||
IFS0bits.U1TXIF = 0; //clear interrupt flag
|
||||
IEC0bits.U1TXIE = 1; //enable tx interrupt
|
||||
IEC0bits.U1RXIE = 0; //disable rx interrupts
|
||||
IEC0bits.U1RXIE = 0; //disable rx interrupts
|
||||
IFS0bits.U1RXIF = 0;
|
||||
#ifdef POLL_UART1_RX
|
||||
IEC0bits.U1RXIE = 0; //disable rx interrupts
|
||||
#else
|
||||
IEC0bits.U1RXIE = 1; //enable rx interrupts
|
||||
#endif
|
||||
U1STAbits.URXEN = 1; //enable receiver
|
||||
|
||||
astInternalUartData[INTERNAL_UART_PORT_1].pcTxDataPtr = &astInternalUartData[INTERNAL_UART_PORT_1].acIntUartTxFIFO[0];
|
||||
astInternalUartData[INTERNAL_UART_PORT_1].iTxDataSize = 0;
|
||||
astInternalUartData[INTERNAL_UART_PORT_1].iIsBusy = 0;
|
||||
|
||||
U1MODEbits.ON = 1; //enable module
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void ResetUart2(void)
|
||||
{
|
||||
//Setup port 2
|
||||
//
|
||||
U2MODEbits.ON = 0; //disable module
|
||||
|
||||
U2STAbits.UTXEN = 0; //disable transmitter
|
||||
|
||||
IEC1bits.U2TXIE = 0; //disable tx interrupt
|
||||
IFS1bits.U2TXIF = 0; //clear interrupt flag
|
||||
IEC1bits.U2TXIE = 0; //enable tx interrupt
|
||||
IEC1bits.U2RXIE = 0; //disable rx interrupts
|
||||
IFS1bits.U2RXIF = 1;
|
||||
#ifdef POLL_UART2_RX
|
||||
IEC1bits.U2RXIE = 0; //disable rx interrupts
|
||||
#else
|
||||
IEC1bits.U2RXIE = 1; //enable rx interrupts
|
||||
#endif
|
||||
U2STAbits.URXEN = 1; //enable receiver
|
||||
|
||||
|
||||
astInternalUartData[INTERNAL_UART_PORT_2].pcTxDataPtr = &astInternalUartData[INTERNAL_UART_PORT_2].acIntUartTxFIFO[0];
|
||||
astInternalUartData[INTERNAL_UART_PORT_2].iTxDataSize = 0;
|
||||
astInternalUartData[INTERNAL_UART_PORT_2].iIsBusy = 0;
|
||||
|
||||
U2MODEbits.ON = 1; //disable module
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void process(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//EOF
|
||||
|
||||
98
ChaloupeLora.X/Source/InternalUart.h
Normal file
98
ChaloupeLora.X/Source/InternalUart.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ¤Revision:
|
||||
000 20100616 JFM,
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
#ifndef INTERNAL_UART_H
|
||||
#define INTERNAL_UART_H
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
#define INTERNAL_UART_BUFFER_DEPTH 1//4//16 //JFM 2012-08-27
|
||||
#define USE_TX_INTERNAL_BUFFER
|
||||
|
||||
#define INTERNAL_UART1_TX_PIN_DIR TRISFbits.TRISF3
|
||||
#define INTERNAL_UART1_TX_PIN LATFbits.LATF3
|
||||
|
||||
#define INTERNAL_UART2_TX_PIN_DIR TRISFbits.TRISF5
|
||||
#define INTERNAL_UART2_TX_PIN LATFbits.LATF5
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
typedef enum
|
||||
{
|
||||
INTERNAL_UART_PORT_1,
|
||||
INTERNAL_UART_PORT_2,
|
||||
MAX_INTERNAL_UART_PORT
|
||||
}eInternalUartPorts;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
INT_UART_NO_PARITY,
|
||||
INT_UART_EVEN_PARITY,
|
||||
INT_UART_ODD_PARITY
|
||||
}eIntUartParity;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
INT_UART_ONE_STOP_BIT,
|
||||
INT_UART_TWO_STOP_BITS
|
||||
}eIntUartStopBits;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
INT_UART_INTERRUPT_OFF,
|
||||
INT_UART_INTERRUPT_ON
|
||||
}eIntUartInterruptOnOff;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *pcTxDataPtr;
|
||||
char acIntUartTxFIFO[INTERNAL_UART_BUFFER_DEPTH];
|
||||
int iNbFIFOPendingBytes;
|
||||
int iTxDataSize;
|
||||
int iTxDataCounter;
|
||||
int iIsBusy;
|
||||
int iIsOpened;
|
||||
int iUartHandle;
|
||||
|
||||
}stInternalUartData;
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
void InternalUartInit(void);
|
||||
int OpenInternalPort(int p_iUartPort,int p_iUartHandle,char *p_pcHeadPtr, char *p_pcTailPtr, int p_iBaudRate, int p_iNbStopBits, int p_iParityEnable);
|
||||
int SendInternalUartData(char *p_pcDataBuf, int p_iDataSize, int p_iUartPort, char *p_pcSourceBufferHead, char *p_pcSourceBufferTail);
|
||||
int SetIntalUartInterrupts(int p_iUartPort, int p_iRxInterrupt,int p_iTxInterrupt);
|
||||
int SendInternalUartDataBlocking(char *p_pcDataBuf, int p_iDataSize, int p_iUartPort);
|
||||
void TickInternalUart(void);
|
||||
void ResetUart1(void);
|
||||
void ResetUart2(void);
|
||||
|
||||
#endif
|
||||
//EOF
|
||||
|
||||
123
ChaloupeLora.X/Source/KnobEncoderCtrl.c
Normal file
123
ChaloupeLora.X/Source/KnobEncoderCtrl.c
Normal file
@ -0,0 +1,123 @@
|
||||
//#include <proc/p32mx440f256h.h>
|
||||
|
||||
#include "KnobEncoderCtrl.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "LedLightCtrl.h"
|
||||
#include "timer.h"
|
||||
|
||||
bool KnobDebounce;
|
||||
int KnobReadSM = KEC_WAIT_FOR_TRIGGER_STATE;
|
||||
#define PIN_ACTIVE 0
|
||||
#define PIN_INACTIVE 1
|
||||
|
||||
//bool KnobDebounce;
|
||||
//void __ISR(_EXTERNAL_1_VECTOR , ipl2) KnobEncoderInterrupt(void)
|
||||
//{
|
||||
// if(KnobDebounce == false)
|
||||
// {
|
||||
// int dir = KNOB_PH_B_PIN;
|
||||
//
|
||||
// KnobDebounce = true;
|
||||
// TimerStart(KNOB_DEBOUNCE_TIMER,KNOB_DEBOUNCE_TIMEOUT);
|
||||
// IEC0bits.INT1IE = 0;
|
||||
//
|
||||
// if(dir == 1)
|
||||
// {
|
||||
// LedLightIncrease();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// LedLightDecrease();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// IFS0bits.INT1IF = 0;
|
||||
//}
|
||||
|
||||
void KnobDebounceCtrlSM()
|
||||
{
|
||||
switch(KnobReadSM)
|
||||
{
|
||||
case KEC_CHECK_BTN_STATE:
|
||||
{
|
||||
if(KNOB_TGLE_BTN_PIN == PIN_ACTIVE)
|
||||
{
|
||||
LedLightONOFFBtnPressed();
|
||||
KnobReadSM = KEC_DEBOUNCE_BTN_STATE;
|
||||
TimerStart(KNOB_DEBOUNCE_TIMER,250);
|
||||
}
|
||||
else
|
||||
{
|
||||
KnobReadSM = KEC_WAIT_FOR_TRIGGER_STATE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEC_DEBOUNCE_BTN_STATE:
|
||||
{
|
||||
if(IsTimerExpired(KNOB_DEBOUNCE_TIMER))
|
||||
{
|
||||
KnobReadSM = KEC_WAIT_FOR_BTN_RST_STATE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case KEC_WAIT_FOR_BTN_RST_STATE:
|
||||
{
|
||||
if(KNOB_TGLE_BTN_PIN == PIN_INACTIVE)
|
||||
{
|
||||
KnobReadSM = KEC_WAIT_FOR_TRIGGER_STATE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEC_WAIT_FOR_TRIGGER_STATE:
|
||||
{
|
||||
if(KNOB_PH_A_PIN == PIN_ACTIVE)
|
||||
{
|
||||
if(KNOB_PH_B_PIN == PIN_ACTIVE)
|
||||
{
|
||||
LedLightIncrease();
|
||||
}
|
||||
else
|
||||
{
|
||||
LedLightDecrease();
|
||||
}
|
||||
TimerStart(KNOB_DEBOUNCE_TIMER,KNOB_DEBOUNCE_TIMEOUT);
|
||||
KnobReadSM = KEC_DEBOUNCE_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
KnobReadSM = KEC_CHECK_BTN_STATE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEC_DEBOUNCE_STATE:
|
||||
{
|
||||
if(IsTimerExpired(KNOB_DEBOUNCE_TIMER))
|
||||
{
|
||||
KnobReadSM = KEC_WAIT_FOR_RESET_STATE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEC_WAIT_FOR_RESET_STATE:
|
||||
{
|
||||
if((KNOB_PH_A_PIN == PIN_INACTIVE))
|
||||
{
|
||||
if(KNOB_PH_B_PIN == PIN_INACTIVE)
|
||||
{
|
||||
TimerStart(KNOB_DEBOUNCE_TIMER,KNOB_DEBOUNCE_TIMEOUT);
|
||||
KnobReadSM = KEC_WAIT_A_LITTLE_MORE_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case KEC_WAIT_A_LITTLE_MORE_STATE:
|
||||
{
|
||||
if(IsTimerExpired(KNOB_DEBOUNCE_TIMER))
|
||||
{
|
||||
KnobReadSM = KEC_CHECK_BTN_STATE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
ChaloupeLora.X/Source/KnobEncoderCtrl.h
Normal file
31
ChaloupeLora.X/Source/KnobEncoderCtrl.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* File: KnobEncoderCtrl.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 30, 2018, 7:33 PM
|
||||
*/
|
||||
|
||||
#ifndef KNOBENCODERCTRL_H
|
||||
#define KNOBENCODERCTRL_H
|
||||
#include "define.h"
|
||||
|
||||
#define KNOB_DEBOUNCE_TIMEOUT 5 //ms
|
||||
|
||||
|
||||
void KnobDebounceCtrlSM();
|
||||
|
||||
enum KnobEncoderCtrlSMStates
|
||||
{
|
||||
KEC_CHECK_BTN_STATE,
|
||||
KEC_DEBOUNCE_BTN_STATE,
|
||||
KEC_WAIT_FOR_BTN_RST_STATE,
|
||||
KEC_WAIT_FOR_TRIGGER_STATE,
|
||||
KEC_DEBOUNCE_STATE,
|
||||
KEC_WAIT_FOR_RESET_STATE,
|
||||
KEC_WAIT_A_LITTLE_MORE_STATE
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* KNOBENCODERCTRL_H */
|
||||
|
||||
96
ChaloupeLora.X/Source/LedLightCtrl.c
Normal file
96
ChaloupeLora.X/Source/LedLightCtrl.c
Normal file
@ -0,0 +1,96 @@
|
||||
#include "define.h"
|
||||
#include "LedLightCtrl.h"
|
||||
#include "PWMCtrl.h"
|
||||
|
||||
int LedLightBrightness = 10;
|
||||
int LedLightState = LED_LIGHT_ON;
|
||||
|
||||
|
||||
|
||||
void LedLightDecrease()
|
||||
{
|
||||
if(LedLightState == LED_LIGHT_OFF)
|
||||
return;
|
||||
|
||||
LedLightDim(LED_LIGHT_TICK_STEP);
|
||||
}
|
||||
void LedLightDim(int Percent)
|
||||
{
|
||||
if(LedLightState == LED_LIGHT_OFF)
|
||||
return;
|
||||
|
||||
LedLightBrightness -= Percent;
|
||||
if(LedLightBrightness < LED_LIGHT_MIN_DIM_VAL)
|
||||
{
|
||||
LedLightBrightness = LED_LIGHT_MIN_DIM_VAL;
|
||||
}
|
||||
|
||||
PWMSetValue(LedLightBrightness);
|
||||
}
|
||||
|
||||
void LedLightBright(int Percent)
|
||||
{
|
||||
if(LedLightState == LED_LIGHT_OFF)
|
||||
return;
|
||||
|
||||
LedLightBrightness += Percent;
|
||||
if(LedLightBrightness >= 100)
|
||||
{
|
||||
LedLightBrightness = 100;
|
||||
}
|
||||
|
||||
PWMSetValue(LedLightBrightness);
|
||||
}
|
||||
|
||||
void LedLightIncrease()
|
||||
{
|
||||
if(LedLightState == LED_LIGHT_OFF)
|
||||
return;
|
||||
|
||||
LedLightBright(LED_LIGHT_TICK_STEP);
|
||||
}
|
||||
|
||||
void LedLightSet(int Percent)
|
||||
{
|
||||
if(Percent < 0)
|
||||
Percent = 0;
|
||||
if(Percent > 100)
|
||||
Percent = 100;
|
||||
|
||||
LedLightBrightness = Percent;
|
||||
PWMSetValue(LedLightBrightness);
|
||||
}
|
||||
|
||||
void TurnLedLightON()
|
||||
{
|
||||
LedLightState = LED_LIGHT_ON;
|
||||
PWMSetValue(LedLightBrightness);
|
||||
}
|
||||
|
||||
void TurnLedLightOFF()
|
||||
{
|
||||
LedLightState = LED_LIGHT_OFF;
|
||||
PWMSetValue(0);
|
||||
}
|
||||
|
||||
void LedLightONOFFBtnPressed()
|
||||
{
|
||||
if(LedLightState == LED_LIGHT_ON)
|
||||
{
|
||||
TurnLedLightOFF();
|
||||
}
|
||||
else
|
||||
{
|
||||
TurnLedLightON();
|
||||
}
|
||||
}
|
||||
|
||||
int GetLedLightBrightness()
|
||||
{
|
||||
return LedLightBrightness;
|
||||
}
|
||||
|
||||
int GetLedLightState()
|
||||
{
|
||||
return LedLightState;
|
||||
}
|
||||
33
ChaloupeLora.X/Source/LedLightCtrl.h
Normal file
33
ChaloupeLora.X/Source/LedLightCtrl.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* File: LedLightCtrl.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 30, 2018, 8:09 PM
|
||||
*/
|
||||
|
||||
#ifndef LEDLIGHTCTRL_H
|
||||
#define LEDLIGHTCTRL_H
|
||||
|
||||
#define LED_LIGHT_TICK_STEP 5 //Percent
|
||||
#define LED_LIGHT_MIN_DIM_VAL 10 //Percent
|
||||
|
||||
#define LED_LIGHT_ON 1
|
||||
#define LED_LIGHT_OFF 0
|
||||
|
||||
extern int LedLightBrightness;
|
||||
|
||||
void LedLightDim(int Percent);
|
||||
void LedLightDecrease();
|
||||
void LedLightBright(int Percent);
|
||||
void LedLightIncrease();
|
||||
void LedLightSet(int Percent);
|
||||
|
||||
void LedLightONOFFBtnPressed();
|
||||
void TurnLedLightON();
|
||||
void TurnLedLightOFF();
|
||||
|
||||
int GetLedLightBrightness();
|
||||
int GetLedLightState();
|
||||
|
||||
#endif /* LEDLIGHTCTRL_H */
|
||||
|
||||
284
ChaloupeLora.X/Source/LoraNetworkInterface.c
Normal file
284
ChaloupeLora.X/Source/LoraNetworkInterface.c
Normal file
@ -0,0 +1,284 @@
|
||||
#include "LoraNetworkInterface.h"
|
||||
#include "ProtocolDefs.h"
|
||||
#include "NetworkProtocol.h"
|
||||
#include "InternalUart.h"
|
||||
#include "define.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "Uart.h"
|
||||
#include "ChaletPowerRelay.h"
|
||||
#include "HarakiriRelay.h"
|
||||
#include "BatteryMonitor.h"
|
||||
#include "LedLightCtrl.h"
|
||||
#include "TemperatureSensor.h"
|
||||
#include "SPI_Flash.h"
|
||||
#include "FlashMapping.h"
|
||||
#include "LoraWatchdog.h"
|
||||
#include "versionbuild.h"
|
||||
//#include "WiFiCtrl.h"
|
||||
//
|
||||
|
||||
//enum eWiFiState
|
||||
//{
|
||||
// WIFI_MODULE_OFF_STATE = 0,
|
||||
// WIFI_CONNECTED_STATE,
|
||||
// WIFI_DISCONNECTED_STATE,
|
||||
// WIFI_INIT_ERROR_STATE,
|
||||
// WIFI_UNKNOWN_STATE
|
||||
//};
|
||||
unsigned char mLoraPreamble[3]={0x00,LORA_MASTER_ADDRESS,LORA_CHANNEL};
|
||||
|
||||
static const char mFirmwareVersion[15] = VERSIONNUMBER;
|
||||
unsigned int mTotalMasterNbRequests = 0;
|
||||
|
||||
void ExecuteMasterCommand(int Command, unsigned char *Data)
|
||||
{
|
||||
//Whatever was the command, we are online...
|
||||
LORA_MODULE_RX_LED_PIN = LED_OFF;
|
||||
KickLoraWatchdog();
|
||||
// printf("EXEC\n\n");
|
||||
ChaletPowerRelayKickTimer();
|
||||
mTotalMasterNbRequests++;
|
||||
switch(Command)
|
||||
{
|
||||
case CHALET_INTERFACE_ACK:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case CHALET_GENERAL_STATUS_REQUEST:
|
||||
{
|
||||
float FloatVoltage = GetBatteryVoltage();
|
||||
float FloatTemperature = TempSensorGetTemp();
|
||||
unsigned int BattVoltage = *((int*)&FloatVoltage);
|
||||
unsigned int Temperature = *((int*)&FloatTemperature);
|
||||
int SolarPanelCurrent = GetSolarPanelCurrent();
|
||||
int SOC = GetBatterySOC();
|
||||
|
||||
char GeneralStatus = 0;
|
||||
char ChaletStatus[18];
|
||||
|
||||
if(GetChaletPowerRelayState() == CHALET_POWER_RELAY_ON_STATE)
|
||||
{
|
||||
GeneralStatus |= LORA_CHALET_STATUS_POWER_RELAY_MASK;
|
||||
}
|
||||
if(GetCurrentModuleOK() == true)
|
||||
{
|
||||
GeneralStatus |= LORA_CHALET_STATUS_CUR_SENSOR_MASK;
|
||||
}
|
||||
|
||||
ChaletStatus[0] = GeneralStatus; //General Status
|
||||
ChaletStatus[1] = GetWiFiSate(); //Wifi Module state
|
||||
|
||||
ChaletStatus[2] = (char)(BattVoltage & 0x000000FF); //Battery Voltage 1
|
||||
BattVoltage >>= 8;
|
||||
ChaletStatus[3] = (char)(BattVoltage & 0x000000FF); //Battery Voltage 2
|
||||
BattVoltage >>= 8;
|
||||
ChaletStatus[4] = (char)(BattVoltage & 0x000000FF); //Battery Voltage 3
|
||||
BattVoltage >>= 8;
|
||||
ChaletStatus[5] = (char)(BattVoltage & 0x000000FF); //Battery Voltage 4
|
||||
|
||||
ChaletStatus[6] = (char)(SolarPanelCurrent & 0x000000FF); //Solar panel Current 1
|
||||
SolarPanelCurrent >>= 8;
|
||||
ChaletStatus[7] = (char)(SolarPanelCurrent & 0x000000FF); //Solar panel Current 2
|
||||
|
||||
ChaletStatus[8] = (char)(SOC & 0x000000FF); //Battery SOC 1
|
||||
SolarPanelCurrent >>= 8;
|
||||
ChaletStatus[9] = (char)(SolarPanelCurrent & 0x000000FF); //Battery SOC 2
|
||||
|
||||
ChaletStatus[10] = (char)(Temperature & 0x000000FF); //Temperature 1
|
||||
Temperature >>= 8;
|
||||
ChaletStatus[11] = (char)(Temperature & 0x000000FF); //Temperature 2
|
||||
Temperature >>= 8;
|
||||
ChaletStatus[12] = (char)(Temperature & 0x000000FF); //BTemperature 3
|
||||
Temperature >>= 8;
|
||||
ChaletStatus[13] = (char)(Temperature & 0x000000FF); //Temperature 4
|
||||
|
||||
int tmp = mTotalMasterNbRequests;
|
||||
ChaletStatus[14] = (char)(mTotalMasterNbRequests & 0x000000FF); //Total Nb Requests 1
|
||||
mTotalMasterNbRequests >>= 8;
|
||||
ChaletStatus[15] = (char)(mTotalMasterNbRequests & 0x000000FF); //Total Nb Requests 2
|
||||
mTotalMasterNbRequests >>= 8;
|
||||
ChaletStatus[16] = (char)(mTotalMasterNbRequests & 0x000000FF); //Total Nb Requests 3
|
||||
mTotalMasterNbRequests >>= 8;
|
||||
ChaletStatus[17] = (char)(mTotalMasterNbRequests & 0x000000FF); //Total Nb Requests 4
|
||||
mTotalMasterNbRequests = tmp;
|
||||
|
||||
|
||||
SendLoraNetworkCommand(CHALET_GENERAL_STATUS_RESPONSE,ChaletStatus,18);
|
||||
|
||||
HEARTBEAT_LED_1_PIN = ~HEARTBEAT_LED_1_PIN;
|
||||
|
||||
break;
|
||||
}
|
||||
case CHALET_AC_POWER_STATE_STATUS_REQUEST:
|
||||
{
|
||||
char PowerStatus = GetChaletPowerRelayState();
|
||||
SendLoraNetworkCommand(CHALET_AC_POWER_STATE_STATUS_RESPONSE,&PowerStatus,1);
|
||||
break;
|
||||
}
|
||||
case CHALET_AC_POWER_SET_STATE_REQUEST:
|
||||
{
|
||||
char response = CHALET_POWER_RELAY_UNKNOWN_STATE;
|
||||
if(Data[0] == CHALET_POWER_RELAY_OFF_STATE)
|
||||
{
|
||||
ChaletPowerRelayTurnOff();
|
||||
response = CHALET_POWER_RELAY_OFF_STATE;
|
||||
}
|
||||
else if(Data[0] == CHALET_POWER_RELAY_ON_STATE)
|
||||
{
|
||||
ChaletPowerRelayTurnOn();
|
||||
response = CHALET_POWER_RELAY_ON_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
//invalid state requested.... don't do anything
|
||||
response = CHALET_POWER_RELAY_UNKNOWN_STATE;
|
||||
}
|
||||
|
||||
SendLoraNetworkCommand(CHALET_AC_POWER_SET_STATE_RESPONSE,&response,1);
|
||||
|
||||
break;
|
||||
}
|
||||
case CHALET_BATTERY_VOLTAGE_REQUEST:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case CHALET_WIFI_STATUS_REQUEST:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case CHALET_WIFI_SET_STATE_REQUEST:
|
||||
{
|
||||
char response = WIFI_UNKNOWN_STATE;
|
||||
if(Data[0] == 0)
|
||||
{
|
||||
TurnOFFWiFi();
|
||||
response = 0;
|
||||
}
|
||||
else if(Data[0] == 1)
|
||||
{
|
||||
if(GetWiFiSate() != WIFI_CONNECTED_STATE)
|
||||
{
|
||||
InitWiFi();
|
||||
response = GetWiFiSate();
|
||||
}
|
||||
else
|
||||
{
|
||||
response = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//invalid state requested.... don't do anything
|
||||
response = WIFI_UNKNOWN_STATE;
|
||||
}
|
||||
|
||||
SendLoraNetworkCommand(CHALET_WIFI_SET_STATE_RESPONSE,&response,1);
|
||||
break;
|
||||
}
|
||||
case CHALET_DO_HARAKIRI_REQUEST:
|
||||
{
|
||||
char response;
|
||||
if(Data[0] == 0xBA &&
|
||||
Data[1] == 0xAD &&
|
||||
Data[2] == 0xBE &&
|
||||
Data[3] == 0xEF)
|
||||
{
|
||||
//Magic word is OK... let's suicide...
|
||||
response = 0x01;
|
||||
//First, send an ACK to master (this is blocking so it's OK)
|
||||
SendLoraNetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&response,1);
|
||||
HarakiriRelayTurnOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
response = 0x00;
|
||||
SendLoraNetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&response,1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHALET_REBOOT_CPU_REQUEST:
|
||||
{
|
||||
char response;
|
||||
if(Data[0] == 0xBA &&
|
||||
Data[1] == 0xAD &&
|
||||
Data[2] == 0xCA &&
|
||||
Data[3] == 0xFE)
|
||||
{
|
||||
//Magic word is OK... let's reboot...
|
||||
response = 0x01;
|
||||
//First, send an ACK to master (this is blocking so it's OK)
|
||||
SendLoraNetworkCommandBlocking(CHALET_REBOOT_CPU_RESPONSE,&response,1);
|
||||
Sleep(100);
|
||||
TurnOFFWiFi();
|
||||
Sleep(100);
|
||||
SoftReset();
|
||||
}
|
||||
else
|
||||
{
|
||||
response = 0x00;
|
||||
SendLoraNetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&response,1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHALET_GET_STORED_WIFI_SETTINGS_REQUEST:
|
||||
{
|
||||
char response[8];
|
||||
SPIFlashReadBuffer(response,8,FLASH_WIFI_IP_ADDRESS);
|
||||
SendLoraNetworkCommand(CHALET_GET_STORED_WIFI_SETTINGS_RESPONSE,response,8);
|
||||
break;
|
||||
}
|
||||
case CHALET_SET_STORED_WIFI_SETTINGS_REQUEST:
|
||||
{
|
||||
char response = 0;
|
||||
if(SPIFlashWriteBuffer(Data,8,FLASH_WIFI_IP_ADDRESS) == 1)
|
||||
{
|
||||
response = 1;
|
||||
}
|
||||
|
||||
SendLoraNetworkCommand(CHALET_SET_STORED_WIFI_SETTINGS_RESPONSE,&response,1);
|
||||
break;
|
||||
}
|
||||
case CHALET_GET_FIRMWARE_VERSION_REQUEST:
|
||||
{
|
||||
SendLoraNetworkCommand(CHALET_GET_FIRMWARE_VERSION_RESPONSE,(unsigned char*)mFirmwareVersion,15);
|
||||
break;
|
||||
}
|
||||
case CHALET_CLEAR_COMMS_STATISTICS_REQUEST:
|
||||
{
|
||||
char response = 1;
|
||||
mTotalMasterNbRequests = 0;
|
||||
SendLoraNetworkCommand(CHALET_CLEAR_COMMS_STATISTICS_RESPONSE,&response,1);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SendLoraNetworkCommand(int Command, unsigned char *Data, unsigned int DataSize)
|
||||
{
|
||||
unsigned char *Payload;
|
||||
unsigned int PayloadSize;
|
||||
//unsigned char DestDevice,unsigned char DestAddress, unsigned char SenderDevice, unsigned char Cmd, unsigned char *Data,unsigned int Size,unsigned char Flags, int *FrameSize)
|
||||
Payload = ProtocolGetFrame(ID_MASTER,MASTER_ADDRESS,ID_CHALET_DEVICE,Command,Data,DataSize,0,&PayloadSize);
|
||||
|
||||
UartTransmitData(NETWORK_UART_PORT,mLoraPreamble,3);
|
||||
UartTransmitData(NETWORK_UART_PORT,Payload,PayloadSize);
|
||||
|
||||
}
|
||||
|
||||
void SendLoraNetworkCommandBlocking(int Command, unsigned char *Data, unsigned int DataSize)
|
||||
{
|
||||
unsigned char *Payload;
|
||||
unsigned int PayloadSize;
|
||||
//unsigned char DestDevice,unsigned char DestAddress, unsigned char SenderDevice, unsigned char Cmd, unsigned char *Data,unsigned int Size,unsigned char Flags, int *FrameSize)
|
||||
Payload = ProtocolGetFrame(ID_MASTER,MASTER_ADDRESS,ID_CHALET_DEVICE,Command,Data,DataSize,0,&PayloadSize);
|
||||
|
||||
SendInternalUartDataBlocking(mLoraPreamble,3,NETWORK_UART_PORT);
|
||||
SendInternalUartDataBlocking(Payload,PayloadSize,NETWORK_UART_PORT);
|
||||
}
|
||||
|
||||
void TestTx()
|
||||
{
|
||||
char toto = 0x03;
|
||||
SendInternalUartDataBlocking(mLoraPreamble,3,NETWORK_UART_PORT);
|
||||
}
|
||||
17
ChaloupeLora.X/Source/LoraNetworkInterface.h
Normal file
17
ChaloupeLora.X/Source/LoraNetworkInterface.h
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
#ifndef LORANEETWORKINTERFACE_H /* Guard against multiple inclusion */
|
||||
#define LORANEETWORKINTERFACE_H
|
||||
#define LORA_CHANNEL 0x04
|
||||
#define LORA_MASTER_ADDRESS 0x05
|
||||
|
||||
#define LORA_CHALET_STATUS_POWER_RELAY_MASK 0x01
|
||||
#define LORA_CHALET_STATUS_CUR_SENSOR_MASK 0x02
|
||||
|
||||
void ExecuteMasterCommand(int Command, unsigned char *Data);
|
||||
void SendLoraNetworkCommand(int Command, unsigned char *Data, unsigned int DataSize);
|
||||
void SendLoraNetworkCommandBlocking(int Command, unsigned char *Data, unsigned int DataSize); //USE WITH CARE
|
||||
|
||||
void TestTx();
|
||||
|
||||
#endif /* LORANEETWORKINTERFACE_H */
|
||||
101
ChaloupeLora.X/Source/LoraWatchdog.c
Normal file
101
ChaloupeLora.X/Source/LoraWatchdog.c
Normal file
@ -0,0 +1,101 @@
|
||||
//#include <proc/p32mx440f256h.h>
|
||||
|
||||
#include "HarakiriRelay.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "timer.h"
|
||||
#include "LoraWatchdog.h"
|
||||
|
||||
int mLoraSMState;
|
||||
|
||||
|
||||
|
||||
void InitLoraWatchdog()
|
||||
{
|
||||
mLoraSMState = LORA_WATCHDOG_OK_STATE;
|
||||
TimerStart(LORA_WATCHDOG_TIMER,LORA_WATCHDOG_MODULE_RESET_TIMEOUT);
|
||||
}
|
||||
|
||||
void TickLoraWatchdog()
|
||||
{
|
||||
LoraWatchdogStateMachine(LORA_SM_TICK_EVENT);
|
||||
}
|
||||
|
||||
void LoraWatchdogStateMachine(int Event)
|
||||
{
|
||||
switch(mLoraSMState)
|
||||
{
|
||||
case LORA_WATCHDOG_OK_STATE:
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case LORA_SM_TICK_EVENT:
|
||||
{
|
||||
if(IsTimerExpired(LORA_WATCHDOG_TIMER))
|
||||
{
|
||||
//We lost the comm... reset the LoRa module
|
||||
LORA_MODULE_RELAY_PIN = 1; //Turn OFF the LoRa module
|
||||
TimerStart(LORA_WATCHDOG_TIMER,LORA_WATCHDOG_MODULE_OFF_TIMEOUT);
|
||||
mLoraSMState = LORA_WATCHDOG_RESET_LORA_MODULE_STATE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LORA_SM_KICK_EVENT:
|
||||
{
|
||||
//All is well...
|
||||
TimerStart(LORA_WATCHDOG_TIMER,LORA_WATCHDOG_MODULE_RESET_TIMEOUT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LORA_WATCHDOG_RESET_LORA_MODULE_STATE:
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case LORA_SM_TICK_EVENT:
|
||||
case LORA_SM_KICK_EVENT://That would be very weird since the LoRa module is OFF!!!
|
||||
{
|
||||
if(IsTimerExpired(LORA_WATCHDOG_TIMER))
|
||||
{
|
||||
//Reset is done, turn module back ON.
|
||||
LORA_MODULE_RELAY_PIN = 0; //Turn ON the LoRa module
|
||||
TimerStart(LORA_WATCHDOG_TIMER,LORA_WATCHDOG_REBOOT_TIMEOUT); //If we don't get Comm. back after this delay... reboot the PIC
|
||||
mLoraSMState = LORA_WATCHDOG_WAIT_FOR_RECONNECT_STATE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LORA_WATCHDOG_WAIT_FOR_RECONNECT_STATE:
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case LORA_SM_TICK_EVENT:
|
||||
{
|
||||
if(IsTimerExpired(LORA_WATCHDOG_TIMER))
|
||||
{
|
||||
|
||||
TurnOFFWiFi();
|
||||
Sleep(100);
|
||||
SoftReset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LORA_SM_KICK_EVENT:
|
||||
{
|
||||
//Communication is re-established.
|
||||
TimerStart(LORA_WATCHDOG_TIMER,LORA_WATCHDOG_MODULE_RESET_TIMEOUT);
|
||||
mLoraSMState = LORA_WATCHDOG_OK_STATE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KickLoraWatchdog()
|
||||
{
|
||||
LoraWatchdogStateMachine(LORA_SM_KICK_EVENT);
|
||||
}
|
||||
38
ChaloupeLora.X/Source/LoraWatchdog.h
Normal file
38
ChaloupeLora.X/Source/LoraWatchdog.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* File: LoraWatchdog.h
|
||||
* Author: JF
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LORAWATCHDOG_H
|
||||
#define LORAWATCHDOG_H
|
||||
#include "define.h"
|
||||
|
||||
#define LORA_WATCHDOG_MODULE_RESET_TIMEOUT 3600000 //1h Time without comm. before we reset the LoRa module
|
||||
#define LORA_WATCHDOG_REBOOT_TIMEOUT 1200000 //20 minutes Time to reboot after we reset the LoRa module
|
||||
#define LORA_WATCHDOG_MODULE_OFF_TIMEOUT 4000 //Keep the LoRa module off for 2 seconds when reseting it.
|
||||
|
||||
enum eLoraWDSMStates
|
||||
{
|
||||
LORA_WATCHDOG_OK_STATE,
|
||||
LORA_WATCHDOG_RESET_LORA_MODULE_STATE,
|
||||
LORA_WATCHDOG_WAIT_FOR_RECONNECT_STATE
|
||||
};
|
||||
|
||||
enum eLoraWDEvents
|
||||
{
|
||||
LORA_SM_TICK_EVENT,
|
||||
LORA_SM_KICK_EVENT
|
||||
};
|
||||
|
||||
|
||||
void InitLoraWatchdog();
|
||||
void TickLoraWatchdog();
|
||||
void LoraWatchdogStateMachine(int Event);
|
||||
void KickLoraWatchdog();
|
||||
|
||||
|
||||
|
||||
#endif /* HARAKIRIRELAY_H */
|
||||
|
||||
282
ChaloupeLora.X/Source/MasterCtrlInterface.c
Normal file
282
ChaloupeLora.X/Source/MasterCtrlInterface.c
Normal file
@ -0,0 +1,282 @@
|
||||
|
||||
#include "define.h"
|
||||
#include "MasterCtrlInterface.h"
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
#include "TCPIP_Stack/TCPIP.h"
|
||||
#endif
|
||||
#include "NetworkProtocol.h"
|
||||
#include "ProtocolDefs.h"
|
||||
#include "timer.h"
|
||||
#include <stdio.h>
|
||||
#include "ValveCtrl.h"
|
||||
#include "FlowMeter.h"
|
||||
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
TCP_SOCKET MySocket;
|
||||
static BYTE MasterIP[] = "192.168.0.100";
|
||||
DWORD MasterPort = 2182;
|
||||
#endif
|
||||
|
||||
int mConnectionState = MASTER_STATE_DISCONNECTED;
|
||||
|
||||
|
||||
int InitMasterCtrlIF()
|
||||
{
|
||||
ProtocolInit();
|
||||
TimerStart(MASTER_CONNECTION_TIMER,MASTER_RECONNECTION_TIMEOUT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ConnectToMasterCtrl()
|
||||
{
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
MySocket = TCPOpen((DWORD) (PTR_BASE) & MasterIP[0], TCP_OPEN_RAM_HOST, MasterPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);
|
||||
|
||||
// Abort operation if no TCP socket of type TCP_PURPOSE_GENERIC_TCP_CLIENT is available
|
||||
// If this ever happens, you need to go add one to TCPIPConfig.h
|
||||
if (MySocket == INVALID_SOCKET)
|
||||
{
|
||||
printf("Could not open socket to MasterCtrl\n");
|
||||
return 0;
|
||||
}
|
||||
printf("MasterCtrl Socket opened\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void TickMasterCtrlInterface()
|
||||
{
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
WORD Pending = TCPIsGetReady(MySocket);
|
||||
if (Pending != 0)
|
||||
{
|
||||
// printf("Rx %d bytes\n",Pending);
|
||||
int i = 0;
|
||||
for(i = 0; i < Pending; i++)
|
||||
{
|
||||
BYTE Byte;
|
||||
if(TCPGet(MySocket,&Byte) == TRUE)
|
||||
{
|
||||
ProtocolAnalyzeNewData(Byte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONNECT_DEVICE_TO_NETWORK
|
||||
if(mConnectionState == MASTER_STATE_DISCONNECTED)
|
||||
{
|
||||
if(IsTimerExpired(MASTER_CONNECTION_TIMER))
|
||||
{
|
||||
TimerStart(MASTER_CONNECTION_TIMER,MASTER_RESPONSE_TIMEOUT);
|
||||
mConnectionState = MASTER_STATE_CONNECTING;
|
||||
ConnectToMasterCtrl();
|
||||
}
|
||||
}
|
||||
else if(mConnectionState == MASTER_STATE_CONNECTING)
|
||||
{
|
||||
// if(IsTimerExpired(MASTER_CONNECTION_TIMER) == true) //
|
||||
// {
|
||||
// TCPClose(MySocket);
|
||||
// TimerStart(MASTER_CONNECTION_TIMER,MASTER_RESPONSE_TIMEOUT);
|
||||
// ConnectToMasterCtrl();
|
||||
// }
|
||||
}
|
||||
else if(mConnectionState == MASTER_STATE_CONNECTED)
|
||||
{
|
||||
// if(IsTimerExpired(MASTER_CONNECTION_TIMER))
|
||||
{
|
||||
if(TCPIsConnected(MySocket) == FALSE)
|
||||
{
|
||||
//we got disconnected...
|
||||
mConnectionState = MASTER_STATE_DISCONNECTED;
|
||||
TCPClose(MySocket);
|
||||
|
||||
printf("Connection with MasterCtrl lost..\n");
|
||||
}
|
||||
TimerStart(MASTER_CONNECTION_TIMER,MASTER_RECONNECTION_TIMEOUT);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void NewMasterMessageReceived(char* Message)
|
||||
{
|
||||
// char Sender = Message[FRAME_SENDER_DEVICE_ID_INDEX];
|
||||
char Target = Message[FRAME_DEST_DEVICE_ID_INDEX];
|
||||
unsigned char Command = Message[FRAME_COMMAND_INDEX];
|
||||
char *Data = &Message[FRAME_DATA_INDEX];
|
||||
|
||||
// printf("MasterMsgReceived %d \n",Command);
|
||||
|
||||
if(Target == ID_ETHERNET_VIRTUAL)
|
||||
{
|
||||
switch(Command)
|
||||
{
|
||||
case ETH_NETWK_DEVICE_INFO_REQUEST:
|
||||
{
|
||||
char Data[2];
|
||||
Data[0] = ID_SPRINKLER_DEVICE;
|
||||
Data[1] = MY_DEVICE_ADDRESS; //Address
|
||||
SendFrame(ID_MASTER,MASTER_ADDRESS,ID_ETHERNET_VIRTUAL, ETH_NETWK_DEVICE_INFO_RESPONSE, Data,2,0);
|
||||
printf("Rx Device info request\n");
|
||||
// int FrameSize = -1;
|
||||
// unsigned char *FramePtr = ProtocolGetFrame(ID_MASTER,MASTER_ADDRESS,ID_ETHERNET_VIRTUAL, ETH_NETWK_DEVICE_INFO_RESPONSE, Data,2,0, &FrameSize);
|
||||
//
|
||||
// if(FrameSize > 0)
|
||||
// {
|
||||
// TCPPutArray(MySocket,FramePtr,FrameSize);
|
||||
// }
|
||||
|
||||
break;
|
||||
}
|
||||
case ETH_NETWK_CONNECTION_REFUSED:
|
||||
{
|
||||
printf("Connection to server refused\n");
|
||||
break;
|
||||
}
|
||||
case ETH_NETWK_SET_DEVICE_INFO_ACK:
|
||||
{
|
||||
//Connected!
|
||||
mConnectionState = MASTER_STATE_CONNECTED;
|
||||
TimerStart(MASTER_CONNECTION_TIMER,MASTER_RECONNECTION_TIMEOUT);
|
||||
printf("Connected to server\n");
|
||||
break;
|
||||
}
|
||||
case ETH_NETWK_DEVICE_INFO_RESPONSE:
|
||||
default:
|
||||
{
|
||||
//error...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(Target == ID_SPRINKLER_DEVICE)
|
||||
{
|
||||
switch(Command)
|
||||
{
|
||||
case SPRINKLER_DEVICE_ACK:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_STATUS_REQUEST:
|
||||
{
|
||||
unsigned char data[6];
|
||||
data[0] = (unsigned char)GetValveState();
|
||||
GetCurrentFlowBytes(&data[1]);
|
||||
data[3] = 0;
|
||||
data[4] = 0;
|
||||
data[5] = 0;
|
||||
SendFrame(ID_MASTER,MASTER_ADDRESS,ID_SPRINKLER_DEVICE, SPRINKLER_DEVICE_STATUS_RESPONSE, data,6,0);
|
||||
// printf("Status sent\n");
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_SET_SPRINKLER_STATE_REQUEST:
|
||||
{
|
||||
unsigned char *MsgData;
|
||||
char data;
|
||||
|
||||
MsgData = ProtocolMsgDataPtr();
|
||||
if(*MsgData == 1)
|
||||
{
|
||||
SetValve(VALVE_ON);
|
||||
data = 1;
|
||||
}
|
||||
else if(*MsgData == 1)
|
||||
{
|
||||
SetValve(VALVE_OFF);
|
||||
data = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = 0;
|
||||
}
|
||||
|
||||
SendFrame(ID_MASTER,MASTER_ADDRESS,ID_SPRINKLER_DEVICE, SPRINKLER_DEVICE_SET_SPRINKLER_STATE_ACK,&data,1,0);
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_GET_SPRINKLER_STATE_REQUEST:
|
||||
{
|
||||
unsigned char data;
|
||||
data = (unsigned char)GetValveState();
|
||||
SendFrame(ID_MASTER,MASTER_ADDRESS,ID_SPRINKLER_DEVICE, SPRINKLER_DEVICE_GET_SPRINKLER_STATE_RESPONSE,&data,1,0);
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_GET_WATER_FLOW_REQUEST:
|
||||
{
|
||||
unsigned char data[2];
|
||||
GetCurrentFlowBytes(data);
|
||||
SendFrame(ID_MASTER,MASTER_ADDRESS,ID_SPRINKLER_DEVICE, SPRINKLER_DEVICE_GET_WATER_FLOW_RESPONSE,data,2,0);
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_GET_MOISTURE_REQUEST:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_SET_PROGRAM_REQUEST:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_GET_PROGRAM_REQUEST:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_SET_PARAMETERS_REQUEST:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_GET_PARAMETERS_REQUEST:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SPRINKLER_DEVICE_STATUS_RESPONSE:
|
||||
case SPRINKLER_DEVICE_SET_SPRINKLER_STATE_ACK:
|
||||
case SPRINKLER_DEVICE_GET_SPRINKLER_STATE_RESPONSE:
|
||||
case SPRINKLER_DEVICE_GET_WATER_FLOW_RESPONSE:
|
||||
case SPRINKLER_DEVICE_GET_MOISTURE_RESPONSE:
|
||||
case SPRINKLER_DEVICE_SET_PROGRAM_ACK:
|
||||
case SPRINKLER_DEVICE_GET_PROGRAM_RESPONSE:
|
||||
case SPRINKLER_DEVICE_SET_PARAMETERS_ACK:
|
||||
case SPRINKLER_DEVICE_GET_PARAMETERS_RESPONSE:
|
||||
default:
|
||||
{
|
||||
//error
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Ignore..???
|
||||
}
|
||||
}
|
||||
|
||||
bool SendFrame(unsigned char DestDevice,unsigned char DestAddress, unsigned char SenderDevice, unsigned char Cmd, unsigned char *Data,unsigned int Size,unsigned char Flags)
|
||||
{
|
||||
|
||||
int FrameSize = -1;
|
||||
unsigned char *FramePtr = ProtocolGetFrame(DestDevice,DestAddress,SenderDevice, Cmd, Data,Size,Flags,&FrameSize);
|
||||
|
||||
if(FrameSize > 0)
|
||||
{
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
TCPPutArray(MySocket,FramePtr,FrameSize);
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
27
ChaloupeLora.X/Source/MasterCtrlInterface.h
Normal file
27
ChaloupeLora.X/Source/MasterCtrlInterface.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* File: MasterCtrlInterface.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on March 31, 2017, 2:41 PM
|
||||
*/
|
||||
|
||||
#ifndef MASTERCTRLINTERFACE_H
|
||||
#define MASTERCTRLINTERFACE_H
|
||||
|
||||
enum eMasterConnectionStates
|
||||
{
|
||||
MASTER_STATE_DISCONNECTED,
|
||||
MASTER_STATE_CONNECTING,
|
||||
MASTER_STATE_CONNECTED
|
||||
};
|
||||
|
||||
int InitMasterCtrlIF(void);
|
||||
int ConnectToMasterCtrl(void);
|
||||
void TickMasterCtrlInterface(void);
|
||||
void MasterCtrlSM(int Event);
|
||||
void NewMasterMessageReceived(char* Message);
|
||||
bool SendFrame(unsigned char DestDevice,unsigned char DestAddress, unsigned char SenderDevice, unsigned char Cmd, unsigned char *Data,unsigned int Size,unsigned char Flags);
|
||||
|
||||
|
||||
#endif /* MASTERCTRLINTERFACE_H */
|
||||
|
||||
324
ChaloupeLora.X/Source/NetworkProtocol.c
Normal file
324
ChaloupeLora.X/Source/NetworkProtocol.c
Normal file
@ -0,0 +1,324 @@
|
||||
/**********************************************************************
|
||||
Project: Automatic cat feeder
|
||||
Date: march 19 2006
|
||||
Author: Jean-Fran<EFBFBD>ois Martel
|
||||
Target: PIC 18F252
|
||||
Compiler: Microchip mcc18
|
||||
Filename: Protocol.c
|
||||
|
||||
File description: Communication protocol implementation.
|
||||
|
||||
|
||||
jean-francois.martel@polymtl.ca
|
||||
**********************************************************************/
|
||||
#include "define.h"
|
||||
#include "NetworkProtocol.h"
|
||||
#include "Uart.h"
|
||||
#include <string.h>
|
||||
#include "ProtocolDefs.h"
|
||||
#include "MasterCtrlInterface.h"
|
||||
#include "LoraNetworkInterface.h"
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned char mRxData[MAX_MESSAGE_SIZE+10], mTxData[MAX_MESSAGE_SIZE+10];
|
||||
unsigned int DataSize = 0;
|
||||
unsigned int DataCtr = 0;
|
||||
unsigned int BufPtr = 0;
|
||||
unsigned char RxPtr = 0;
|
||||
unsigned char Command = 0;
|
||||
unsigned char State = RxHeader;
|
||||
unsigned char CRC = 0;
|
||||
unsigned char SenderID = 0;
|
||||
unsigned char SenderAddress = 0;
|
||||
unsigned char Flags = 0;
|
||||
unsigned char IsUpdating = 0;
|
||||
unsigned char *BmpDataPtr = 0;
|
||||
|
||||
static char MyDeviceID = ID_SPRINKLER_DEVICE;
|
||||
|
||||
void ProtocolInit(void)
|
||||
{
|
||||
ResetStateMachine();
|
||||
|
||||
}
|
||||
|
||||
void StateMachine(unsigned char Data)
|
||||
{
|
||||
switch(State)
|
||||
{
|
||||
case Initialization: //Reset all pointers and data...
|
||||
{
|
||||
DataSize = 0;
|
||||
BufPtr = 0;
|
||||
RxPtr = 0;
|
||||
Command = 0;
|
||||
CRC = 0;
|
||||
State = RxHeader;
|
||||
break;
|
||||
}
|
||||
case RxHeader: //Wait for data header...
|
||||
{
|
||||
if(Data == FRAME_HEADER)
|
||||
{
|
||||
mRxData[BufPtr++] = Data;
|
||||
State = RxAdd;
|
||||
CRC ^= Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
DataSize = 0;
|
||||
ResetStateMachine();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RxAdd: //Sender Address.
|
||||
{
|
||||
SenderAddress = Data;
|
||||
mRxData[BufPtr++] = Data;
|
||||
State = RxID;
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
case RxID: //Sender ID
|
||||
{
|
||||
mRxData[BufPtr++] = Data;
|
||||
State = RxMyID;
|
||||
SenderID = Data;
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
case RxMyID:
|
||||
{
|
||||
// if(Data != MyDeviceID && Data != BROADCAST_VALUE) //Message is not for this type of device and it's not a broadcast
|
||||
// {
|
||||
// ResetStateMachine();
|
||||
// break;
|
||||
// }
|
||||
mRxData[BufPtr++] = Data;
|
||||
State = RxMyAddress;
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
case RxMyAddress:
|
||||
{
|
||||
if(Data != MY_DEVICE_ADDRESS && Data != BROADCAST_VALUE) //Message is not for this device address and it's not a broadcast
|
||||
{
|
||||
ResetStateMachine();
|
||||
break;
|
||||
}
|
||||
mRxData[BufPtr++] = Data;
|
||||
State = RxFlags;
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
case RxFlags:
|
||||
{
|
||||
Flags = Data;
|
||||
mRxData[BufPtr++] = Data;
|
||||
State = RxCMD;
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
case RxCMD:
|
||||
{
|
||||
Command = Data;
|
||||
mRxData[BufPtr++] = Data;
|
||||
State = RxSize1;
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
case RxSize1: //Data size MSB
|
||||
{
|
||||
DataSize = 0;
|
||||
DataSize = (unsigned int)Data;
|
||||
DataSize <<= 8;
|
||||
mRxData[BufPtr++] = Data;
|
||||
|
||||
|
||||
State = RxSize2;
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
case RxSize2: //Data size
|
||||
{
|
||||
DataSize |= (unsigned int)Data;
|
||||
DataSize <<= 8;
|
||||
mRxData[BufPtr++] = Data;
|
||||
|
||||
|
||||
State = RxSize3;
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
case RxSize3: //Data size
|
||||
{
|
||||
DataSize |= (unsigned int)Data;
|
||||
DataSize <<= 8;
|
||||
mRxData[BufPtr++] = Data;
|
||||
|
||||
|
||||
State = RxSize4;
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
|
||||
case RxSize4: //Data size LSB
|
||||
{
|
||||
DataSize |= (unsigned int)Data;
|
||||
mRxData[BufPtr++] = Data;
|
||||
|
||||
if(DataSize > MAX_MESSAGE_SIZE)
|
||||
ResetStateMachine();
|
||||
|
||||
if(DataSize == 0)
|
||||
State = RxCRC;
|
||||
else
|
||||
State = RxData;
|
||||
|
||||
CRC ^= Data;
|
||||
break;
|
||||
}
|
||||
case RxData:
|
||||
{
|
||||
CRC ^= Data;
|
||||
|
||||
mRxData[BufPtr++] = Data;
|
||||
DataCtr++;
|
||||
|
||||
if(DataCtr == DataSize)
|
||||
{
|
||||
State = RxCRC;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RxCRC:
|
||||
{
|
||||
if(Data != CRC)
|
||||
{
|
||||
ResetStateMachine();
|
||||
// ProtocolAcknowledge(0,Command,0);
|
||||
break;
|
||||
}
|
||||
// NewMasterMessageReceived(mRxData);
|
||||
ExecuteMasterCommand(Command,ProtocolMsgDataPtr());
|
||||
ResetStateMachine();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ResetStateMachine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolAnalyzeNewData(unsigned char Data)
|
||||
{
|
||||
// mRxData[RxPtr] = Data;
|
||||
// printf("%X",Data);
|
||||
StateMachine(Data);
|
||||
}
|
||||
|
||||
void ResetStateMachine(void)
|
||||
{
|
||||
DataSize = 0;
|
||||
BufPtr = 0;
|
||||
RxPtr = 0;
|
||||
Command = 0;
|
||||
CRC = 0;
|
||||
State = RxHeader;
|
||||
DataCtr = 0;
|
||||
Flags = 0;
|
||||
SenderAddress = 0;
|
||||
}
|
||||
|
||||
void ProtocolExecCmd(void)
|
||||
{
|
||||
switch(Command)
|
||||
{
|
||||
case RX_GET_STATUS:
|
||||
{
|
||||
unsigned char StatusByte =0;
|
||||
// memcpy(&StatusByte, &IRRemoteStatus, sizeof(IRRemoteStatus));
|
||||
// ProtocolSendCmd(TX_DEADBOLT_STATUS,&StatusByte,sizeof(StatusByte),1,0);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolAcknowledge(unsigned char Answer,unsigned char Cmd, unsigned char Data)
|
||||
{
|
||||
unsigned char data[2];
|
||||
if(Answer == 1)
|
||||
{
|
||||
data[0] = PROTOCOL_ACK; //CMD
|
||||
}
|
||||
else
|
||||
{
|
||||
data[0] = PROTOCOL_NAK; //CMD
|
||||
}
|
||||
data[1] = Cmd;
|
||||
|
||||
// ProtocolSendCmd(TX_NETWORK_ACK,&data[0],2,1,0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char ProtocolCalcCrc(unsigned char* Buffer,unsigned char size)
|
||||
{
|
||||
unsigned char CRC = 0;
|
||||
unsigned char i;
|
||||
for(i = 0; i < size; i++)
|
||||
CRC ^= Buffer[i];
|
||||
|
||||
return CRC;
|
||||
}
|
||||
|
||||
unsigned char ProtocolIsReceiving(void)
|
||||
{
|
||||
if(State == RxHeader)
|
||||
return 0; // Idle...
|
||||
else
|
||||
return 1; //receiving from serial port
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char* ProtocolGetFrame(unsigned char DestDevice,unsigned char DestAddress, unsigned char SenderDevice, unsigned char Cmd, unsigned char *Data,unsigned int Size,unsigned char Flags, int *FrameSize)
|
||||
{
|
||||
if(Size > MAX_MESSAGE_SIZE)
|
||||
{
|
||||
*FrameSize = 0;
|
||||
return &mTxData[FRAME_HEADER_INDEX];
|
||||
}
|
||||
|
||||
mTxData[FRAME_HEADER_INDEX] = FRAME_HEADER; //header
|
||||
mTxData[FRAME_SENDER_ADDRESS_INDEX] = MY_DEVICE_ADDRESS; //My Address
|
||||
mTxData[FRAME_SENDER_DEVICE_ID_INDEX] = SenderDevice; //My ID
|
||||
mTxData[FRAME_DEST_DEVICE_ID_INDEX] = DestDevice; //Destination ID
|
||||
mTxData[FRAME_DEST_ADDRESS_INDEX] = DestAddress ;//Address; //Destination Address
|
||||
mTxData[FRAME_FLAGS_INDEX] = Flags; //Flags
|
||||
mTxData[FRAME_COMMAND_INDEX] = Cmd; //Command to send
|
||||
mTxData[FRAME_SIZE1_INDEX] = (unsigned char)((Size >> 24) & 0xFF);
|
||||
mTxData[FRAME_SIZE2_INDEX] = (unsigned char)((Size >> 16) & 0xFF);
|
||||
mTxData[FRAME_SIZE3_INDEX] = (unsigned char)((Size >> 8) & 0xFF);
|
||||
mTxData[FRAME_SIZE4_INDEX] = (unsigned char)(Size & 0xFF);
|
||||
memcpy((void*)&mTxData[FRAME_DATA_INDEX],(void*)Data,Size); //Cmd data
|
||||
mTxData[Size+FRAME_DATA_INDEX] = ProtocolCalcCrc(mTxData,Size + FRAME_DATA_INDEX); // CRC
|
||||
|
||||
*FrameSize = Size + FRAME_INDEX_NBR;
|
||||
|
||||
return &mTxData[FRAME_HEADER_INDEX];
|
||||
|
||||
}
|
||||
|
||||
unsigned char *ProtocolMsgDataPtr()
|
||||
{
|
||||
return &mRxData[FRAME_DATA_INDEX];
|
||||
}
|
||||
77
ChaloupeLora.X/Source/NetworkProtocol.h
Normal file
77
ChaloupeLora.X/Source/NetworkProtocol.h
Normal file
@ -0,0 +1,77 @@
|
||||
/**********************************************************************
|
||||
Project: Automatic cat feeder
|
||||
Date: march 19 2006
|
||||
Author: Jean-Fran<EFBFBD>ois Martel
|
||||
Target: PIC 18F252
|
||||
Compiler: Microchip mcc18
|
||||
Filename: Protocol.h
|
||||
|
||||
File description: Communication protocol implementation.
|
||||
|
||||
|
||||
jean-francois.martel@polymtl.ca
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#ifndef BOOTLOADERINTERFACE_H
|
||||
#define BOOTLOADERINTERFACE_H
|
||||
|
||||
//Protocol buffer specific definitions
|
||||
|
||||
#define MASTER_ADDRESS 0x01
|
||||
#define MY_DEVICE_ADDRESS 0x01
|
||||
|
||||
#define ADDRESS 0x01
|
||||
|
||||
//State Machine states
|
||||
enum States
|
||||
{
|
||||
Initialization,
|
||||
RxHeader,
|
||||
RxAdd,
|
||||
RxID,
|
||||
RxMyID,
|
||||
RxMyAddress,
|
||||
RxFlags,
|
||||
RxCMD,
|
||||
RxSize1,
|
||||
RxSize2,
|
||||
RxSize3,
|
||||
RxSize4,
|
||||
RxData,
|
||||
RxCRC
|
||||
};
|
||||
|
||||
//enum DEVICES_IDS
|
||||
//{
|
||||
// ID_MASTER, //Master Controller
|
||||
// ID_CONSOLE, //LCD Console
|
||||
// ID_PC, //PC
|
||||
// ID_AV_MUX, //Audio Video Multiplexer
|
||||
// ID_IR_REMOTE,
|
||||
// ID_DEADBOLT
|
||||
//};
|
||||
|
||||
//enum MESSAGE_IDS
|
||||
//{
|
||||
// TX_NETWORK_ACK = 1,
|
||||
// RX_GET_STATUS,
|
||||
// TX_DEADBOLT_STATUS,
|
||||
//
|
||||
// MAX_NETWORK_CMD
|
||||
//};
|
||||
|
||||
//State machine states definition
|
||||
|
||||
void ProtocolInit(void);
|
||||
void StateMachine(unsigned char STATE);
|
||||
void ProtocolAnalyzeNewData(unsigned char RxByte);
|
||||
void ResetStateMachine(void);
|
||||
void ProtocolExecCmd(void);
|
||||
void ProtocolAcknowledge(unsigned char Answer,unsigned char Cmd, unsigned char Data);
|
||||
unsigned char* ProtocolGetFrame(unsigned char DestDevice,unsigned char DestAddress, unsigned char SenderDevice, unsigned char Cmd, unsigned char *Data,unsigned int Size,unsigned char Flags, int *FrameSize);
|
||||
unsigned char ProtocolCalcCrc(unsigned char* Buffer,unsigned char size);
|
||||
unsigned char ProtocolIsReceiving(void);
|
||||
unsigned char *ProtocolMsgDataPtr();
|
||||
|
||||
#endif
|
||||
31
ChaloupeLora.X/Source/PWMCtrl.c
Normal file
31
ChaloupeLora.X/Source/PWMCtrl.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include "PWMCtrl.h"
|
||||
#include "BoardCfg.h"
|
||||
|
||||
|
||||
void PWMSetValue(unsigned int percent)
|
||||
{
|
||||
if(percent > 100)
|
||||
percent = 100;
|
||||
#ifdef REVERSE_POLARITY
|
||||
percent = 100 - percent;
|
||||
#endif
|
||||
|
||||
LED_PWM_VAL_REG = ((PWM_RANGE_MAX / 100) * percent);
|
||||
|
||||
}
|
||||
|
||||
void PWMShutDown()
|
||||
{
|
||||
PWMSetValue(0);
|
||||
}
|
||||
|
||||
void PWMSetAbsoluteValue(unsigned int value)
|
||||
{
|
||||
if(value > PWM_RANGE_MAX)
|
||||
{
|
||||
value = PWM_RANGE_MAX;
|
||||
}
|
||||
|
||||
LED_PWM_VAL_REG = value;
|
||||
|
||||
}
|
||||
18
ChaloupeLora.X/Source/PWMCtrl.h
Normal file
18
ChaloupeLora.X/Source/PWMCtrl.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* File: PWMCtrl.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 29, 2018, 5:24 PM
|
||||
*/
|
||||
|
||||
#ifndef PWMCTRL_H
|
||||
#define PWMCTRL_H
|
||||
|
||||
#define REVERSE_POLARITY
|
||||
|
||||
void PWMSetValue(unsigned int percent);
|
||||
void PWMShutDown();
|
||||
void PWMSetAbsoluteValue(unsigned int value);
|
||||
|
||||
#endif /* PWMCTRL_H */
|
||||
|
||||
97
ChaloupeLora.X/Source/PinguinoBoard.c
Normal file
97
ChaloupeLora.X/Source/PinguinoBoard.c
Normal file
@ -0,0 +1,97 @@
|
||||
#include "BoardCfg.h"
|
||||
|
||||
int InitBoard()
|
||||
{
|
||||
HEARTBEAT_LED_1_PIN_DIR = PIN_OUTPUT;
|
||||
// HEARTBEAT_LED_2_PIN_DIR = PIN_OUTPUT;
|
||||
|
||||
// HEARTBEAT_LED_2_PIN = LED_ON;
|
||||
HEARTBEAT_LED_1_PIN = LED_ON;
|
||||
|
||||
GP_DEBUG_1_PIN_DIR = PIN_OUTPUT;
|
||||
GP_DEBUG_1_PIN = 0;
|
||||
GP_DEBUG_2_PIN_DIR = PIN_OUTPUT;
|
||||
GP_DEBUG_2_PIN = 0;
|
||||
|
||||
|
||||
SPI_SDI_PIN_DIR = PIN_INPUT;
|
||||
SD_SPI_SS_PIN_DIR = PIN_OUTPUT;
|
||||
SPI_SDO_PIN_DIR = PIN_OUTPUT;
|
||||
SPI_SCK_PIN_DIR = PIN_OUTPUT;
|
||||
|
||||
//Wifi (WINC1500 module)
|
||||
WIFI_SPI_SS_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_SPI_SS_PIN = 1;
|
||||
WIFI_IRQ_PIN_DIR = PIN_INPUT;
|
||||
// WIFI_WAKE_PIN_DIR = PIN_OUTPUT;
|
||||
// WIFI_WAKE_PIN = 1;
|
||||
WIFI_SPI_CFG_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_SPI_CFG_PIN = 0;
|
||||
WIFI_CHP_EN_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_CHP_EN_PIN = 0;
|
||||
WIFI_CHP_RST_PIN_DIR = PIN_OUTPUT;
|
||||
WIFI_CHP_RST_PIN = 0;
|
||||
|
||||
//Wifi chip IRQ
|
||||
IEC0bits.INT0IE = 0;
|
||||
IFS0bits.INT0IF = 0;
|
||||
INTCONbits.INT0EP = 0; //Rising edge
|
||||
IPC0bits.INT0IP = 3;
|
||||
IPC0bits.INT0IS = 0;
|
||||
IEC0bits.INT0IE = 1;
|
||||
|
||||
//Wifi chip SPI
|
||||
SPI2CON = 0;
|
||||
SPI2CONbits.MSTEN = 1;
|
||||
SPI2CONbits.CKE = 0;
|
||||
SPI2CONbits.SMP = 0;
|
||||
SPI2CONbits.CKP = 0;
|
||||
SPI2BRG = SPICalculateBRG(PERIPHERAL_FREQ, 500000);
|
||||
SPI2CONbits.ON = 1;
|
||||
|
||||
|
||||
|
||||
//Control knob encoder
|
||||
KNOB_PH_A_PIN_DIR = PIN_INPUT;
|
||||
KNOB_PH_B_PIN_DIR = PIN_INPUT;
|
||||
KNOB_TGLE_BTN_PIN_DIR = PIN_INPUT;
|
||||
IEC0bits.INT1IE = 0;
|
||||
IFS0bits.INT1IF = 0;
|
||||
INTCONbits.INT1EP = 1; //Rising edge
|
||||
IPC1bits.INT1IP = 2;
|
||||
IPC1bits.INT1IS = 1;
|
||||
// IEC0bits.INT1IE = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Led controller PWM
|
||||
LED_PWM_PIN_DIR = PIN_OUTPUT;
|
||||
LED_PWM_PIN = 0;
|
||||
|
||||
OC3CON = 0;
|
||||
OC3R = 0;
|
||||
OC3RS = 2000; //50% PWM
|
||||
OC3CONbits.OCTSEL = 0;
|
||||
OC3CONbits.OCM = 0b110; //PWM mode, no fault protection
|
||||
|
||||
T2CONbits.TON = 0; // Disable Timer
|
||||
T2CONbits.TCS = 0; // Select internal instruction cycle clock
|
||||
T2CONbits.TGATE = 0; // Disable Gated Timer mode
|
||||
T2CONbits.TCKPS = 0b00; // Select 1:1 Prescaler
|
||||
TMR2 = 0x00; // Clear timer register
|
||||
|
||||
//PR2 = 256; // Load the period value
|
||||
PR2 = PWM_RANGE_MAX; //10KHz @ 80MHz
|
||||
|
||||
IPC2bits.T2IP = 0x01; // Set Timer 2 Interrupt Priority Level
|
||||
IFS0bits.T2IF = 0; // Clear Timer 2 Interrupt Flag
|
||||
IEC0bits.T2IE = 0; // Disable Timer 2 interrupt
|
||||
T2CONbits.TON = 1; // Start Timer
|
||||
|
||||
OC3CONbits.ON = 1;
|
||||
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
104
ChaloupeLora.X/Source/PrintfServer.c
Normal file
104
ChaloupeLora.X/Source/PrintfServer.c
Normal file
@ -0,0 +1,104 @@
|
||||
#include "define.h"
|
||||
#include "PrintfServer.h"
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
#include "TCPIP_Stack/TCPIP.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
//BYTE vTelnetSession;
|
||||
WORD w, w2;
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
TCP_SOCKET MyPrintfSocket;
|
||||
#endif
|
||||
|
||||
char mPrintfString[1024]; //Make shure this string is at least as big as the heap
|
||||
BOOL mPrintfAvailable;
|
||||
|
||||
int OpenPrintfServer()
|
||||
{
|
||||
memset(mPrintfString,'\0',1024);
|
||||
|
||||
#ifdef USE_WINC1500
|
||||
return 0;
|
||||
#else
|
||||
MyPrintfSocket = TCPOpen(0, TCP_OPEN_SERVER, 6463, TCP_PURPOSE_GENERIC_TCP_SERVER);
|
||||
|
||||
|
||||
if (MyPrintfSocket == INVALID_SOCKET)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
mPrintfAvailable = FALSE;
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void TickPrintfServer()
|
||||
{
|
||||
int length;
|
||||
static int PrintfServerTickState = PRINTF_SERVER_INIT_STATE;
|
||||
|
||||
switch(PrintfServerTickState)
|
||||
{
|
||||
case PRINTF_SERVER_INIT_STATE:
|
||||
{
|
||||
if(OpenPrintfServer() == 1)
|
||||
{
|
||||
PrintfServerTickState = PRINTF_SERVER_RUN_STATE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PRINTF_SERVER_RUN_STATE:
|
||||
{
|
||||
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
if(TCPIsConnected(MyPrintfSocket) == FALSE)
|
||||
{
|
||||
mPrintfAvailable = FALSE;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mPrintfAvailable == FALSE)
|
||||
{
|
||||
mPrintfAvailable = TRUE;
|
||||
TCPPutString(MyPrintfSocket,"Sprinkler printf console\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
length = (int)strlen(mPrintfString);
|
||||
if(length > 0 /*&& TCPIsPutReady(MySocket) > length*/)
|
||||
{
|
||||
TCPPutString(MyPrintfSocket,mPrintfString);
|
||||
memset(mPrintfString,'\0',1024);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TelnetPutPrintf(char c)
|
||||
{
|
||||
if(mPrintfAvailable == FALSE)
|
||||
return;
|
||||
|
||||
// if(strlen(mPrintfString) >= 1000)
|
||||
// return;
|
||||
//
|
||||
// strncat(mPrintfString,&c,1);
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
TCPPut(MyPrintfSocket,c);
|
||||
#endif
|
||||
// TCPFlush(MyPrintfSocket);
|
||||
}
|
||||
17
ChaloupeLora.X/Source/PrintfServer.h
Normal file
17
ChaloupeLora.X/Source/PrintfServer.h
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
#ifndef PRINTFSERVER_H
|
||||
#define PRINTFSERVER_H
|
||||
|
||||
enum ePrintfServerTickStates
|
||||
{
|
||||
PRINTF_SERVER_INIT_STATE,
|
||||
PRINTF_SERVER_RUN_STATE
|
||||
};
|
||||
|
||||
int OpenPrintfServer();
|
||||
void TickPrintfServer();
|
||||
void TelnetPutPrintf(char c);
|
||||
|
||||
|
||||
#endif
|
||||
339
ChaloupeLora.X/Source/ProtocolDefs.h
Normal file
339
ChaloupeLora.X/Source/ProtocolDefs.h
Normal file
@ -0,0 +1,339 @@
|
||||
/**********************************************************************
|
||||
Project: Automatic cat feeder
|
||||
Date: march 19 2006
|
||||
Author: Jean-François Martel
|
||||
Target: PIC 18F252
|
||||
Compiler: Microchip mcc18
|
||||
Filename: Protocol.h
|
||||
|
||||
File description: Communication protocol implementation.
|
||||
|
||||
|
||||
jean-francois.martel@polymtl.ca
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef PROTOCOLDEFS_H
|
||||
#define PROTOCOLDEFS_H
|
||||
|
||||
//Protocol buffer specific definitions
|
||||
|
||||
#define MAX_BOOTLOADER_MESSAGE_SIZE 25
|
||||
#define MAX_MESSAGE_SIZE 300
|
||||
#define BOOTLOADER_MAX_MESSAGE_SIZE 50
|
||||
|
||||
|
||||
#define FRAME_HEADER 0x8A
|
||||
#define BOOTLOADER_HEADER 0xA8
|
||||
#define DATA_START 11
|
||||
#define PROTOCOL_ACK 0xA3
|
||||
#define PROTOCOL_NAK 0x90
|
||||
#define BROADCAST_VALUE 0xFF
|
||||
|
||||
#define MASTER_RECONNECTION_TIMEOUT 25000 //Try to reconnect every 5s
|
||||
#define MASTER_RESPONSE_TIMEOUT 30000 //Wait max 30s for the master to respond...
|
||||
|
||||
enum eFrameIndex
|
||||
{
|
||||
FRAME_HEADER_INDEX = 0,
|
||||
FRAME_SENDER_ADDRESS_INDEX,
|
||||
FRAME_SENDER_DEVICE_ID_INDEX,
|
||||
FRAME_DEST_DEVICE_ID_INDEX,
|
||||
FRAME_DEST_ADDRESS_INDEX,
|
||||
FRAME_FLAGS_INDEX,
|
||||
FRAME_COMMAND_INDEX,
|
||||
FRAME_SIZE1_INDEX,
|
||||
FRAME_SIZE2_INDEX,
|
||||
FRAME_SIZE3_INDEX,
|
||||
FRAME_SIZE4_INDEX,
|
||||
FRAME_DATA_INDEX,
|
||||
|
||||
FRAME_INDEX_NBR
|
||||
};
|
||||
|
||||
enum DEVICES_IDS
|
||||
{
|
||||
ID_MASTER, //Master Controller
|
||||
ID_CONSOLE, //LCD Console
|
||||
ID_PC, //PC
|
||||
ID_AV_MUX, //Audio Video Multiplexer
|
||||
ID_IR_REMOTE, //Infra red transmitter
|
||||
ID_DEADBOLT_DEVICE,
|
||||
ID_AV_RECEIVER,
|
||||
ID_SMS_CLIENT,
|
||||
ID_ETHERNET_VIRTUAL,
|
||||
ID_SPRINKLER_DEVICE,
|
||||
ID_SPRINKLER_INTERFACE,
|
||||
ID_DEADBOLT_INTERFACE,
|
||||
ID_AVRECEIVER_INTERFACE,
|
||||
ID_CHALET_INTERFACE,
|
||||
ID_CHALET_DEVICE,
|
||||
ID_BOOTLOADER_VIRTUAL,
|
||||
ID_NB_DEVICE_ID
|
||||
|
||||
};
|
||||
|
||||
// Commands definitions
|
||||
|
||||
enum MASTER_CMD
|
||||
{
|
||||
RX_MASTER_GET_STATUS,
|
||||
TX_MASTER_STATUS,
|
||||
TX_MASTER_ACK,
|
||||
RX_MASTER_SET_NET_INFO,
|
||||
RX_MASTER_GET_NET_INFO,
|
||||
TX_MASTER_NET_INFO,
|
||||
RX_MASTER_SEND_DEVICE_CMD,
|
||||
TX_MASTER_SEND_DEVICE_CMD_ACK,
|
||||
RX_MASTER_SET_WEATHER_INFO,
|
||||
TX_MASTER_SET_WEATHER_INFO_ACK,
|
||||
RX_MASTER_SET_MAIL_MSG,
|
||||
TX_MASTER_SET_MAIL_MSG_ACK,
|
||||
RX_MASTER_NEW_OUTLOOK_EMAILS,
|
||||
TX_MASTER_NEW_OUTLOOK_EMAILS_ACK,
|
||||
RX_MASTER_TODAYS_EVENTS,
|
||||
TX_MASTER_TODAYS_EVENTS_ACK
|
||||
};
|
||||
|
||||
|
||||
//CONSOLE
|
||||
enum CONSOLE_CMD
|
||||
{
|
||||
RX_CONSOLE_GET_STATUS,
|
||||
TX_CONSOLE_STATUS,
|
||||
TX_CONSOLE_ACK,
|
||||
RX_START_CALIBRATION,
|
||||
RX_GET_CONSOLE_EVENT_MSG,
|
||||
TX_CONSOLE_EVENT_MSG,
|
||||
RX_CONSOLE_SHOW_CALLER_ID,
|
||||
RX_SET_TIME,
|
||||
RX_SET_WEATHER,
|
||||
RX_SEND_NEW_MAIL_MSG,
|
||||
RX_SEND_NEW_MAIL_MSG_ACK,
|
||||
RX_NEW_OUTLOOK_EMAILS,
|
||||
TX_NEW_OUTLOOK_EMAILS_ACK,
|
||||
RX_TODAYS_EVENTS,
|
||||
TX_TODAYS_EVENTS_ACK,
|
||||
LAST_CONSOLE_CMD
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum IR_REMOTE_CMDS
|
||||
{
|
||||
TX_IR_REMOTE_ACK = 1,
|
||||
RX_GET_STATUS,
|
||||
TX_REMOTE_STATUS,
|
||||
RX_TRANSMIT_CMD,
|
||||
RX_LEARN_IR_CMD,
|
||||
TX_LEARN_IR_CMD_FINISHED,
|
||||
RX_GET_IR_DATA,
|
||||
TX_SEND_IR_DATA,
|
||||
RX_SET_IR_CMD,
|
||||
RX_SET_IR_DATA,
|
||||
RX_GET_IR_CMD,
|
||||
TX_SEND_IR_CMD,
|
||||
MAX_IR_REMOTE_CMD
|
||||
};
|
||||
|
||||
//The SMS remote interface commands
|
||||
enum SMS_CLIENT_CMDS
|
||||
{
|
||||
SMS_CLIENT_DEVICE_ACK = 1,
|
||||
SMS_CLIENT_DEVICE_STATUS_REQUEST,
|
||||
SMS_CLIENT_DEVICE_STATUS_RESPONSE,
|
||||
SMS_CLIENT_DEVICE_DID_INFO_REQUEST,
|
||||
SMS_CLIENT_DEVICE_DID_INFO_RESPONSE,
|
||||
SMS_CLIENT_DEVICE_GET_ALL_MSG_REQUEST,
|
||||
SMS_CLIENT_DEVICE_GET_ALL_MSG_RESPONSE,
|
||||
SMS_CLIENT_DEVICE_NEW_MSG_NOTIFICATION,
|
||||
SMS_CLIENT_DEVICE_SEND_SMS_REQUEST,
|
||||
SMS_CLIENT_DEVICE_SEND_SMS_ACK,
|
||||
SMS_CLIENT_DEVICE_GET_CONTACTS_REQUEST,
|
||||
SMS_CLIENT_DEVICE_GET_CONTACTS_RESPONSE,//12
|
||||
SMS_CLIENT_DEVICE_CONTACTS_CHANGED_NOTIFICATION,
|
||||
|
||||
SMS_CLIENT_DEVICE_MAX_MSG
|
||||
|
||||
};
|
||||
|
||||
//The actual deadbolt device commands
|
||||
enum DEADBOLT_CMDS
|
||||
{
|
||||
DEADBOLT_DEVICE_ACK = 1,
|
||||
DEADBOLT_DEVICE_STATUS_REQUEST,
|
||||
DEADBOLT_DEVICE_STATUS_RESPONSE,
|
||||
DEADBOLT_DEVICE_GET_LOCKED_STATE_REQUEST,
|
||||
DEADBOLT_DEVICE_LOCKED_STATE_RESPONSE,
|
||||
DEADBOLT_DEVICE_GOTO_LOCKED_REQUEST,
|
||||
DEADBOLT_DEVICE_GOTO_LOCKED_ACK,
|
||||
DEADBOLT_DEVICE_GOTO_UNLOCKED_REQUEST,
|
||||
DEADBOLT_DEVICE_GOTO_UNLOCKED_ACK,
|
||||
DEADBOLT_DEVICE_GET_PASSWORDS_REQUEST,
|
||||
DEADBOLT_DEVICE_GET_PASSWORDS_RESPONSE,
|
||||
DEADBOLT_DEVICE_SET_PASSWORDS_REQUEST,
|
||||
DEADBOLT_DEVICE_SET_PASSWORDS_ACK,
|
||||
DEADBOLT_DEVICE_LOCK_EVENT,
|
||||
|
||||
MAX_DEADBOLT_DEVICE_CMD
|
||||
};
|
||||
|
||||
//The actual sprinkler module device commands
|
||||
enum SPRINKLER_DEVICE_CMDS
|
||||
{
|
||||
SPRINKLER_DEVICE_ACK = 1,
|
||||
SPRINKLER_DEVICE_STATUS_REQUEST,
|
||||
SPRINKLER_DEVICE_STATUS_RESPONSE,
|
||||
SPRINKLER_DEVICE_SET_SPRINKLER_STATE_REQUEST,
|
||||
SPRINKLER_DEVICE_SET_SPRINKLER_STATE_ACK,
|
||||
SPRINKLER_DEVICE_GET_SPRINKLER_STATE_REQUEST,
|
||||
SPRINKLER_DEVICE_GET_SPRINKLER_STATE_RESPONSE,
|
||||
SPRINKLER_DEVICE_GET_WATER_FLOW_REQUEST,
|
||||
SPRINKLER_DEVICE_GET_WATER_FLOW_RESPONSE,
|
||||
SPRINKLER_DEVICE_GET_MOISTURE_REQUEST,
|
||||
SPRINKLER_DEVICE_GET_MOISTURE_RESPONSE,
|
||||
SPRINKLER_DEVICE_SET_PROGRAM_REQUEST,
|
||||
SPRINKLER_DEVICE_SET_PROGRAM_ACK,
|
||||
SPRINKLER_DEVICE_GET_PROGRAM_REQUEST,
|
||||
SPRINKLER_DEVICE_GET_PROGRAM_RESPONSE,
|
||||
SPRINKLER_DEVICE_SET_PARAMETERS_REQUEST,
|
||||
SPRINKLER_DEVICE_SET_PARAMETERS_ACK,
|
||||
SPRINKLER_DEVICE_GET_PARAMETERS_REQUEST,
|
||||
SPRINKLER_DEVICE_GET_PARAMETERS_RESPONSE,
|
||||
|
||||
|
||||
MAX_SPRINKLER_DEVICE_CMD
|
||||
};
|
||||
|
||||
//The sprinkler interface commands
|
||||
enum SPRINKLER_INTERFACE_CMDS
|
||||
{
|
||||
SPRINKLER_INTERFACE_ACK = 1,
|
||||
SPRINKLER_INTERFACE_STATUS_REQUEST,
|
||||
SPRINKLER_INTERFACE_STATUS_RESPONSE,
|
||||
SPRINKLER_INTERFACE_GET_SPRINKLERS_REQUEST,
|
||||
SPRINKLER_INTERFACE_GET_SPRINKLERS_RESPONSE,
|
||||
SPRINKLER_INTERFACE_GET_SPRINKLER_DATA_REQUEST,
|
||||
SPRINKLER_INTERFACE_GET_SPRINKLER_DATA_RESPONSE,
|
||||
SPRINKLER_INTERFACE_SET_SPRINKLER_DATA_REQUEST,
|
||||
SPRINKLER_INTERFACE_SET_SPRINKLER_DATA_ACK,
|
||||
SPRINKLER_INTERFACE_GET_SPRINKLER_STATE_REQUEST,
|
||||
SPRINKLER_INTERFACE_GET_SPRINKLER_STATE_RESPONSE,
|
||||
SPRINKLER_INTERFACE_SET_SPRINKLER_STATE_REQUEST,
|
||||
SPRINKLER_INTERFACE_SET_SPRINKLER_STATE_ACK,
|
||||
|
||||
MAX_SPRINKLER_INTERFACE_CMD
|
||||
};
|
||||
|
||||
|
||||
enum ETHERNET_NETWORK_VIRTUAL_CMDS
|
||||
{
|
||||
ETH_NETWK_DEVICE_INFO_REQUEST = 0xD0,
|
||||
ETH_NETWK_DEVICE_INFO_RESPONSE,
|
||||
ETH_NETWK_SET_DEVICE_INFO_ACK,
|
||||
ETH_NETWK_CONNECTION_REFUSED,
|
||||
|
||||
MAX_ETHERNET_NETWORK_VIRTUAL_CMDS
|
||||
|
||||
};
|
||||
|
||||
enum AV_RECEIVER_INTERFACE_CMDS
|
||||
{
|
||||
AV_RECEIVER_INTERFACE_ACK = 1,
|
||||
AV_RECEIVER_INTERFACE_GENERAL_STATUS_REQUEST,
|
||||
AV_RECEIVER_INTERFACE_GENERAL_STATUS_RESPONSE,
|
||||
AV_RECEIVER_INTERFACE_SET_MAIN_POWER_REQUEST,
|
||||
AV_RECEIVER_INTERFACE_SET_MAIN_POWER_RESPONSE,
|
||||
AV_RECEIVER_INTERFACE_SET_SPEAKERB_REQUEST,
|
||||
AV_RECEIVER_INTERFACE_SET_SPEAKERB_RESPONSE,
|
||||
AV_RECEIVER_INTERFACE_SET_SPEAKERA_REQUEST,
|
||||
AV_RECEIVER_INTERFACE_SET_SPEAKERA_RESPONSE,
|
||||
AV_RECEIVER_INTERFACE_SET_SPEAKERS_REQUEST,
|
||||
AV_RECEIVER_INTERFACE_SET_SPEAKERS_RESPONSE,
|
||||
AV_RECEIVER_INTERFACE_SEND_DIRECT_CMD_REQUEST,
|
||||
AV_RECEIVER_INTERFACE_SEND_DIRECT_CMD_RESPONSE,
|
||||
|
||||
|
||||
MAX_AV_RECEIVER_INTERFACE_CMD
|
||||
};
|
||||
|
||||
enum CHALET_INTERFACE_CMDS
|
||||
{
|
||||
CHALET_INTERFACE_ACK = 1,
|
||||
CHALET_INTERFACE_GENERAL_STATUS_REQUEST,
|
||||
CHALET_INTERFACE_GENERAL_STATUS_RESPONSE,
|
||||
CHALET_INTERFACE_AC_POWER_STATE_STATUS_REQUEST,
|
||||
CHALET_INTERFACE_AC_POWER_STATE_STATUS_RESPONSE,
|
||||
CHALET_INTERFACE_AC_POWER_SET_STATE_REQUEST,
|
||||
CHALET_INTERFACE_AC_POWER_SET_STATE_RESPONSE,
|
||||
CHALET_INTERFACE_BATTERY_VOLTAGE_REQUEST,
|
||||
CHALET_INTERFACE_BATTERY_VOLTAGE_RESPONSE,
|
||||
|
||||
MAX_CHALET_INTERFACE_CMD
|
||||
};
|
||||
|
||||
enum CHALET_CMDS
|
||||
{
|
||||
CHALET_ACK = 1,
|
||||
CHALET_GENERAL_STATUS_REQUEST,
|
||||
CHALET_GENERAL_STATUS_RESPONSE,
|
||||
CHALET_AC_POWER_STATE_STATUS_REQUEST,
|
||||
CHALET_AC_POWER_STATE_STATUS_RESPONSE,
|
||||
CHALET_AC_POWER_SET_STATE_REQUEST,
|
||||
CHALET_AC_POWER_SET_STATE_RESPONSE,
|
||||
CHALET_BATTERY_VOLTAGE_REQUEST,
|
||||
CHALET_BATTERY_VOLTAGE_RESPONSE,
|
||||
CHALET_BATTERY_CURRENT_REQUEST,
|
||||
CHALET_BATTERY_CURRENT_RESPONSE,
|
||||
CHALET_WIFI_STATUS_REQUEST,
|
||||
CHALET_WIFI_STATUS_RESPONSE,
|
||||
CHALET_WIFI_SET_STATE_REQUEST,
|
||||
CHALET_WIFI_SET_STATE_RESPONSE,
|
||||
CHALET_DO_HARAKIRI_REQUEST,
|
||||
CHALET_DO_HARAKIRI_CONFIRMATION,
|
||||
CHALET_REBOOT_CPU_REQUEST,
|
||||
CHALET_REBOOT_CPU_RESPONSE,
|
||||
CHALET_GET_STORED_WIFI_SETTINGS_REQUEST,
|
||||
CHALET_GET_STORED_WIFI_SETTINGS_RESPONSE,
|
||||
CHALET_SET_STORED_WIFI_SETTINGS_REQUEST,
|
||||
CHALET_SET_STORED_WIFI_SETTINGS_RESPONSE,
|
||||
CHALET_GET_FIRMWARE_VERSION_REQUEST,
|
||||
CHALET_GET_FIRMWARE_VERSION_RESPONSE,
|
||||
CHALET_CLEAR_COMMS_STATISTICS_REQUEST,
|
||||
CHALET_CLEAR_COMMS_STATISTICS_RESPONSE,
|
||||
|
||||
MAX_CHALET_CMD
|
||||
};
|
||||
|
||||
enum BOOTLOADER_CMDS
|
||||
{
|
||||
BOOTLOADER_ACK = 1,
|
||||
BOOTLOADER_HEARTBEAT_REQUEST,
|
||||
BOOTLOADER_HEARTBEAT_RESPONSE,
|
||||
BOOTLOADER_ERASE_BOOTLOADER_FLASH_REQUEST,
|
||||
BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESPONSE,
|
||||
BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESULT_RESPONSE,
|
||||
BOOTLOADER_INIT_UPLOAD_REQUEST,
|
||||
BOOTLOADER_INIT_UPLOAD_RESPONSE,
|
||||
BOOTLOADER_GET_STATE_REQUEST,
|
||||
BOOTLOADER_GET_STATE_RESPONSE,
|
||||
BOOTLOADER_READY_FOR_DATA_RESPONSE,
|
||||
BOOTLOADER_SEND_DATA_CHUNK_REQUEST,
|
||||
BOOTLOADER_SEND_DATA_CHUNK_RESPONSE,
|
||||
BOOTLOADER_UPLOAD_FINISHED_REQUEST,
|
||||
BOOTLOADER_UPLOAD_FINISHED_RESPONSE,
|
||||
BOOTLOADER_EXECUTE_UPGRAGE_REQUEST,
|
||||
BOOTLOADER_EXECUTE_UPGRADE_RESPONSE,
|
||||
BOOTLOADER_ABORT_OPERATION_REQUEST,
|
||||
BOOTLOADER_ABORT_OPERATION_RESPONSE,
|
||||
BOOTLOADER_SEND_FLASH_DATA_REQUEST,
|
||||
BOOTLOADER_SEND_FLASH_DATA_RESPONSE,
|
||||
BOOTLOADER_SEND_FLASH_DATA_CHUNK,
|
||||
BOOTLOADER_SEND_FLASH_DATA_CHUNK_RESPONSE,
|
||||
BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_REQUEST,
|
||||
BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_RESPONSE,
|
||||
BOOTLOADER_GET_STORED_FIRMWARE_INFO_REQUEST,
|
||||
BOOTLOADER_GET_STORED_FIRMWARE_INFO_RESPONSE,
|
||||
|
||||
MAX_BOOTLOADER_CMD
|
||||
};
|
||||
#endif
|
||||
212
ChaloupeLora.X/Source/SDCardMgr.c
Normal file
212
ChaloupeLora.X/Source/SDCardMgr.c
Normal file
@ -0,0 +1,212 @@
|
||||
#include "SDCardMgr.h"
|
||||
|
||||
#ifdef USE_FATFS
|
||||
#include "FatFS/diskio.h"
|
||||
#include "FatFS/ff.h"
|
||||
|
||||
FATFS FatFs; /* File system object */
|
||||
FIL File[2]; /* File objects */
|
||||
BYTE Buff[4096]; /* Working buffer */
|
||||
|
||||
#else
|
||||
#include "sd_hw_ctl.h"
|
||||
#include "FileSystem/fileio_lfn.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "timer.h"
|
||||
|
||||
int mSDCardState;
|
||||
int mCardDetected;
|
||||
int mCardMounted;
|
||||
|
||||
#ifdef USE_FATFS
|
||||
#else
|
||||
uint16_t mDriveLetter;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_FATFS
|
||||
|
||||
int InitSDCard()
|
||||
{
|
||||
|
||||
|
||||
mSDCardState = SD_CARD_INIT_STATE;
|
||||
mCardDetected = 0;
|
||||
mCardMounted = 0;
|
||||
|
||||
return MountDrive();
|
||||
|
||||
|
||||
}
|
||||
int TickSDCard()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int MountDrive()
|
||||
{
|
||||
FRESULT res;
|
||||
res = f_mount(&FatFs, "", 0); /* Give a work area to the default drive */
|
||||
if(!res)
|
||||
{
|
||||
printf("Could not mount SD card\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("SD Card mounted successfuly");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IsDriveDetected()
|
||||
{
|
||||
return mCardDetected;
|
||||
}
|
||||
|
||||
int IsDriveMounted()
|
||||
{
|
||||
return mCardMounted;
|
||||
}
|
||||
|
||||
int ListRootDir()
|
||||
{
|
||||
FRESULT res;
|
||||
DIR dir;
|
||||
UINT i;
|
||||
static FILINFO fno;
|
||||
char path[] = "/";
|
||||
|
||||
|
||||
|
||||
res = f_opendir(&dir, path); /* Open the directory */
|
||||
if (res == FR_OK) {
|
||||
for (;;) {
|
||||
res = f_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
|
||||
// if (fno.fattrib & AM_DIR) { /* It is a directory */
|
||||
// i = strlen(path);
|
||||
// sprintf(&path[i], "/%s", fno.fname);
|
||||
// res = scan_files(path); /* Enter the directory */
|
||||
// if (res != FR_OK) break;
|
||||
// path[i] = 0;
|
||||
// } else { /* It is a file. */
|
||||
printf("%s/%s\n", path, fno.fname);
|
||||
//}
|
||||
}
|
||||
f_closedir(&dir);
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
void FILEIO_GetTimestamp (FILEIO_TIMESTAMP * timeStamp)
|
||||
{
|
||||
timeStamp->date.bitfield.day = 6;
|
||||
timeStamp->date.bitfield.month = 5;
|
||||
timeStamp->date.bitfield.year = (2017 - 1980);
|
||||
|
||||
timeStamp->time.bitfield.hours = 9;
|
||||
timeStamp->time.bitfield.minutes = 5;
|
||||
timeStamp->time.bitfield.secondsDiv2 = 0;
|
||||
|
||||
timeStamp->timeMs = 0;
|
||||
|
||||
}
|
||||
|
||||
int InitSDCard()
|
||||
{
|
||||
SD_SPIConfigurePins();
|
||||
FILEIO_Initialize();
|
||||
mSDCardState = SD_CARD_INIT_STATE;
|
||||
|
||||
mCardDetected = 0;
|
||||
mCardMounted = 0;
|
||||
|
||||
mDriveLetter = 'D';
|
||||
TimerStart(SD_CARD_DETECT_TIMER,5000);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int TickSDCard()
|
||||
{
|
||||
switch(mSDCardState)
|
||||
{
|
||||
case SD_CARD_INIT_STATE:
|
||||
{
|
||||
if(IsTimerExpired(SD_CARD_DETECT_TIMER))
|
||||
{
|
||||
if(FILEIO_MediaDetect(0, 0) == true)
|
||||
{
|
||||
mCardDetected = 1;
|
||||
mSDCardState = SD_CARD_MOUNT_DRIVE_STATE;
|
||||
printf("SD Card detected\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
TimerStart(SD_CARD_DETECT_TIMER,999);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SD_CARD_MOUNT_DRIVE_STATE:
|
||||
{
|
||||
if(FILEIO_DriveMount(mDriveLetter, 0, 0) == FILEIO_ERROR_NONE)
|
||||
{
|
||||
mCardMounted = 1;
|
||||
mSDCardState = SD_CARD_READY_STATE;
|
||||
printf("SD Card mounted on drive %c\n",(unsigned char)mDriveLetter);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSDCardState = SD_CARD_ERROR_MOUNTING_STATE;
|
||||
printf("Error mounting SD card.\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SD_CARD_READY_STATE:
|
||||
{
|
||||
// if(FILEIO_MediaDetect(0, 0) == false)
|
||||
// {
|
||||
// mCardDetected = 0;
|
||||
// mSDCardState = SD_CARD_INIT_STATE;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
case SD_CARD_ERROR_MOUNTING_STATE:
|
||||
{
|
||||
//wait for removal of the sd card...
|
||||
// if(FILEIO_MediaDetect(0, 0) == false)
|
||||
// {
|
||||
// mCardDetected = 0;
|
||||
// mSDCardState = SD_CARD_INIT_STATE;
|
||||
// printf("SD Card removed");
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int MountDrive()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int IsDriveDetected()
|
||||
{
|
||||
return mCardDetected;
|
||||
}
|
||||
|
||||
int IsDriveMounted()
|
||||
{
|
||||
return mCardMounted;
|
||||
}
|
||||
#endif
|
||||
45
ChaloupeLora.X/Source/SDCardMgr.h
Normal file
45
ChaloupeLora.X/Source/SDCardMgr.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* File: SDCardMgr.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on May 18, 2017, 8:20 PM
|
||||
*/
|
||||
|
||||
#ifndef SDCARDMGR_H
|
||||
#define SDCARDMGR_H
|
||||
#ifdef USE_FATFS
|
||||
//#include "FatFS/diskio.h"
|
||||
#else
|
||||
#include "FileSystem/fileio_lfn.h"
|
||||
#endif
|
||||
|
||||
enum eSDCardStates
|
||||
{
|
||||
SD_CARD_INIT_STATE,
|
||||
SD_CARD_MOUNT_DRIVE_STATE,
|
||||
SD_CARD_READY_STATE,
|
||||
SD_CARD_ERROR_MOUNTING_STATE
|
||||
};
|
||||
|
||||
#ifdef USE_FATFS
|
||||
|
||||
#else
|
||||
void FILEIO_GetTimestamp(FILEIO_TIMESTAMP * timeStamp);
|
||||
//void FILEIO_SETUP_HW();
|
||||
#endif
|
||||
|
||||
int InitSDCard();
|
||||
int MountDrive();
|
||||
int IsDriveDetected();
|
||||
int IsDriveMounted();
|
||||
int TickSDCard();
|
||||
|
||||
int ListRootDir();
|
||||
|
||||
|
||||
|
||||
//void FILEIO_
|
||||
|
||||
|
||||
#endif /* SDCARDMGR_H */
|
||||
|
||||
20
ChaloupeLora.X/Source/SPI.c
Normal file
20
ChaloupeLora.X/Source/SPI.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "define.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "SPI.h"
|
||||
|
||||
unsigned char SPITransaction(unsigned char OutBuf, unsigned char BaudRate)
|
||||
{
|
||||
|
||||
SPI2BRG = BaudRate;
|
||||
|
||||
// WIFI_SPI_SS_PIN = 0;
|
||||
|
||||
SPI2BUF = OutBuf;
|
||||
while(!SPI2STATbits.SPIRBF);
|
||||
|
||||
OutBuf = SPI2BUF;
|
||||
|
||||
// WIFI_SPI_SS_PIN = 1;
|
||||
|
||||
return OutBuf;
|
||||
}
|
||||
14
ChaloupeLora.X/Source/SPI.h
Normal file
14
ChaloupeLora.X/Source/SPI.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* File: SPI.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on December 2, 2018, 3:36 PM
|
||||
*/
|
||||
|
||||
#ifndef SPI_H
|
||||
#define SPI_H
|
||||
|
||||
unsigned char SPITransaction(unsigned char OutBuf, unsigned char Baudrate);
|
||||
|
||||
#endif /* SPI_H */
|
||||
|
||||
432
ChaloupeLora.X/Source/SPI_Flash.c
Normal file
432
ChaloupeLora.X/Source/SPI_Flash.c
Normal file
@ -0,0 +1,432 @@
|
||||
#include "SPI_Flash.h"
|
||||
#include "SPI.h"
|
||||
#include "BoardCfg.h"
|
||||
|
||||
unsigned char mSPIFlashBaudrate;
|
||||
unsigned char mSPIFlashHighSpeedBaudrate;
|
||||
unsigned char mFlashSectorBuffer[SPI_FLASH_SECTOR_SIZE];
|
||||
unsigned int mSPIFlashOK;
|
||||
|
||||
int InitSPIFlash()
|
||||
{
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
mSPIFlashBaudrate = SPICalculateBRG(PERIPHERAL_FREQ, 25000000);
|
||||
// mSPIFlashHighSpeedBaudrate = SPICalculateBRG(PERIPHERAL_FREQ, 50000000);
|
||||
mSPIFlashHighSpeedBaudrate = SPICalculateBRG(PERIPHERAL_FREQ, 35000000);
|
||||
mSPIFlashOK = 0;
|
||||
}
|
||||
|
||||
int SPIFlashCheckAndConfigure()
|
||||
{
|
||||
|
||||
if(SPIFlashCheckChipID() == RET_OK)
|
||||
{
|
||||
SPIFlashWriteEnable();
|
||||
|
||||
FLASH_SS_PIN = 0;
|
||||
SPITransaction(SPI_FLASH_WRITE_STATUS_REG,mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(0x00,mSPIFlashHighSpeedBaudrate); //Configure for write enable the whole memory
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
SPIFlashReadStatusReg(1);
|
||||
|
||||
mSPIFlashOK = 1;
|
||||
printf("SPI Flash configured\n");
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
mSPIFlashOK = 0;
|
||||
printf("ERROR: SPI Flash not detected\n");
|
||||
return RET_ERROR;
|
||||
|
||||
}
|
||||
|
||||
int SPIFlashIsPresent()
|
||||
{
|
||||
return mSPIFlashOK;
|
||||
}
|
||||
|
||||
int SPIFlashWriteEnable()
|
||||
{
|
||||
FLASH_SS_PIN = 0;
|
||||
SPITransaction(SPI_FLASH_WRITE_ENABLE,mSPIFlashHighSpeedBaudrate);
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char SPIFlashReadStatusReg(int print)
|
||||
{
|
||||
unsigned char result;
|
||||
|
||||
FLASH_SS_PIN = 0;
|
||||
result = SPITransaction(SPI_FLASH_READ_STATUS_REG,mSPIFlashBaudrate);
|
||||
result = SPITransaction(0x00,mSPIFlashBaudrate); //get data
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
if(print)
|
||||
{
|
||||
printf("Flash status register : 0x%x\n",result);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
int SPIFlashCheckBusy()
|
||||
{
|
||||
unsigned char status = SPIFlashReadStatusReg(0);
|
||||
if((status & SPI_FLASH_BUSY_MASK) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SPIFlashCheckChipID()
|
||||
{
|
||||
unsigned char VendorID, ChipID;
|
||||
|
||||
FLASH_SS_PIN = 0;
|
||||
SPITransaction(SPI_FLASH_READ_ID,mSPIFlashBaudrate);
|
||||
SPITransaction(0x00,mSPIFlashBaudrate);
|
||||
SPITransaction(0x00,mSPIFlashBaudrate);
|
||||
SPITransaction(0x00,mSPIFlashBaudrate); //Vendor address
|
||||
VendorID = SPITransaction(0x00,mSPIFlashBaudrate); //Vendor ID, should be 0xBF
|
||||
ChipID = SPITransaction(0x00,mSPIFlashBaudrate); //Device ID, should be 0x41
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
if(VendorID != SPI_FLASH_VENDOR_ID || ChipID != SPI_FLASH_CHIP_ID)
|
||||
{
|
||||
printf("SPI Flash detection FAILED. Vendor: 0x%x, Chip ID: 0x%x\n",VendorID,ChipID);
|
||||
return RET_ERROR;
|
||||
}
|
||||
printf("SPI Flash detected. Vendor: 0x%x, Chip ID: 0x%x\n",VendorID,ChipID);
|
||||
return RET_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int SPIFlashReadBuffer(unsigned char *Buf, int Size, int StartAddress)
|
||||
{
|
||||
if(StartAddress + Size - 1 > SPI_FLASH_MAX_ADDRESS)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
FLASH_SS_PIN = 0;
|
||||
SPITransaction(SPI_FLASH_HI_SPEED_READ,mSPIFlashBaudrate);
|
||||
SPITransaction(((StartAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(((StartAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction((StartAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction((0x00),mSPIFlashHighSpeedBaudrate); //Chip requires a dummy read in high speed
|
||||
|
||||
int i;
|
||||
for(i = 0; i < Size; i++)
|
||||
{
|
||||
unsigned char tmp;
|
||||
tmp =SPITransaction(0xDE,mSPIFlashHighSpeedBaudrate);
|
||||
*Buf++ = tmp;
|
||||
// *Buf++ = SPITransaction(0xDE,mSPIFlashHighSpeedBaudrate);
|
||||
}
|
||||
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int SPIFlashEraseSector(int SectorAddress)
|
||||
{
|
||||
if(SectorAddress % SPI_FLASH_SECTOR_SIZE != 0) //Sectors are aligned on 0x1000
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
SPIFlashWriteEnable();
|
||||
|
||||
FLASH_SS_PIN = 0;
|
||||
SPITransaction(SPI_FLASH_4KB_SECOTR_ERASE,mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(((SectorAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(((SectorAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction((SectorAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
SectorAddress++;
|
||||
|
||||
while( SPIFlashCheckBusy() == true);
|
||||
//SPIFlashWriteEnable();
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int SPIFlashErase64KSector(int SectorAddress, int Blocking)
|
||||
{
|
||||
if(SectorAddress % SPI_FLASH_64K_SECTOR_SIZE != 0) //Sectors are aligned on 0x1000
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
if((SectorAddress + SPI_FLASH_64K_SECTOR_SIZE - 1) > SPI_FLASH_MAX_ADDRESS)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
SPIFlashWriteEnable();
|
||||
|
||||
FLASH_SS_PIN = 0;
|
||||
SPITransaction(SPI_FLASH_64KB_BLOCK_ERASE,mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(((SectorAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(((SectorAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction((SectorAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
if(Blocking != 0)
|
||||
{
|
||||
while( SPIFlashCheckBusy() == true);
|
||||
// SPIFlashWriteEnable();
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SPIFlashWriteSectorWorkingBuffer(int SectorAddress, int Erase)
|
||||
{
|
||||
if(SectorAddress % SPI_FLASH_SECTOR_SIZE != 0) //Sectors are aligned on 0x1000
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
if(Erase == 1)
|
||||
{
|
||||
SPIFlashEraseSector(SectorAddress);
|
||||
}
|
||||
|
||||
unsigned char *DataPtr = &mFlashSectorBuffer[0];
|
||||
int j;
|
||||
for(j = 0; j < SPI_FLASH_SECTOR_SIZE; j++)
|
||||
{
|
||||
unsigned char curbyte;
|
||||
curbyte = *DataPtr;
|
||||
SPIFlashWriteEnable();
|
||||
|
||||
|
||||
|
||||
char Add1, Add2, Add3;
|
||||
Add1 = (unsigned char)((SectorAddress & 0xFF0000) >> 16);
|
||||
Add2 = ((unsigned char)((SectorAddress & 0x00FF00) >> 8));
|
||||
Add3 = ((unsigned char)(SectorAddress & 0x0000FF));
|
||||
|
||||
int t;
|
||||
t = 0;
|
||||
|
||||
FLASH_SS_PIN = 0;
|
||||
SPITransaction(SPI_FLASH_BYTE_PROGRAM,mSPIFlashHighSpeedBaudrate);
|
||||
// SPITransaction((unsigned char)((SectorAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
|
||||
// SPITransaction((unsigned char)((SectorAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
|
||||
// SPITransaction((unsigned char)(SectorAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(Add1,mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(Add2,mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(Add3,mSPIFlashHighSpeedBaudrate);
|
||||
|
||||
SPITransaction(curbyte,mSPIFlashHighSpeedBaudrate);
|
||||
// SPITransaction(*DataPtr,mSPIFlashHighSpeedBaudrate);
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
DataPtr++;
|
||||
SectorAddress++;
|
||||
|
||||
while( SPIFlashCheckBusy() == true);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int SPIFlashWriteByte(unsigned int ByteAddress, char byte, int blocking)
|
||||
{
|
||||
if(ByteAddress > SPI_FLASH_MAX_ADDRESS)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
SPIFlashWriteEnable();
|
||||
|
||||
FLASH_SS_PIN = 0;
|
||||
SPITransaction(SPI_FLASH_BYTE_PROGRAM,mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(((ByteAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(((ByteAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction((ByteAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
|
||||
SPITransaction(byte,mSPIFlashHighSpeedBaudrate);
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
if(blocking)
|
||||
{
|
||||
while( SPIFlashCheckBusy() == true);
|
||||
}
|
||||
|
||||
|
||||
return RET_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//int SPIFlashEraseSectorForWrite(unsigned char StartAddress, int Size)
|
||||
//{
|
||||
// //First, let's determine which sector to erase.
|
||||
//
|
||||
// int NbSectors = 1;
|
||||
// int FirstSector = StartAddress / 0x1000;
|
||||
// int LastSector = (StartAddress + Size) / 0x1000;
|
||||
//
|
||||
// if(LastSector > FirstSector)
|
||||
// {
|
||||
// NbSectors = LastSector - FirstSector;
|
||||
// }
|
||||
//
|
||||
// int i;
|
||||
// for(i = FirstSector; i < LastSector; i++ ) //Erase each sector one by one
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
//int SPIFlashWriteBuffer(unsigned char *Buf, int Size, int StartAddress)
|
||||
//{
|
||||
// //First, we need to determine if the data overlaps or uses more than one sector
|
||||
// //First, let's determine which sector to erase.
|
||||
// int EndAddress = StartAddress + Size - 1;
|
||||
// if(EndAddress > SPI_FLASH_MAX_ADDRESS)
|
||||
// {
|
||||
// return RET_ERROR;
|
||||
// }
|
||||
//
|
||||
// int NbSectors = 1;
|
||||
// int FirstSector = StartAddress / SPI_FLASH_SECTOR_SIZE;
|
||||
// int LastSector = EndAddress / SPI_FLASH_SECTOR_SIZE;
|
||||
//
|
||||
// if(LastSector > FirstSector)
|
||||
// {
|
||||
// NbSectors = LastSector - FirstSector + 1;
|
||||
// }
|
||||
//
|
||||
// int i;
|
||||
// int FlashAddress = StartAddress;
|
||||
// int CurSector = FirstSector;
|
||||
// for(i = 0; i < NbSectors; i++ ) //Read, erase and write each sector one by one
|
||||
// {
|
||||
// //first we need to backup the data outside our buffer.
|
||||
// //TODO: optimize
|
||||
// int SectorStartAddress = CurSector++ * SPI_FLASH_SECTOR_SIZE;
|
||||
// int SectorEndAddress = SectorStartAddress + SPI_FLASH_SECTOR_SIZE - 1;
|
||||
// if(SectorEndAddress > EndAddress)
|
||||
// {
|
||||
// SectorEndAddress = EndAddress;
|
||||
// }
|
||||
//
|
||||
// SPIFlashReadBuffer(mFlashSectorBuffer,SPI_FLASH_SECTOR_SIZE,SectorStartAddress); //Get local RAM buffer of the sector
|
||||
//
|
||||
// //Update the data to write.
|
||||
// int RAMAddress = FlashAddress - SectorStartAddress;
|
||||
// int RAMSectorSize = SectorEndAddress - FlashAddress + 1;
|
||||
// FlashAddress += RAMSectorSize;
|
||||
//
|
||||
// unsigned char* RAMPtr = &mFlashSectorBuffer[RAMAddress];
|
||||
// int j;
|
||||
// for(j = 0; j < RAMSectorSize; j++)
|
||||
// {
|
||||
// *RAMPtr++ = *Buf++;
|
||||
// }
|
||||
//
|
||||
// int SectorAddress = SectorStartAddress;
|
||||
// RAMPtr = mFlashSectorBuffer;
|
||||
//
|
||||
// for(j = 0; j < SPI_FLASH_SECTOR_SIZE; j++)
|
||||
// {
|
||||
// SPIFlashWriteEnable();
|
||||
//
|
||||
// FLASH_SS_PIN = 0;
|
||||
// SPITransaction(SPI_FLASH_BYTE_PROGRAM,mSPIFlashHighSpeedBaudrate);
|
||||
// SPITransaction(((SectorAddress & 0xFF0000) >> 16),mSPIFlashBaudrate);
|
||||
// SPITransaction(((SectorAddress & 0x00FF00) >> 8),mSPIFlashBaudrate);
|
||||
// SPITransaction((SectorAddress & 0x0000FF),mSPIFlashBaudrate);
|
||||
// SPITransaction(*RAMPtr++,mSPIFlashBaudrate);
|
||||
// FLASH_SS_PIN = 1;
|
||||
//
|
||||
// SectorAddress++;
|
||||
//
|
||||
// while( SPIFlashCheckBusy() == true);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
int SPIFlashWriteBuffer(unsigned char *Buf, int Size, int StartAddress)
|
||||
{
|
||||
int CurDataFlashAddress, DataFlashEndAddress;
|
||||
char *DataBufPtr, *WorkPagePtr;
|
||||
int WriteFinished;
|
||||
|
||||
|
||||
//Init stuff
|
||||
WriteFinished = 0;
|
||||
DataFlashEndAddress = StartAddress + Size; //Start + size means the data at "DataFlashEndAddress" should not be written.
|
||||
CurDataFlashAddress = StartAddress;
|
||||
DataBufPtr = Buf;
|
||||
|
||||
if(DataFlashEndAddress > SPI_FLASH_MAX_ADDRESS)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
while(WriteFinished == 0)
|
||||
{
|
||||
//Determine the current sector start address.
|
||||
int SectorStartAddress;
|
||||
SectorStartAddress = ((CurDataFlashAddress / SPI_FLASH_SECTOR_SIZE) * SPI_FLASH_SECTOR_SIZE); //Weird but it works
|
||||
|
||||
//Load the sector in RAM working buffer
|
||||
if(SPIFlashReadBuffer(mFlashSectorBuffer,SPI_FLASH_SECTOR_SIZE,SectorStartAddress) != RET_OK)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
//Set the working buffer pointer to the right value.
|
||||
WorkPagePtr = &mFlashSectorBuffer[CurDataFlashAddress - SectorStartAddress];
|
||||
|
||||
//Modify the working buffer with data to write.
|
||||
int SectorFinished = 0;
|
||||
while(SectorFinished == 0)
|
||||
{
|
||||
*WorkPagePtr++ = *DataBufPtr++;
|
||||
CurDataFlashAddress++;
|
||||
|
||||
//Are we at the end of the buffer to write?
|
||||
if(CurDataFlashAddress == DataFlashEndAddress)
|
||||
{
|
||||
SectorFinished = 1;
|
||||
WriteFinished = 1;
|
||||
// SPIFlashEraseSector(SectorStartAddress);
|
||||
SPIFlashWriteSectorWorkingBuffer(SectorStartAddress,1);
|
||||
|
||||
break;
|
||||
}
|
||||
else if(CurDataFlashAddress % SPI_FLASH_SECTOR_SIZE == 0) //Are we at the beginning of the next sector?
|
||||
{
|
||||
SectorFinished = 1;
|
||||
// SPIFlashEraseSector(SectorStartAddress);
|
||||
SPIFlashWriteSectorWorkingBuffer(SectorStartAddress,1);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
49
ChaloupeLora.X/Source/SPI_Flash.h
Normal file
49
ChaloupeLora.X/Source/SPI_Flash.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef SPI_FLASH_H /* Guard against multiple inclusion */
|
||||
#define SPI_FLASH_H
|
||||
|
||||
#define SPI_FLASH_READ 0x03
|
||||
#define SPI_FLASH_HI_SPEED_READ 0x0b
|
||||
#define SPI_FLASH_4KB_SECOTR_ERASE 0x20
|
||||
#define SPI_FLASH_32KB_BLOCK_ERASE 0x52
|
||||
#define SPI_FLASH_64KB_BLOCK_ERASE 0xd8
|
||||
#define SPI_FLASH_CHIP_ERASE 0x60
|
||||
#define SPI_FLASH_BYTE_PROGRAM 0x02
|
||||
#define SPI_FLASH_AAI_WORD_PROGRAM 0xad
|
||||
#define SPI_FLASH_READ_STATUS_REG 0x05
|
||||
#define SPI_FLASH_ENABLE_WRITE_STATUS_REG 0x50
|
||||
#define SPI_FLASH_WRITE_STATUS_REG 0x01
|
||||
#define SPI_FLASH_WRITE_ENABLE 0x06
|
||||
#define SPI_FLASH_WRITE_DISABLE 0x04
|
||||
#define SPI_FLASH_READ_ID 0x90
|
||||
#define SPI_FLASH_READ_JEDEC_ID 0x9f
|
||||
#define SPI_FLASH_ENABLE_SO_BUSY 0x70
|
||||
#define SPI_FLASH_DISABLE_SO_BUSY 0x80
|
||||
|
||||
|
||||
#define SPI_FLASH_BUSY_MASK 0x01
|
||||
|
||||
#define SPI_FLASH_VENDOR_ID 0xBF
|
||||
#define SPI_FLASH_CHIP_ID 0x41
|
||||
#define SPI_FLASH_MAX_ADDRESS 0x1FFFFF
|
||||
#define SPI_FLASH_SECTOR_SIZE 0x1000
|
||||
#define SPI_FLASH_64K_SECTOR_SIZE 0x10000
|
||||
#define SPI_NB_SECTORS 0x1FF //511 sectors = SPI_FLASH_MAX_ADDRESS / SPI_FLASH_SECTOR_SIZE
|
||||
|
||||
|
||||
int InitSPIFlash();
|
||||
int SPIFlashCheckChipID();
|
||||
unsigned char SPIFlashReadStatusReg(int print);
|
||||
int SPIFlashCheckAndConfigure();
|
||||
int SPIFlashReadBuffer(unsigned char *Buf, int Size, int StartAddress);
|
||||
int SPIFlashCheckBusy();
|
||||
int SPIFlashWriteEnable();
|
||||
int SPIFlashEraseSector(int SectorAddress);
|
||||
int SPIFlashErase64KSector(int SectorAddress, int Blocking);
|
||||
int SPIFlashWriteSectorWorkingBuffer(int SectorAddress, int Erase);
|
||||
int SPIFlashWriteBuffer(unsigned char *Buf, int Size, int StartAddress);
|
||||
int SPIFlashWriteByte(unsigned int ByteAddress, char byte, int blocking);
|
||||
int SPIFlashIsPresent();
|
||||
|
||||
|
||||
#endif /* SPI_FLASH_H */
|
||||
|
||||
7
ChaloupeLora.X/Source/Schedule.c
Normal file
7
ChaloupeLora.X/Source/Schedule.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "define.h"
|
||||
#include "Schedule.h"
|
||||
|
||||
void InitSchedule()
|
||||
{
|
||||
|
||||
}
|
||||
14
ChaloupeLora.X/Source/Schedule.h
Normal file
14
ChaloupeLora.X/Source/Schedule.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* File: Schedule.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on May 4, 2017, 1:16 PM
|
||||
*/
|
||||
|
||||
#ifndef SCHEDULE_H
|
||||
#define SCHEDULE_H
|
||||
|
||||
void InitSchedule();
|
||||
|
||||
#endif /* SCHEDULE_H */
|
||||
|
||||
39
ChaloupeLora.X/Source/Scheduler.c
Normal file
39
ChaloupeLora.X/Source/Scheduler.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2012 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
### 20120516 JFM
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
#include "Scheduler.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void InitScheduler(void)
|
||||
{
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//EOF
|
||||
48
ChaloupeLora.X/Source/Scheduler.h
Normal file
48
ChaloupeLora.X/Source/Scheduler.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2012 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
### 20120516 JFM
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
#ifndef SCHEDULER_H
|
||||
#define SCHEDULER_H
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
void InitScheduler(void);
|
||||
|
||||
|
||||
#endif
|
||||
//EOF
|
||||
|
||||
92
ChaloupeLora.X/Source/Syslog.c
Normal file
92
ChaloupeLora.X/Source/Syslog.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include "Syslog.h"
|
||||
#include "define.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "terminal.h"
|
||||
#include "WiFiCtrl.h"
|
||||
#include "timer.h"
|
||||
|
||||
//#define SYSLOG_BUFFER_SIZE 1024
|
||||
#define SYSLOG_BUFFER_SIZE 500
|
||||
char mSyslogBuffer[SYSLOG_BUFFER_SIZE];
|
||||
int mSyslogBufPtr;
|
||||
|
||||
int InitSyslog()
|
||||
{
|
||||
mSyslogBufPtr = 0;
|
||||
memset(mSyslogBuffer,0,SYSLOG_BUFFER_SIZE);
|
||||
TimerStart(SYSLOG_TX_TIMER,SYSLOG_TX_TIMEOUT);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SyslogTick()
|
||||
{
|
||||
if(IsSyslogClientConnected() == 0)
|
||||
{
|
||||
mSyslogBufPtr = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(mSyslogBufPtr != 0 && IsTimerExpired(SYSLOG_TX_TIMER) == 1)
|
||||
{
|
||||
SendSyslogData(mSyslogBuffer,mSyslogBufPtr);
|
||||
mSyslogBufPtr = 0;
|
||||
// if(mSyslogBufPtr >= 150)
|
||||
// {
|
||||
// SendSyslogData(mSyslogBuffer,150);
|
||||
// mSyslogBufPtr -= 150;
|
||||
//
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// SendSyslogData(mSyslogBuffer,mSyslogBufPtr);
|
||||
// mSyslogBufPtr = 0;
|
||||
// }
|
||||
TimerStart(SYSLOG_TX_TIMER,SYSLOG_TX_TIMEOUT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int SyslogNewByte(char byte)
|
||||
{
|
||||
if(IsSyslogClientConnected() == 0)
|
||||
{
|
||||
mSyslogBufPtr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mSyslogBuffer[mSyslogBufPtr] = byte;
|
||||
mSyslogBufPtr++;
|
||||
|
||||
if(mSyslogBufPtr == SYSLOG_BUFFER_SIZE)
|
||||
{
|
||||
SendSyslogData(mSyslogBuffer,SYSLOG_BUFFER_SIZE);
|
||||
mSyslogBufPtr = 0;
|
||||
}
|
||||
|
||||
TimerStart(SYSLOG_TX_TIMER,SYSLOG_TX_TIMEOUT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SyslogNewString(char *string)
|
||||
{
|
||||
if(IsSyslogClientConnected() == 0)
|
||||
{
|
||||
mSyslogBufPtr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SendSyslogData(string,strlen(string));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SyslogIsBufferEmpty()
|
||||
{
|
||||
if(mSyslogBufPtr == 0)
|
||||
return RET_OK;
|
||||
|
||||
return RET_ERROR;
|
||||
|
||||
}
|
||||
14
ChaloupeLora.X/Source/Syslog.h
Normal file
14
ChaloupeLora.X/Source/Syslog.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef SYSLOG_H
|
||||
#define SYSLOG_H
|
||||
|
||||
#define SYSLOG_TX_TIMEOUT 200 //ms
|
||||
|
||||
|
||||
int InitSyslog();
|
||||
void SyslogTick();
|
||||
int SyslogNewByte(char byte);
|
||||
int SyslogNewString(char *string);
|
||||
int SyslogIsBufferEmpty();
|
||||
|
||||
|
||||
#endif
|
||||
95
ChaloupeLora.X/Source/TC77.c
Normal file
95
ChaloupeLora.X/Source/TC77.c
Normal file
@ -0,0 +1,95 @@
|
||||
//#include <proc/p32mx440f256h.h>
|
||||
|
||||
#include "TC77.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "timer.h"
|
||||
|
||||
short mDeviceID;
|
||||
|
||||
int TC77Configure()
|
||||
{
|
||||
|
||||
TEMP_SENSOR_CS_PIN = 0;
|
||||
|
||||
//Execute a 16 bits read first.
|
||||
SPI3BUF = 0xFF;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
SPI3BUF = 0xFF;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
|
||||
//Now, write 0xFFFF to config register.
|
||||
SPI3BUF = 0xFF;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
SPI3BUF = 0xFF;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
|
||||
//Read Device ID
|
||||
SPI3BUF = 0x00;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
mDeviceID = SPI3BUF;
|
||||
mDeviceID <<= 8;
|
||||
|
||||
SPI3BUF = 0xFF;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
mDeviceID += SPI3BUF;
|
||||
TEMP_SENSOR_CS_PIN = 1;
|
||||
|
||||
mDeviceID &= 0xFFFC;
|
||||
if(mDeviceID != 0x5400)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
Sleep(100);
|
||||
|
||||
//Device detected. Now, put the device in continuous read mode.
|
||||
TEMP_SENSOR_CS_PIN = 0;
|
||||
|
||||
//Execute a 16 bits read first.
|
||||
SPI3BUF = 0xFF;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
SPI3BUF = 0xFF;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
|
||||
//Now, write 0x0000 to config register.
|
||||
SPI3BUF = 0x00;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
SPI3BUF = 0x00;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
|
||||
TEMP_SENSOR_CS_PIN = 1;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
float TC77GetActualTemp()
|
||||
{
|
||||
short RawTemp = 0;
|
||||
float Temp;
|
||||
TEMP_SENSOR_CS_PIN = 0;
|
||||
|
||||
//Read 16 bits.
|
||||
SPI3BUF = 0x00;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
RawTemp = SPI3BUF;
|
||||
RawTemp <<= 8;
|
||||
|
||||
SPI3BUF = 0xFF;
|
||||
while(!SPI3STATbits.SPIRBF);
|
||||
RawTemp += SPI3BUF;
|
||||
|
||||
TEMP_SENSOR_CS_PIN = 1;
|
||||
|
||||
RawTemp &= 0xFFF8; //Get rid of useless 3 LSB
|
||||
//RawTemp >>= 3;
|
||||
|
||||
Temp = ((float)0.0625 * (float)RawTemp);
|
||||
Temp /= 8;
|
||||
|
||||
return Temp;
|
||||
|
||||
}
|
||||
|
||||
short TC77GetDeviceID()
|
||||
{
|
||||
return mDeviceID;
|
||||
}
|
||||
18
ChaloupeLora.X/Source/TC77.h
Normal file
18
ChaloupeLora.X/Source/TC77.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* File:
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 30, 2018, 7:33 PM
|
||||
*/
|
||||
|
||||
#ifndef TC77_H
|
||||
#define TC77_H
|
||||
#include "define.h"
|
||||
|
||||
int TC77Configure();
|
||||
float TC77GetActualTemp();
|
||||
short TC77GetDeviceID();
|
||||
|
||||
|
||||
#endif /* TC77_H */
|
||||
|
||||
59
ChaloupeLora.X/Source/TCPServer.c
Normal file
59
ChaloupeLora.X/Source/TCPServer.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include "define.h"
|
||||
#include "TCPServer.h"
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
#include "TCPIP_Stack/TCPIP.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
BYTE vTelnetSession;
|
||||
WORD w, w2;
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
TCP_SOCKET MyTCPSocket;
|
||||
#endif
|
||||
|
||||
int OpenTCPServer()
|
||||
{
|
||||
#ifdef USE_WINC1500
|
||||
return 0;
|
||||
#else
|
||||
MyTCPSocket = TCPOpen(0, TCP_OPEN_SERVER, 1212, TCP_PURPOSE_GENERIC_TCP_SERVER);
|
||||
|
||||
if (MyTCPSocket == INVALID_SOCKET)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void TickTCPServer()
|
||||
{
|
||||
BYTE i;
|
||||
#ifdef USE_WINC1500
|
||||
#else
|
||||
WORD size = TCPIsGetReady(MyTCPSocket);
|
||||
if (size != 0)
|
||||
{
|
||||
printf("Server Rx %d bytes\n",size);
|
||||
BYTE buf[100];
|
||||
TCPGetArray(MyTCPSocket, buf,size);
|
||||
TCPPutArray(MyTCPSocket,buf,size);
|
||||
// switch (i)
|
||||
// {
|
||||
// case 'q':
|
||||
// case 'Q':
|
||||
// {
|
||||
// TCPPutString(MySocket, "Bye\n");
|
||||
// TCPDisconnect(MySocket);
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// {
|
||||
// TCPPut(MySocket,i);
|
||||
// }f
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
11
ChaloupeLora.X/Source/TCPServer.h
Normal file
11
ChaloupeLora.X/Source/TCPServer.h
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
#ifndef TCPSERVER_H
|
||||
#define TCPSERVER_H
|
||||
|
||||
|
||||
int OpenTCPServer();
|
||||
void TickTCPServer();
|
||||
|
||||
|
||||
#endif
|
||||
38
ChaloupeLora.X/Source/TemperatureSensor.c
Normal file
38
ChaloupeLora.X/Source/TemperatureSensor.c
Normal file
@ -0,0 +1,38 @@
|
||||
//#include <proc/p32mx440f256h.h>
|
||||
|
||||
#include "TemperatureSensor.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "TC77.h"
|
||||
#include "timer.h"
|
||||
|
||||
void InitTempSensor()
|
||||
{
|
||||
ActualTemp = 0xBAADBEEF;
|
||||
TimerStart(TEMP_SENSOR_REFRESH_TIMER,1000);
|
||||
}
|
||||
|
||||
int TempSensorCheckAndConfigure()
|
||||
{
|
||||
if(TC77Configure() == RET_OK)
|
||||
{
|
||||
ActualTemp = TC77GetActualTemp();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
float TempSensorGetTemp()
|
||||
{
|
||||
return ActualTemp;
|
||||
}
|
||||
|
||||
void TickTempSensor()
|
||||
{
|
||||
if(IsTimerExpired(TEMP_SENSOR_REFRESH_TIMER))
|
||||
{
|
||||
ActualTemp = TC77GetActualTemp();
|
||||
TimerStart(TEMP_SENSOR_REFRESH_TIMER,1000);
|
||||
// printf("Temperature: %f\n",ActualTemp);
|
||||
}
|
||||
}
|
||||
24
ChaloupeLora.X/Source/TemperatureSensor.h
Normal file
24
ChaloupeLora.X/Source/TemperatureSensor.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* File: ChaletPowerRelay.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on November 30, 2018, 7:33 PM
|
||||
*/
|
||||
|
||||
#ifndef TEMPERATURESENSOR_H
|
||||
#define TEMPERATURESENSOR_H
|
||||
#include "define.h"
|
||||
|
||||
float ActualTemp;
|
||||
|
||||
void InitTempSensor();
|
||||
int TempSensorCheckAndConfigure();
|
||||
float TempSensorGetTemp();
|
||||
|
||||
void TickTempSensor();
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* TEMPERATURESENSOR_H */
|
||||
|
||||
527
ChaloupeLora.X/Source/Terminal.c
Normal file
527
ChaloupeLora.X/Source/Terminal.c
Normal file
@ -0,0 +1,527 @@
|
||||
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
### 20120607 JFM
|
||||
Original version.
|
||||
|
||||
### 20120607 Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "terminal.h"
|
||||
#include "define.h"
|
||||
#include "WiFiCtrl.h"
|
||||
#include "LedLightCtrl.h"
|
||||
#include "ChaletPowerRelay.h"
|
||||
#include "BatteryMonitor.h"
|
||||
#include "BootloaderInterface.h"
|
||||
|
||||
//#include "SDCardMgr.h"
|
||||
#ifdef TERMINAL_USE_TELNET
|
||||
#include "TCPIP_Stack/Telnet.h"
|
||||
#endif
|
||||
|
||||
#define TerminalPrint(fmt, ...) \
|
||||
do { sprintf(TerminalWorkString, fmt, __VA_ARGS__); \
|
||||
TerminalPrintString(TerminalWorkString);} while (0)
|
||||
|
||||
char TerminalDataBuf[TERMINAL_STRING_LENGTH];
|
||||
char TerminalPrevDataBuf[TERMINAL_STRING_LENGTH];
|
||||
char TerminalWorkString[TERMINAL_STRING_LENGTH];
|
||||
char *TerminalDataPtr;
|
||||
|
||||
int mTerminalPendingAction;
|
||||
BOOL mTerminalOpened;
|
||||
int mTerminalTickState;
|
||||
|
||||
static BYTE mHelpString[] = "Here is the list of the available commands:\n\r\n\r"
|
||||
"help : Shows this window\n\r"
|
||||
"\npower [state] Set chalet's 12V Inverter feed power state. This command controls the main power relay\n"
|
||||
" - Available [state] argument are: on\n"
|
||||
" off\n"
|
||||
"\nwifi [command] control ChaletDuino's WiFi module state%\n"
|
||||
" - Available [command] argument are: on (turns ON module)\n"
|
||||
" off (turns OFF module)\n"
|
||||
" status (returns current status)\n"
|
||||
"\nbattery [sensor] returns current battery sensors readings\n"
|
||||
" - Available [sensor] argument are: voltage\n"
|
||||
" current\n"
|
||||
" soc (state of charge)\n"
|
||||
" Empty [sensor] argument prints all values\n"
|
||||
"\nstatus : get general system status\n"
|
||||
"\nbootloader [command] : bootloader mode control\n"
|
||||
" - Available [command] argument are: start (enable bootloader and opens port)\n"
|
||||
" stop (disables bootloader if not busy)\n"
|
||||
" state (prints actual state of the bootloader)\n"
|
||||
|
||||
//"\ndebug : print some real-time stuff..."
|
||||
"\nHave a good day!\n";
|
||||
|
||||
BYTE *mHelpStringPtr;
|
||||
|
||||
void InitTerminal(void)
|
||||
{
|
||||
TerminalDataPtr = &TerminalDataBuf[0];
|
||||
memset(TerminalDataBuf,0,sizeof(TerminalDataBuf));
|
||||
memset(TerminalPrevDataBuf,'\0',sizeof(TerminalPrevDataBuf));
|
||||
memset(TerminalWorkString,'\0',sizeof(TerminalWorkString));
|
||||
|
||||
mTerminalPendingAction = TERMINAL_ACTION_NONE;
|
||||
}
|
||||
|
||||
|
||||
void TickTerminal()
|
||||
{
|
||||
switch(mTerminalPendingAction)
|
||||
{
|
||||
case TERMINAL_ACTION_NONE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case TERMINAL_ACTION_TURN_OFF_WIFI:
|
||||
{
|
||||
mTerminalPendingAction = TERMINAL_ACTION_NONE;
|
||||
TurnOFFWiFi();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RxTerminalBuf(uint8* DataBuf, int size)
|
||||
{
|
||||
if(DataBuf != 0)
|
||||
{
|
||||
int i = 0;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
RxTerminalData(*DataBuf++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RxTerminalData(unsigned char Data)
|
||||
{
|
||||
// sTerminalPrint(TerminalWorkString,"%c",Data);
|
||||
// TerminalPrintString(TerminalWorkString);
|
||||
if(Data == 0x0D) //enter
|
||||
{
|
||||
//TerminalPrint("\n\r");
|
||||
TerminalPrintString("\n\r\0");
|
||||
|
||||
if(strlen(TerminalDataBuf) != 0)
|
||||
{
|
||||
strcpy(TerminalPrevDataBuf,TerminalDataBuf);
|
||||
ParseNewBuffer();
|
||||
}
|
||||
|
||||
TerminalDataPtr = &TerminalDataBuf[0];
|
||||
memset(TerminalDataBuf,'\0',sizeof(TerminalDataBuf));
|
||||
|
||||
}
|
||||
else if(Data == 0x08 || Data == 0x7F) //backspace
|
||||
{
|
||||
// TerminalPrint("%c",Data);
|
||||
TerminalPrintChar(Data);
|
||||
if(TerminalDataPtr != &TerminalDataBuf[0])
|
||||
{
|
||||
TerminalDataPtr--;
|
||||
*TerminalDataPtr = '\0';
|
||||
}
|
||||
|
||||
}
|
||||
// else if(Data == 0x1B) //Up key
|
||||
// {
|
||||
// //memcpy(TerminalDataBuf,TerminalPrevDataBuf,strlen(TerminalPrevDataBuf)-1);
|
||||
// strcpy(TerminalDataBuf,TerminalPrevDataBuf);
|
||||
// TerminalPrint("%s",TerminalDataBuf);
|
||||
// }
|
||||
else
|
||||
{
|
||||
//TerminalPrint("%c",Data);
|
||||
TerminalPrintChar(Data);
|
||||
if(TerminalDataPtr < &TerminalDataBuf[TERMINAL_STRING_LENGTH])
|
||||
{
|
||||
*TerminalDataPtr = Data;
|
||||
TerminalDataPtr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParseNewBuffer(void)
|
||||
{
|
||||
char mCmdString[30], mDataString1[30], mDataString2[30], mDataString3[30],mDataString4[30];
|
||||
memset(mCmdString,'\0',sizeof(mCmdString));
|
||||
memset(mDataString1,'\0',sizeof(mDataString1));
|
||||
memset(mDataString2,'\0',sizeof(mDataString2));
|
||||
memset(mDataString3,'\0',sizeof(mDataString3));
|
||||
memset(mDataString4,'\0',sizeof(mDataString4));
|
||||
|
||||
sscanf(TerminalDataBuf,"%s %s %s %s %s",mCmdString, mDataString1, mDataString2, mDataString3,mDataString4);
|
||||
|
||||
if(strncmp(mCmdString,"help",strlen("help")) == 0)
|
||||
{
|
||||
mHelpStringPtr = mHelpString;
|
||||
static BYTE* Ptr= mHelpString;
|
||||
|
||||
SendTerminalData(mHelpString,strlen(mHelpString));
|
||||
|
||||
Ptr = mHelpStringPtr;
|
||||
}
|
||||
|
||||
else if(strncmp(mCmdString,"power",strlen("power")) == 0)
|
||||
{
|
||||
if(strlen(mDataString1) == 0)
|
||||
{
|
||||
TerminalPrintString("\n[state] parameter is invalid. Type 'help' for more info\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(strncmp(mDataString1,"on",strlen("on")) == 0)
|
||||
{
|
||||
TerminalPrintString("Turning chalet's inverter ON\n");
|
||||
ChaletPowerRelayTurnOn();
|
||||
}
|
||||
else if(strncmp(mDataString1,"off",strlen("off")) == 0)
|
||||
{
|
||||
TerminalPrintString("Turning chalet's inverter OFF\n");
|
||||
ChaletPowerRelayTurnOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
TerminalPrintString("\n[state] parameter is invalid. Type 'help' for valid values\n");
|
||||
}
|
||||
|
||||
TerminalPrintString("\n");
|
||||
}
|
||||
else if(strncmp(mCmdString,"wifi",strlen("wifi")) == 0)
|
||||
{
|
||||
if(strlen(mDataString1) == 0)
|
||||
{
|
||||
TerminalPrintString("\n[value] parameter is invalid. Type 'help' for more info\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(strncmp(mDataString1,"on",strlen("on")) == 0)
|
||||
{
|
||||
if(GetWiFiSate() != WIFI_CONNECTED_STATE)
|
||||
{
|
||||
TerminalPrintString("Turning WiFi module ON\n");
|
||||
InitWiFi();
|
||||
}
|
||||
else
|
||||
{
|
||||
TerminalPrintString("WiFi already connected...\n");
|
||||
}
|
||||
}
|
||||
else if(strncmp(mDataString1,"off",strlen("off")) == 0)
|
||||
{
|
||||
if(GetWiFiSate() != WIFI_MODULE_OFF_STATE)
|
||||
{
|
||||
TerminalPrintString("Turning WiFi module OFF... Goodbye!\n");
|
||||
//TurnOFFWiFi();
|
||||
mTerminalPendingAction = TERMINAL_ACTION_TURN_OFF_WIFI;
|
||||
}
|
||||
else
|
||||
{
|
||||
TerminalPrintString("WiFi module already OFF... that's weird!\n");
|
||||
}
|
||||
}
|
||||
else if(strncmp(mDataString1,"status",strlen("status")) == 0)
|
||||
{
|
||||
switch (GetWiFiSate())
|
||||
{
|
||||
case WIFI_MODULE_OFF_STATE:
|
||||
{
|
||||
TerminalPrintString("WiFi module OFF\n");
|
||||
break;
|
||||
}
|
||||
case WIFI_CONNECTED_STATE:
|
||||
{
|
||||
TerminalPrintString("WiFi Connected\n");
|
||||
break;
|
||||
}
|
||||
case WIFI_DISCONNECTED_STATE:
|
||||
{
|
||||
TerminalPrintString("WiFi Disconnected\n");
|
||||
break;
|
||||
}
|
||||
case WIFI_INIT_ERROR_STATE:
|
||||
{
|
||||
TerminalPrintString("WiFi ERROR\n");
|
||||
break;
|
||||
}
|
||||
case WIFI_UNKNOWN_STATE:
|
||||
{
|
||||
TerminalPrintString("WiFi state Unknown!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TerminalPrintString("\n");
|
||||
}
|
||||
else if(strncmp(mCmdString,"battery",strlen("battery")) == 0)
|
||||
{
|
||||
if(strlen(mDataString1) == 0)
|
||||
{
|
||||
char voltage[15];
|
||||
sprintf(voltage,"%f",GetBatteryVoltage());
|
||||
TerminalPrintString("Battery Voltage: ");
|
||||
TerminalPrintString(voltage);
|
||||
TerminalPrintString("\n");
|
||||
char current[15];
|
||||
sprintf(current,"%d",GetSolarPanelCurrent());
|
||||
TerminalPrintString("Battery charge current: ");
|
||||
TerminalPrintString(current);
|
||||
TerminalPrintString("mA\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(strncmp(mDataString1,"voltage",strlen("voltage")) == 0)
|
||||
{
|
||||
char voltage[15];
|
||||
sprintf(voltage,"%f",GetBatteryVoltage());
|
||||
TerminalPrintString("Battery Voltage: ");
|
||||
TerminalPrintString(voltage);
|
||||
TerminalPrintString("\n");
|
||||
}
|
||||
else if(strncmp(mDataString1,"current",strlen("current")) == 0)
|
||||
{
|
||||
char current[15];
|
||||
sprintf(current,"%d",GetSolarPanelCurrent());
|
||||
TerminalPrintString("Battery charge current: ");
|
||||
TerminalPrintString(current);
|
||||
TerminalPrintString("mA\n");
|
||||
}
|
||||
else if(strncmp(mDataString1,"soc",strlen("soc")) == 0)
|
||||
{
|
||||
char SOC[15];
|
||||
sprintf(SOC,"%d",GetBatterySOC());
|
||||
TerminalPrintString("Battery SOC: ");
|
||||
// TerminalPrintString(SOC);
|
||||
TerminalPrintString("%\n");
|
||||
}
|
||||
TerminalPrintString("\n");
|
||||
}
|
||||
else if(strncmp(mCmdString,"status",strlen("status")) == 0)
|
||||
{
|
||||
// TerminalPrintString("General status:\nBattery: TBD \nWiFi: TBD\nOther Stuff: TBD\n");
|
||||
TerminalPrintString("General status:\n");
|
||||
|
||||
if(GetChaletPowerRelayState() == CHALET_POWER_RELAY_OFF_STATE)
|
||||
{
|
||||
TerminalPrintString("Inverter power relay: OFF\n");
|
||||
}
|
||||
else if(GetChaletPowerRelayState() == CHALET_POWER_RELAY_ON_STATE)
|
||||
{
|
||||
TerminalPrintString("Inverter power relay: ON\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
TerminalPrintString("Inverter power relay: UNKNOWN\n");
|
||||
}
|
||||
|
||||
switch(GetWiFiSate())
|
||||
{
|
||||
case WIFI_MODULE_OFF_STATE:
|
||||
{
|
||||
TerminalPrintString("WiFi: Module is turned OFF\n");
|
||||
break;
|
||||
}
|
||||
case WIFI_CONNECTED_STATE:
|
||||
{
|
||||
TerminalPrintString("WiFi: Connected to AP\n");
|
||||
break;
|
||||
}
|
||||
case WIFI_DISCONNECTED_STATE:
|
||||
{
|
||||
TerminalPrintString("WiFi: Disconnected from AP\n");
|
||||
break;
|
||||
}
|
||||
case WIFI_INIT_ERROR_STATE:
|
||||
{
|
||||
TerminalPrintString("WiFi: Module initialization error\n");
|
||||
break;
|
||||
}
|
||||
case WIFI_UNKNOWN_STATE:
|
||||
default:
|
||||
{
|
||||
TerminalPrintString("WiFi: Unknown state\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char voltage[15];
|
||||
memset(voltage,0,15);
|
||||
sprintf(voltage,"%.2f",GetBatteryVoltage());
|
||||
TerminalPrintString("Battery Voltage: ");
|
||||
TerminalPrintString(voltage);
|
||||
TerminalPrintString("V\n");
|
||||
|
||||
char current[15];
|
||||
memset(current,0,15);
|
||||
sprintf(current,"%dmA\n",GetSolarPanelCurrent());
|
||||
TerminalPrintString("Battery charge current: ");
|
||||
TerminalPrintString(current);
|
||||
//TerminalPrintString("mA\n");
|
||||
|
||||
Sleep(100);
|
||||
char SOC[15];
|
||||
memset(SOC,0,15);
|
||||
sprintf(SOC,"%d%%\n",GetBatterySOC());
|
||||
TerminalPrintString("Battery SOC: ");
|
||||
TerminalPrintString(SOC);
|
||||
// TerminalPrintString("\n");
|
||||
|
||||
|
||||
TerminalPrintString("\n");
|
||||
}
|
||||
else if(strncmp(mCmdString,"bootloader",strlen("bootloader")) == 0)
|
||||
{
|
||||
if(strlen(mDataString1) == 0)
|
||||
{
|
||||
TerminalPrintString("\n[command] parameter is invalid. Type 'help' for more info\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(strncmp(mDataString1,"start",strlen("start")) == 0)
|
||||
{
|
||||
//start bootloader server
|
||||
// OpenBootloaderServer();
|
||||
BootloaderActivateBootloader();
|
||||
TerminalPrintString("Activating bootloader\n");
|
||||
}
|
||||
else if(strncmp(mDataString1,"stop",strlen("stop")) == 0)
|
||||
{
|
||||
//CloseBootloaderServer();
|
||||
TerminalPrintString("Deactivating bootloader\n");
|
||||
BootloaderDeactivateBootloader();
|
||||
}
|
||||
else if(strncmp(mDataString1,"status",strlen("status")) == 0)
|
||||
{
|
||||
if(IsBootloaderClientConnected())
|
||||
{
|
||||
TerminalPrintString("\nBootloader client connected\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(IsBootloaderClientConnected())
|
||||
{
|
||||
TerminalPrintString("\nBootloader client not connected\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(strncmp(mCmdString,"debug",strlen(mCmdString)) == 0)
|
||||
{
|
||||
// if(strlen(mDataString1) == 0)
|
||||
// {
|
||||
// TerminalPrintString("\n[subsystem] parameter is invalid. Type 'help' for more info\n");
|
||||
// return;
|
||||
// }
|
||||
// if(strlen(mDataString2) == 0)
|
||||
// {
|
||||
// TerminalPrintString("\n[timeout] parameter is invalid. Type 'help' for more info\n");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// unsigned int timeout = atoi(mDataString2);
|
||||
// if(timeout != 0 && timeout < 100 && timeout > 5000)
|
||||
// {
|
||||
// TerminalPrint("[timeout] value must be between 100 & 5000. Current value: %d",timeout);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(strncmp(mDataString1,"valve",strlen("valve")) == 0)
|
||||
// {
|
||||
// // TerminalPrintValveStatus();
|
||||
// TerminalPrintString("Debug valve not implemented\n");
|
||||
// }
|
||||
// else if(strncmp(mDataString1,"flow",strlen("flow")) == 0)
|
||||
// {
|
||||
// if(timeout == 0)
|
||||
// {
|
||||
// TerminalPrintString("Flow debugging stopped\n");
|
||||
// StopDebugFlowMeter();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// TerminalPrintString("OK\n");
|
||||
// StartDebugFlowMeter(timeout);
|
||||
// }
|
||||
// }
|
||||
// else if(strncmp(mDataString1,"hygro",strlen("hygro")) == 0)
|
||||
// {
|
||||
// TerminalPrintString("Debug hygro not implemented\n");
|
||||
// }
|
||||
}
|
||||
|
||||
else
|
||||
TerminalPrintString("Unknown command\n\n");
|
||||
}
|
||||
|
||||
void TerminalPrintString(char *str)
|
||||
{
|
||||
#ifdef USE_WINC1500
|
||||
SendTerminalData(str,strlen(str));
|
||||
#else
|
||||
#ifdef TERMINAL_USE_TCP_SERVER
|
||||
TCPPutString(mTerminalSocket, str);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void TerminalPrintChar(char byte)
|
||||
{
|
||||
#ifdef USE_WINC1500
|
||||
SentTerminalByte(byte);
|
||||
#else
|
||||
#ifdef TERMINAL_USE_TCP_SERVER
|
||||
TCPPut(mTerminalSocket,byte);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void TerminalStateMachine(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
//void TerminalPrintValveStatus()
|
||||
//{
|
||||
// if(GetValveState() == VALVE_ON)
|
||||
// {
|
||||
// TerminalPrintString("The valve is ON\n");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// TerminalPrintString("The valve is OFF\n");
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void TerminalPrintFlowStatus()
|
||||
//{
|
||||
// unsigned int Flow = GetCurrentFlow();
|
||||
// TerminalPrint("Flow: %d\n",Flow);;
|
||||
//}
|
||||
//
|
||||
//void TerminalPrintHygroStatus(int unit)
|
||||
//{
|
||||
// TerminalPrint("Hygro %d: ?\n",unit);
|
||||
//}
|
||||
//
|
||||
|
||||
//EOf
|
||||
|
||||
67
ChaloupeLora.X/Source/Terminal.h
Normal file
67
ChaloupeLora.X/Source/Terminal.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2012 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
### YYYYMMDD JFM
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
#define TERMINAL_STRING_LENGTH 300
|
||||
#define USE_WINC1500
|
||||
enum eTerminalCmds
|
||||
{
|
||||
HELP_CMD,
|
||||
PWM_CMD,
|
||||
SET_CMD,
|
||||
MAX_CMD
|
||||
};
|
||||
|
||||
enum eTerimnalTickStates
|
||||
{
|
||||
TERMINAL_INIT_STATE,
|
||||
TERMINAL_RUN_STATE
|
||||
};
|
||||
|
||||
enum eTerminalActions
|
||||
{
|
||||
TERMINAL_ACTION_NONE = 0,
|
||||
TERMINAL_ACTION_TURN_OFF_WIFI,
|
||||
|
||||
TERMINAL_ACTION_MAX
|
||||
};
|
||||
|
||||
|
||||
void InitTerminal(void);
|
||||
|
||||
|
||||
void RxTerminalData(unsigned char Data);
|
||||
void RxTerminalBuf(unsigned char *DataBuf, int size);
|
||||
void ParseNewBuffer(void);
|
||||
void TerminalStateMachine(void);
|
||||
|
||||
void TickTerminal(void);
|
||||
void TerminalPrintString(char *str);
|
||||
void TerminalPrintChar(char byte);
|
||||
|
||||
void TerminalPrintValveStatus();
|
||||
void TerminalPrintFlowStatus();
|
||||
void TerminalPrintHygroStatus(int unit);
|
||||
|
||||
//EOF
|
||||
|
||||
699
ChaloupeLora.X/Source/Uart.c
Normal file
699
ChaloupeLora.X/Source/Uart.c
Normal file
@ -0,0 +1,699 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C code file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ¤Revision:
|
||||
000 20100616 JFM,
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
#include "Uart.h"
|
||||
#include "Internaluart.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
//#include "Watchdog.h"
|
||||
|
||||
#ifndef NO_EXTERNAL_UART
|
||||
#include "sc16IS740Driver.h"
|
||||
#endif
|
||||
|
||||
#include "digitalio.h"
|
||||
//#include "DriveProtocol.h"
|
||||
#include "terminal.h"
|
||||
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Local variables */
|
||||
|
||||
stUartData astUartData[MAX_UART_HANDLE];
|
||||
|
||||
const char *gUartStrings[MAX_UART_HANDLE] = { "PRINTF" //UART_1
|
||||
//,"CU", //UART_2
|
||||
// ,"CONSOLE" //UART_3
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Private function prototypes */
|
||||
//void _mon_putc(char c); //override from stdio to redirect stdout on uart 3B
|
||||
//void _mon_write (const char * s, unsigned int count);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void InitUart(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
InternalUartInit();
|
||||
//InitSC16S740();
|
||||
|
||||
memset(&astUartData,0,sizeof(astUartData));
|
||||
|
||||
for(i = 0; i < MAX_UART_HANDLE; i++)
|
||||
{
|
||||
astUartData[i].iDataPending = 0; //This flag is 0 when : TxPtr == RxPtr OR Uart is transmitting.
|
||||
astUartData[i].pcTxInPtr = &astUartData[i].acTxCircularBuffer[0];
|
||||
astUartData[i].pcTxOutPtr = &astUartData[i].acTxCircularBuffer[0];
|
||||
//memset(&astUartData[i].acTxCircularBuffer[0],0xDE,UART_MAX_TX_BUFF_SIZE);
|
||||
|
||||
astUartData[i].pcRxInDataPtr = astUartData[i].pcRxOutDataPtr = &astUartData[i].acRxCircularBuffer[0];
|
||||
astUartData[i].iNbRxFIFOPendingBytes = 0;
|
||||
}
|
||||
|
||||
|
||||
//This is a physical mapping of the UARTS.
|
||||
//DO NOT CHANGE assignments unless hardware changed !
|
||||
//
|
||||
astUartData[UART_1].iIsInternal = 1;
|
||||
astUartData[UART_1].iPhysicalUartPort = INTERNAL_UART_PORT_2; // (232)
|
||||
|
||||
// astUartData[UART_2].iIsInternal = 1;
|
||||
//astUartData[UART_2].iPhysicalUartPort = INTERNAL_UART_PORT_2; // (232)
|
||||
|
||||
#ifndef NO_EXTERNAL_UART
|
||||
astUartData[UART_3].iIsInternal = 0;
|
||||
astUartData[UART_3].iPhysicalUartPort = EXT_UART_1; // (SPI - 232 daughter board)
|
||||
#endif
|
||||
|
||||
setbuf(stdout,NULL); //to use printf without \r
|
||||
fflush(stdout);
|
||||
|
||||
UartOpenComPort(NETWORK_UART_PORT,9600,UART_ONE_STOP_BIT,UART_NO_PARITY); //Open console port
|
||||
#ifdef USE_PRINTF
|
||||
//UartOpenComPort(CONSOLE_UART_PORT,115200,UART_ONE_STOP_BIT,UART_NO_PARITY); //Open console port
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int UartResetPort(int p_iUartHandle)
|
||||
{
|
||||
if(p_iUartHandle > MAX_UART_HANDLE)
|
||||
return 0;
|
||||
|
||||
//reset the port data structures...
|
||||
astUartData[p_iUartHandle].iDataPending = 0; //This flag is 0 when : TxPtr == RxPtr OR Uart is transmitting.
|
||||
astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
|
||||
astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
|
||||
astUartData[p_iUartHandle].pcRxInDataPtr = astUartData[p_iUartHandle].pcRxOutDataPtr = &astUartData[p_iUartHandle].acRxCircularBuffer[0];
|
||||
astUartData[p_iUartHandle].iNbRxFIFOPendingBytes = 0;
|
||||
|
||||
if(astUartData[UART_1].iIsInternal == 1)
|
||||
{
|
||||
switch(astUartData[p_iUartHandle].iPhysicalUartPort)
|
||||
{
|
||||
case INTERNAL_UART_PORT_1:
|
||||
{
|
||||
ResetUart1();
|
||||
break;
|
||||
}
|
||||
case INTERNAL_UART_PORT_2:
|
||||
{
|
||||
ResetUart2();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef NO_EXTERNAL_UART
|
||||
switch(astUartData[p_iUartHandle].iPhysicalUartPort)
|
||||
{
|
||||
case EXT_UART_1:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int UartOpenComPort(int p_iUartHandle, int p_iBaudRate, int p_iNbStopBits, int p_iParityEnable)
|
||||
{
|
||||
int iStopbits,iParity,iRet;
|
||||
if(p_iUartHandle >= MAX_UART_HANDLE || p_iUartHandle < 0)
|
||||
return UART_INVALID_HANDLE;
|
||||
|
||||
if(astUartData[p_iUartHandle].iIsInternal == 1)
|
||||
{
|
||||
switch(p_iNbStopBits)
|
||||
{
|
||||
case UART_ONE_STOP_BIT:
|
||||
case UART_ONE_HALF_STOP_BIT: //1½ stop bits doesn't exist for internal uart
|
||||
{
|
||||
iStopbits = INT_UART_ONE_STOP_BIT;
|
||||
break;
|
||||
}
|
||||
case UART_TWO_STOP_BITS:
|
||||
{
|
||||
iStopbits = INT_UART_TWO_STOP_BITS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(p_iParityEnable)
|
||||
{
|
||||
case UART_NO_PARITY:
|
||||
{
|
||||
iParity = INT_UART_NO_PARITY;
|
||||
break;
|
||||
}
|
||||
case UART_EVEN_PARITY:
|
||||
{
|
||||
iParity = INT_UART_EVEN_PARITY;
|
||||
break;
|
||||
}
|
||||
case UART_ODD_PARTIY:
|
||||
{
|
||||
iParity = INT_UART_ODD_PARITY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iRet = OpenInternalPort(astUartData[p_iUartHandle].iPhysicalUartPort,
|
||||
p_iUartHandle,
|
||||
&astUartData[p_iUartHandle].acTxCircularBuffer[0],
|
||||
&astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1],
|
||||
p_iBaudRate,
|
||||
iStopbits,
|
||||
iParity);
|
||||
}
|
||||
#ifndef NO_EXTERNAL_UART
|
||||
else
|
||||
{
|
||||
switch(p_iNbStopBits)
|
||||
{
|
||||
case UART_ONE_STOP_BIT:
|
||||
{
|
||||
iStopbits = ONE_STOP_BIT;
|
||||
break;
|
||||
}
|
||||
case UART_ONE_HALF_STOP_BIT: //1½ stop bits doesn't exist for internal uart
|
||||
{
|
||||
iStopbits = ONE_HALF_STOP_BIT;
|
||||
break;
|
||||
}
|
||||
case UART_TWO_STOP_BITS:
|
||||
{
|
||||
iStopbits = TWO_STOP_BITS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(p_iParityEnable)
|
||||
{
|
||||
case UART_NO_PARITY:
|
||||
{
|
||||
iParity = NO_PARITY;
|
||||
break;
|
||||
}
|
||||
case UART_EVEN_PARITY:
|
||||
{
|
||||
iParity = EVEN_PARITY;
|
||||
break;
|
||||
}
|
||||
case UART_ODD_PARTIY:
|
||||
{
|
||||
iParity = ODD_PARITY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iRet = OpenExternalPort(astUartData[p_iUartHandle].iPhysicalUartPort,
|
||||
p_iUartHandle,
|
||||
&astUartData[p_iUartHandle].acTxCircularBuffer[0],
|
||||
&astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1],
|
||||
p_iBaudRate,
|
||||
iStopbits,
|
||||
iParity);
|
||||
}
|
||||
#endif
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//All the uart callback function assignment must be done here !!!
|
||||
//This must be changed if hardware changes or if port assignment is changed !!!
|
||||
//
|
||||
int UartReceiveData(int p_iUartHandle, char *p_pcBuffer, int p_iSize)
|
||||
{
|
||||
int i;
|
||||
stUartData *p_stUartDatPtr = &astUartData[p_iUartHandle];
|
||||
|
||||
if(p_iUartHandle < 0 && p_iUartHandle >= MAX_UART_HANDLE)
|
||||
{
|
||||
//TODO: Flag a logic error !
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < p_iSize; i++)
|
||||
{
|
||||
*p_stUartDatPtr->pcRxInDataPtr++ = *p_pcBuffer++;
|
||||
if(p_stUartDatPtr->pcRxInDataPtr > &p_stUartDatPtr->acRxCircularBuffer[UART_MAX_RX_BUFF_SIZE-1])
|
||||
{
|
||||
p_stUartDatPtr->pcRxInDataPtr = &p_stUartDatPtr->acRxCircularBuffer[0]; //wrap pointer
|
||||
// printf("Wrap\n");
|
||||
}
|
||||
}
|
||||
p_stUartDatPtr->iNbRxFIFOPendingBytes += p_iSize;
|
||||
|
||||
if(p_stUartDatPtr->iNbRxFIFOPendingBytes >= UART_MAX_RX_BUFF_SIZE)
|
||||
PRINTF("RX FIFO Overflow\n");
|
||||
|
||||
|
||||
/* switch(p_iUartHandle)
|
||||
{
|
||||
case UART_0:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case UART_1:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case UART_2:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case UART_3:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case UART_4:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case UART_5:
|
||||
{
|
||||
break;
|
||||
}
|
||||
} */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UartGetPendingDataSize(int iUartHandle)
|
||||
{
|
||||
stUartData *p_stUartDatPtr = &astUartData[iUartHandle];
|
||||
|
||||
if(p_stUartDatPtr->pcRxInDataPtr == p_stUartDatPtr->pcRxOutDataPtr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(p_stUartDatPtr->pcRxOutDataPtr < p_stUartDatPtr->pcRxInDataPtr)
|
||||
{
|
||||
return(p_stUartDatPtr->pcRxInDataPtr - p_stUartDatPtr->pcRxOutDataPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = &p_stUartDatPtr->acRxCircularBuffer[UART_MAX_RX_BUFF_SIZE-1] - p_stUartDatPtr->pcRxOutDataPtr;
|
||||
size += p_stUartDatPtr->pcRxInDataPtr - &p_stUartDatPtr->acRxCircularBuffer[0];
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int UartTransmitData(int p_iUartHandle, char *p_pcBuffer, int p_iSize)
|
||||
{
|
||||
int iRet = 0;
|
||||
|
||||
// Case where OutPtr < InPtr
|
||||
// * = Available space
|
||||
//
|
||||
//Top ---->|---------------|
|
||||
// | * |
|
||||
//OutPtr ->| |
|
||||
// | |
|
||||
// | (p_pcBuffer) | //Available size = (OutPtr - Top) + (Bottom - InPtr)
|
||||
// | |
|
||||
//InPtr -->| |
|
||||
// | * |
|
||||
// | * |
|
||||
//Bottom ->|---------------|
|
||||
|
||||
|
||||
// Case where OutPtr > InPtr
|
||||
// * = Available space
|
||||
//
|
||||
//Top ---->|---------------|
|
||||
// | |
|
||||
//InPtr -->| |
|
||||
// | * |
|
||||
// | * | //available size = OutPtr - InPtr
|
||||
// | * |
|
||||
//OutPtr ->| |
|
||||
// | (p_pcBuffer) |
|
||||
// | |
|
||||
//Bottom ->|---------------|
|
||||
|
||||
|
||||
//Check if data buffer fits in remaining circular buffer space
|
||||
if(astUartData[p_iUartHandle].pcTxOutPtr < astUartData[p_iUartHandle].pcTxInPtr)
|
||||
{
|
||||
//Calculate remaining buffer space and check if it's enough to fit requested data buffer
|
||||
if(p_iSize > ((astUartData[p_iUartHandle].pcTxOutPtr - &astUartData[p_iUartHandle].acTxCircularBuffer[0]) + //Outptr - Top
|
||||
(&astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1] - astUartData[p_iUartHandle].pcTxInPtr))) //Bottom - Inptr
|
||||
{
|
||||
//Drop remaining packets, flush buffer
|
||||
astUartData[p_iUartHandle].iDataPending = 0;
|
||||
astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
|
||||
astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
|
||||
return UART_BUFFER_FULL;
|
||||
}
|
||||
}
|
||||
else if(astUartData[p_iUartHandle].pcTxInPtr < astUartData[p_iUartHandle].pcTxOutPtr)
|
||||
{
|
||||
//Calculate remaining buffer space and check if it's enough to fit requested data buffer
|
||||
if(p_iSize > (astUartData[p_iUartHandle].pcTxOutPtr - astUartData[p_iUartHandle].pcTxInPtr))
|
||||
{
|
||||
//Drop remaining packets, flush buffer
|
||||
astUartData[p_iUartHandle].iDataPending = 0; //Force data pending flag to flush buffer
|
||||
astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
|
||||
astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
|
||||
return UART_BUFFER_FULL;
|
||||
}
|
||||
}
|
||||
else //OutPtr = InPtr
|
||||
{
|
||||
if(p_iSize > UART_MAX_TX_BUFF_SIZE - 1) //message is too big to fit in buffer !!!
|
||||
{
|
||||
//Drop remaining packets, flush buffer
|
||||
astUartData[p_iUartHandle].iDataPending = 0; //Force data pending flag to flush buffer
|
||||
astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
|
||||
astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
|
||||
|
||||
return UART_BUFFER_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
for(i = 0; i < p_iSize; i++)
|
||||
{
|
||||
*astUartData[p_iUartHandle].pcTxInPtr++ = *p_pcBuffer++; //fill circular buffer
|
||||
|
||||
if(astUartData[p_iUartHandle].pcTxInPtr > &astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1]) //check for wrapping
|
||||
{
|
||||
astUartData[p_iUartHandle].pcTxInPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0];
|
||||
}
|
||||
}
|
||||
|
||||
//Now flag pending data for transmission.
|
||||
astUartData[p_iUartHandle].iDataPending = 1; //The data send will start on next Main loop processing
|
||||
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//Some data has been entirely sent
|
||||
//Move output pointer
|
||||
//
|
||||
int DataSentNotification(int p_iUartHandle,int DataSize)
|
||||
{
|
||||
//Check wrapping.
|
||||
if(astUartData[p_iUartHandle].pcTxOutPtr + DataSize < &astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE])
|
||||
{
|
||||
astUartData[p_iUartHandle].pcTxOutPtr += DataSize;
|
||||
}
|
||||
else //Pointer must wrap
|
||||
{
|
||||
|
||||
//Top ------>|---------------|
|
||||
// | * |
|
||||
//Final Pos->| | // Final Pos = Top + *
|
||||
// | |
|
||||
// | (buffer) | // DataSize = & + *
|
||||
// | | // & = Bottom - OutPtr
|
||||
//OutPtr --->| | // * = DataSize - &
|
||||
// | & | // FinalPos = Top + (DataSize - (Bottom - OutPtr))
|
||||
// | & |
|
||||
//Bottom --->|---------------|
|
||||
|
||||
// if(p_iUartHandle != PRINTF_UART_PORT)
|
||||
// printf("Out wrap\r");
|
||||
|
||||
DataSize -= (&astUartData[p_iUartHandle].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE] - astUartData[p_iUartHandle].pcTxOutPtr); //p_iSize - (Bottom - OutPtr)
|
||||
|
||||
astUartData[p_iUartHandle].pcTxOutPtr = &astUartData[p_iUartHandle].acTxCircularBuffer[0] + DataSize; //Top + new p_iSize
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Check if data is pending in buffer
|
||||
if(astUartData[p_iUartHandle].pcTxOutPtr != astUartData[p_iUartHandle].pcTxInPtr)
|
||||
{
|
||||
astUartData[p_iUartHandle].iDataPending = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
astUartData[p_iUartHandle].iDataPending = 0;
|
||||
LORA_MODULE_TX_LED_PIN = LED_OFF;
|
||||
}
|
||||
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//Called by main loop. Check if any uart has data pending to be sent
|
||||
//
|
||||
int UartTick(void)
|
||||
{
|
||||
int i = 0;
|
||||
int iRet;
|
||||
int p_iSize;
|
||||
char aTempBuffer[UART_MAX_RX_BUFF_SIZE];
|
||||
|
||||
TickInternalUart();
|
||||
|
||||
//Send...
|
||||
|
||||
for(i = 0; i < MAX_UART_HANDLE; i++)
|
||||
{
|
||||
if(astUartData[i].iDataPending)
|
||||
{
|
||||
char *pcTxInPtr = astUartData[i].pcTxInPtr;
|
||||
//Check remaining data size.
|
||||
if(astUartData[i].pcTxOutPtr < pcTxInPtr)
|
||||
{
|
||||
p_iSize = pcTxInPtr - astUartData[i].pcTxOutPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_iSize = ((&astUartData[i].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE] - astUartData[i].pcTxOutPtr) +
|
||||
(pcTxInPtr - &astUartData[i].acTxCircularBuffer[0]));
|
||||
}
|
||||
|
||||
if(astUartData[i].iIsInternal) //Uart handle mapped to PIC internal uart
|
||||
{
|
||||
astUartData[i].iDataPending = 0;
|
||||
iRet = SendInternalUartData(astUartData[i].pcTxOutPtr,
|
||||
p_iSize,
|
||||
astUartData[i].iPhysicalUartPort,
|
||||
&astUartData[i].acTxCircularBuffer[0],
|
||||
&astUartData[i].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1]);
|
||||
}
|
||||
|
||||
#ifndef NO_EXTERNAL_UART
|
||||
else //mapped to external uart
|
||||
{
|
||||
astUartData[i].iDataPending = 0;
|
||||
iRet = SendExternalUartData(astUartData[i].iPhysicalUartPort, astUartData[i].pcTxOutPtr, p_iSize,&astUartData[i].acTxCircularBuffer[0], &astUartData[i].acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE-1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
//TODO: manage return values
|
||||
switch(iRet)
|
||||
{
|
||||
case UART_OK:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case UART_PORT_BUSY:
|
||||
case UART_BUFFER_FULL:
|
||||
{
|
||||
astUartData[i].iDataPending = 1;
|
||||
break;
|
||||
}
|
||||
case UART_PORT_NOT_OPENED:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Receive...
|
||||
|
||||
// int iNbPendingData = astUartData[i].iNbRxFIFOPendingBytes; //JFM 2012-09-05
|
||||
int iNbPendingData = UartGetPendingDataSize(i);
|
||||
if(iNbPendingData > 0)
|
||||
{
|
||||
int byte;
|
||||
for(byte = 0; byte < iNbPendingData; byte++)
|
||||
{
|
||||
aTempBuffer[byte] = *astUartData[i].pcRxOutDataPtr++;
|
||||
if(astUartData[i].pcRxOutDataPtr > &astUartData[i].acRxCircularBuffer[UART_MAX_RX_BUFF_SIZE-1])
|
||||
astUartData[i].pcRxOutDataPtr = &astUartData[i].acRxCircularBuffer[0]; //wrap pointer
|
||||
}
|
||||
astUartData[i].iNbRxFIFOPendingBytes -= iNbPendingData;
|
||||
|
||||
switch(i)
|
||||
{
|
||||
// case DRIVE_UART_PORT:
|
||||
// {
|
||||
// //printf("drive rx\n");
|
||||
// DriveProtocolRxData(aTempBuffer,iNbPendingData);
|
||||
// break;
|
||||
// }
|
||||
// case CU_UART_PORT:
|
||||
// {
|
||||
// CUProtocolRxData(aTempBuffer,iNbPendingData); // HCAM 20120918
|
||||
// break;
|
||||
// }
|
||||
case NETWORK_UART_PORT:
|
||||
{
|
||||
//HEARTBEAT_LED_1_TOGGLE_REG = HEARTBEAT_LED_1_TOGGLE_MASK;
|
||||
//UartTransmitData(CONSOLE_UART_PORT, aTempBuffer, iNbPendingData);//echo received character
|
||||
int i = 0;
|
||||
for(i = 0; i< iNbPendingData; i++)
|
||||
{
|
||||
ProtocolAnalyzeNewData(aTempBuffer[i]);
|
||||
//RxTerminalData(aTempBuffer[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return UART_OK;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// This function is used in the case of a large amount of data to be sent or received
|
||||
// in a process without going back to main loop.
|
||||
|
||||
void UartBlockAndTick(unsigned int TickCount)
|
||||
{
|
||||
int i;
|
||||
|
||||
// KickWatchdog();
|
||||
for(i = 0; i < TickCount; i++)
|
||||
{
|
||||
UartTick();
|
||||
}
|
||||
// KickWatchdog();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// This function is used in the case of a large amount of data to be sent or received
|
||||
// in a process without going back to main loop.
|
||||
int UartBlockUntillBufEmpty(int iUartHandle)
|
||||
{
|
||||
if(iUartHandle >= MAX_UART_HANDLE)
|
||||
return 0;
|
||||
|
||||
// KickWatchdog();
|
||||
while(astUartData[iUartHandle].iDataPending)
|
||||
{
|
||||
UartTick();
|
||||
}
|
||||
// KickWatchdog();
|
||||
return 1;
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//Overload the stdio character output routine to redirect printfs
|
||||
//
|
||||
//void _mon_putc(char c)
|
||||
//{
|
||||
// KickWatchdog();
|
||||
|
||||
// U2TXREG = c;
|
||||
// while (U2STAbits.TRMT==0);
|
||||
|
||||
|
||||
//#ifdef USE_BLOCKING_PRINTF
|
||||
// switch(CONSOLE_UART_PORT)
|
||||
// {
|
||||
// case UART_1: //(422) Uart 1B
|
||||
// {
|
||||
// if(U1MODEbits.ON == 1)
|
||||
// {
|
||||
// U1TXREG = c;
|
||||
// while (U1STAbits.TRMT==0);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// case UART_2: //(422) Uart 2A
|
||||
// {
|
||||
// if(U2MODEbits.ON == 1)
|
||||
// {
|
||||
// U2TXREG = c;
|
||||
// while (U2STAbits.TRMT==0);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
|
||||
// }
|
||||
//#else
|
||||
// UartTransmitData(PRINTF_UART_PORT, &c, 1);
|
||||
//#endif
|
||||
// UartTransmitData(CONSOLE_UART_PORT, &c, 1);
|
||||
// Nop();
|
||||
|
||||
// KickWatchdog();
|
||||
//}
|
||||
|
||||
/*
|
||||
void _mon_write (const char * s, unsigned int count)
|
||||
{
|
||||
#ifdef USE_BLOCKING_PRINTF
|
||||
int i;
|
||||
for(i = 0; i < count; i++)
|
||||
_mon_putc(*s++);
|
||||
#else
|
||||
UartTransmitData(UART_10, s, count);
|
||||
#endif
|
||||
}*/
|
||||
|
||||
//EOF
|
||||
|
||||
106
ChaloupeLora.X/Source/Uart.h
Normal file
106
ChaloupeLora.X/Source/Uart.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ¤Revision:
|
||||
000 20100616 JFM,
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
#ifndef UART_H
|
||||
#define UART_H
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
#define UART_MAX_RX_BUFF_SIZE 512
|
||||
#define UART_MAX_TX_BUFF_SIZE 1024
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
//Handles to the Uart ports as mapped physically on the CU board.
|
||||
//in comment is the physical port assigned to each handle
|
||||
//
|
||||
enum eUartHandles
|
||||
{
|
||||
UART_1, //(232) Uart 1 - Drive
|
||||
//UART_2, //(232) Uart 2 - CU
|
||||
//UART_3, // !!!EXTERNAL!!! SPI daughter board...
|
||||
MAX_UART_HANDLE,
|
||||
|
||||
INVALID_UART_HANDLE = 0xFF
|
||||
};
|
||||
|
||||
extern const char *gUartStrings[MAX_UART_HANDLE];
|
||||
|
||||
enum eUartStopBits
|
||||
{
|
||||
UART_ONE_STOP_BIT,
|
||||
UART_ONE_HALF_STOP_BIT,
|
||||
UART_TWO_STOP_BITS
|
||||
};
|
||||
enum eUartParity
|
||||
{
|
||||
UART_NO_PARITY,
|
||||
UART_EVEN_PARITY,
|
||||
UART_ODD_PARTIY
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int iIsInternal;
|
||||
int iPhysicalUartPort;
|
||||
int iDataPending; //This flag is 0 when : TxPtr == RxPtr OR Uart is transmitting.
|
||||
|
||||
char acTxCircularBuffer[UART_MAX_TX_BUFF_SIZE];
|
||||
char *pcTxInPtr;
|
||||
char *pcTxOutPtr;
|
||||
char acRxCircularBuffer[UART_MAX_RX_BUFF_SIZE];
|
||||
char *pcRxInDataPtr;
|
||||
char *pcRxOutDataPtr;
|
||||
int iNbRxFIFOPendingBytes;
|
||||
|
||||
|
||||
}stUartData;
|
||||
|
||||
enum eUartReturnValues
|
||||
{
|
||||
UART_OK = 1,
|
||||
UART_PORT_BUSY,
|
||||
UART_PORT_NOT_OPENED,
|
||||
UART_BUFFER_FULL,
|
||||
UART_INVALID_HANDLE,
|
||||
UART_INVALID_PORT
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
int UartTransmitData(int p_iUartHandle, char *p_pcBuffer, int p_iSize);
|
||||
int UartReceiveData(int p_iUartHandle, char *p_pcBuffer, int p_iSize);
|
||||
int DataSentNotification(int p_iUartHandle,int p_iDataSize);
|
||||
void InitUart(void);
|
||||
int UartOpenComPort(int p_iUartHandle, int p_iBaudRate, int p_iNbStopBits, int p_iParityEnable);
|
||||
int UartTick(void);
|
||||
void UartBlockAndTick(unsigned int TickCount);
|
||||
int UartBlockUntillBufEmpty(int iUartHandle);
|
||||
int UartGetPendingDataSize(int iUartHandle);
|
||||
int UartResetPort(int p_iUartHandle);
|
||||
|
||||
#endif
|
||||
//EOF
|
||||
|
||||
367
ChaloupeLora.X/Source/Util.c
Normal file
367
ChaloupeLora.X/Source/Util.c
Normal file
@ -0,0 +1,367 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C code file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ¤Revision:
|
||||
000 20100616 JFM,
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
#include "Util.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "PrintfServer.h"
|
||||
//#include "Watchdog.h"
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Local variables */
|
||||
#ifdef ENABLE_DEBUG_LOG
|
||||
char acDebugLog[DEBUG_LOG_SIZE][100];
|
||||
int iLogIndex = 0;
|
||||
int iWrapCntr = 0;
|
||||
#endif
|
||||
|
||||
//void _mon_putc(char c); //override from stdio to redirect stdout
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//void _mon_putc(char c)
|
||||
//{
|
||||
// TelnetPutPrintf(c);
|
||||
//}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
short SwapEndianShort(short p_sData)
|
||||
{
|
||||
return (((p_sData & 0xFF00) >> 8) | ((p_sData & 0x00FF) << 8));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int SwapEndianInt(int p_iData)
|
||||
{
|
||||
return (((p_iData & 0xFF000000) >> 24) | ((p_iData & 0x00FF0000) >> 8) | ((p_iData & 0x0000FF00) << 8) | ((p_iData & 0x000000FF) << 24));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef ENABLE_DEBUG_LOG
|
||||
char* GetDebugLogPtr(void)
|
||||
{
|
||||
char *pcPtr;
|
||||
|
||||
if(iLogIndex == DEBUG_LOG_SIZE)
|
||||
{
|
||||
iLogIndex = 0;
|
||||
iWrapCntr++;
|
||||
}
|
||||
|
||||
memset(&acDebugLog[iLogIndex][0],0,sizeof(acDebugLog[iLogIndex]));
|
||||
pcPtr = &acDebugLog[iLogIndex][0];
|
||||
|
||||
iLogIndex++;
|
||||
|
||||
return pcPtr;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void ClearDebugLog(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < DEBUG_LOG_SIZE; i++)
|
||||
{
|
||||
memset(&acDebugLog[i][0],0,sizeof(acDebugLog[i]));
|
||||
}
|
||||
|
||||
iLogIndex = 0;
|
||||
iWrapCntr = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int ConvertIntToStrLeadingZero(char* p_pcString, unsigned int p_iChar, int digit)
|
||||
{
|
||||
char temp[8];
|
||||
int i=0;
|
||||
sprintf(temp, "%X", p_iChar);
|
||||
//itoa(p_cChar,temp,radix);
|
||||
if(p_iChar < 0xF)
|
||||
{
|
||||
for (i=0; i<digit-1; i++)
|
||||
p_pcString[i] = '0'; //Add a Zero in front of the Character
|
||||
memcpy(&p_pcString[i], &temp[0], digit-i);
|
||||
}
|
||||
else if(p_iChar < 0xFF)
|
||||
{
|
||||
for (i=0; i<digit-2; i++)
|
||||
p_pcString[i] = '0'; //Add a Zero in front of the Character
|
||||
memcpy(&p_pcString[i], &temp[0], digit-i);
|
||||
}
|
||||
else if(p_iChar < 0xFFF)
|
||||
{
|
||||
for (i=0; i<digit-3; i++)
|
||||
p_pcString[i] = '0'; //Add a Zero in front of the Character
|
||||
memcpy(&p_pcString[i], &temp[0], digit-i);
|
||||
}
|
||||
else if(p_iChar < 0xFFFF)
|
||||
{
|
||||
for (i=0; i<digit-4; i++)
|
||||
p_pcString[i] = '0'; //Add a Zero in front of the Character
|
||||
memcpy(&p_pcString[i], &temp[0], digit-i);
|
||||
}
|
||||
else if(p_iChar < 0xFFFFF)
|
||||
{
|
||||
for (i=0; i<digit-5; i++)
|
||||
p_pcString[i] = '0'; //Add a Zero in front of the Character
|
||||
memcpy(&p_pcString[i], &temp[0], digit-i);
|
||||
}
|
||||
else if(p_iChar < 0xFFFFFF)
|
||||
{
|
||||
for (i=0; i<digit-6; i++)
|
||||
p_pcString[i] = '0'; //Add a Zero in front of the Character
|
||||
memcpy(&p_pcString[i], &temp[0], digit-i);
|
||||
}
|
||||
else if(p_iChar < 0xFFFFFFF)
|
||||
{
|
||||
for (i=0; i<digit-7; i++)
|
||||
p_pcString[i] = '0'; //Add a Zero in front of the Character
|
||||
memcpy(&p_pcString[i], &temp[0], digit-i);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int ConvertIntToStr(char* p_pcString, unsigned int p_iChar)
|
||||
{
|
||||
char temp[8];
|
||||
int i=0;
|
||||
|
||||
sprintf(temp, "%X", p_iChar);
|
||||
if(p_iChar < 0xF)
|
||||
{
|
||||
p_pcString[0] = temp[0];
|
||||
return 1;
|
||||
}
|
||||
else if(p_iChar < 0xFF)
|
||||
{
|
||||
for (i=0; i<2; i++)
|
||||
p_pcString[i] = temp[i];
|
||||
return 2;
|
||||
}
|
||||
else if(p_iChar < 0xFFF)
|
||||
{
|
||||
for (i=0; i<3; i++)
|
||||
p_pcString[i] = temp[i];
|
||||
return 3;
|
||||
}
|
||||
else if(p_iChar < 0xFFFF)
|
||||
{
|
||||
for (i=0; i<4; i++)
|
||||
p_pcString[i] = temp[i];
|
||||
return 4;
|
||||
}
|
||||
else if(p_iChar < 0xFFFFF)
|
||||
{
|
||||
for (i=0; i<5; i++)
|
||||
p_pcString[i] = temp[i];
|
||||
return 5;
|
||||
}
|
||||
else if(p_iChar < 0xFFFFFF)
|
||||
{
|
||||
for (i=0; i<6; i++)
|
||||
p_pcString[i] = temp[i];
|
||||
return 6;
|
||||
}
|
||||
else if(p_iChar < 0xFFFFFFF)
|
||||
{
|
||||
for (i=0; i<7; i++)
|
||||
p_pcString[i] = temp[i];
|
||||
return 7;
|
||||
}
|
||||
else if(p_iChar < 0xFFFFFFFF)
|
||||
{
|
||||
for (i=0; i<8; i++)
|
||||
p_pcString[i] = temp[i];
|
||||
return 8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int ConvertCharToStrLeadingZero(char* p_pcString, unsigned char p_cChar, int digit)
|
||||
{
|
||||
char temp[2];
|
||||
int i=0;
|
||||
sprintf(temp, "%X", p_cChar);
|
||||
//itoa(p_cChar,temp,radix);
|
||||
if(p_cChar < 0xF)
|
||||
{
|
||||
for (i=0; i<digit-1; i++)
|
||||
p_pcString[i] = '0'; //Add a Zero in front of the Character
|
||||
memcpy(&p_pcString[i], &temp[0], digit-i);
|
||||
}
|
||||
else if(p_cChar < 0xFF)
|
||||
{
|
||||
for (i=0; i<digit-2; i++)
|
||||
p_pcString[i] = '0'; //Add a Zero in front of the Character
|
||||
memcpy(&p_pcString[i], &temp[0], digit-i);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int ConvertStrToValue(char* p_pcString, int p_iSize, int p_iRadix)
|
||||
{
|
||||
int i=0;
|
||||
int j=0;
|
||||
unsigned int uiValue = 0;
|
||||
unsigned int uiFactor = 1;
|
||||
|
||||
if (p_iRadix == 16)
|
||||
{
|
||||
for (i=p_iSize-1; i>=0; i--)
|
||||
{
|
||||
if (i==p_iSize-1)
|
||||
{
|
||||
uiValue = p_pcString[i] - 0x30;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j=i; j<=p_iSize-2; j++)
|
||||
uiFactor *= 16;
|
||||
uiValue += (p_pcString[i] - 0x30) * uiFactor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if (p_iRadix == 10)
|
||||
{
|
||||
for (i=0; i<p_iSize; i++)
|
||||
{
|
||||
if (i==0)
|
||||
uiFactor = 1;
|
||||
else
|
||||
{
|
||||
for (j=0; j<i; j++)
|
||||
uiFactor *= 10;
|
||||
}
|
||||
|
||||
uiValue += (p_pcString[i] - 0x30) * uiFactor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return uiValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int ConvertCharToStr(char* p_pcString, unsigned char p_cChar)
|
||||
{
|
||||
char temp[2];
|
||||
|
||||
sprintf(temp, "%X", p_cChar);
|
||||
if(p_cChar < 0xF)
|
||||
{
|
||||
p_pcString[0] = temp[0];
|
||||
return 1;
|
||||
}
|
||||
else if(p_cChar < 0xFF)
|
||||
{
|
||||
p_pcString[0] = temp[0];
|
||||
p_pcString[1] = temp[1];
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// CRC-8 table (256 bytes)
|
||||
// Crc table for poly: $C7
|
||||
const int CRC8_TABLE[256] = { 0, 199, 73, 142, 146, 85, 219, 28, 227, 36, 170, 109, 113, 182, 56, 255,
|
||||
1, 198, 72, 143, 147, 84, 218, 29, 226, 37, 171, 108, 112, 183, 57, 254,
|
||||
2, 197, 75, 140, 144, 87, 217, 30, 225, 38, 168, 111, 115, 180, 58, 253,
|
||||
3, 196, 74, 141, 145, 86, 216, 31, 224, 39, 169, 110, 114, 181, 59, 252,
|
||||
4, 195, 77, 138, 150, 81, 223, 24, 231, 32, 174, 105, 117, 178, 60, 251,
|
||||
5, 194, 76, 139, 151, 80, 222, 25, 230, 33, 175, 104, 116, 179, 61, 250,
|
||||
6, 193, 79, 136, 148, 83, 221, 26, 229, 34, 172, 107, 119, 176, 62, 249,
|
||||
7, 192, 78, 137, 149, 82, 220, 27, 228, 35, 173, 106, 118, 177, 63, 248,
|
||||
8, 207, 65, 134, 154, 93, 211, 20, 235, 44, 162, 101, 121, 190, 48, 247,
|
||||
9, 206, 64, 135, 155, 92, 210, 21, 234, 45, 163, 100, 120, 191, 49, 246,
|
||||
10, 205, 67, 132, 152, 95, 209, 22, 233, 46, 160, 103, 123, 188, 50, 245,
|
||||
11, 204, 66, 133, 153, 94, 208, 23, 232, 47, 161, 102, 122, 189, 51, 244,
|
||||
12, 203, 69, 130, 158, 89, 215, 16, 239, 40, 166, 97, 125, 186, 52, 243,
|
||||
13, 202, 68, 131, 159, 88, 214, 17, 238, 41, 167, 96, 124, 187, 53, 242,
|
||||
14, 201, 71, 128, 156, 91, 213, 18, 237, 42, 164, 99, 127, 184, 54, 241,
|
||||
15, 200, 70, 129, 157, 90, 212, 19, 236, 43, 165, 98, 126, 185, 55, 240 };
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Function: Crc8
|
||||
//
|
||||
// Parameter: char* message
|
||||
// int number of characters in the command
|
||||
//
|
||||
// Descrip: calc the crc of a commans string
|
||||
//
|
||||
// Author: ADubreuil (12/05/06)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int Crc8(char* answer, int length)
|
||||
{
|
||||
int i,crc,key;
|
||||
|
||||
crc = 0;
|
||||
for(i=0;i<length;i++) {
|
||||
key = CRC8_TABLE[crc];
|
||||
crc = answer[i] ^ key;
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void Delay(unsigned int count)
|
||||
{
|
||||
// KickWatchdog();
|
||||
// while(--count);
|
||||
// KickWatchdog();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
//EOF
|
||||
|
||||
63
ChaloupeLora.X/Source/Util.h
Normal file
63
ChaloupeLora.X/Source/Util.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
000 20100616 HCAM
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
#ifndef _INC_UTIL_H
|
||||
#define _INC_UTIL_H
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
#ifdef ENABLE_DEBUG_LOG
|
||||
#define DEBUG_LOG_SIZE 300
|
||||
#endif
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
short SwapEndianShort(short p_sData);
|
||||
int SwapEndianEndianInt(int p_iData);
|
||||
#ifdef ENABLE_DEBUG_LOG
|
||||
char* GetDebugLogPtr(void);
|
||||
void ClearDebugLog(void);
|
||||
#endif
|
||||
//int AppendCharToStrLeadingZero(char* p_pcString, unsigned char p_cChar, int radix);
|
||||
//int AppendLongToStrLeadingZero(char* p_pcString, int p_iChar, int radix);
|
||||
int ConvertIntToStrLeadingZero(char* p_pcString, unsigned int p_iChar, int digit);
|
||||
int ConvertCharToStrLeadingZero(char* p_pcString, unsigned char p_cChar, int digit);
|
||||
int ConvertIntToStr(char* p_pcString, unsigned int p_iChar);
|
||||
int ConvertCharToStr(char* p_pcString, unsigned char p_cChar);
|
||||
unsigned int ConvertStrToValue(char* p_pcString, int p_iSize, int p_iRadix);
|
||||
int Crc8(char* answer, int length);
|
||||
void Delay(unsigned int count);
|
||||
|
||||
#endif
|
||||
//EOF
|
||||
|
||||
64
ChaloupeLora.X/Source/Watchdog.c
Normal file
64
ChaloupeLora.X/Source/Watchdog.c
Normal file
@ -0,0 +1,64 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C code file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ¤Revision:
|
||||
000 20100616 JFM,
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
#include "Watchdog.h"
|
||||
int WatchdogTriggered = 0;
|
||||
|
||||
void InitWatchdog(void)
|
||||
{
|
||||
if(RCONbits.WDTO == 1)
|
||||
{
|
||||
WatchdogTriggered = 1;
|
||||
printf("Watchdog was triggered\n");
|
||||
}
|
||||
}
|
||||
|
||||
void EnableWatchdog(void)
|
||||
{
|
||||
// WDTCONbits.ON = 1;
|
||||
WDTCONSET = _WDTCON_ON_MASK;
|
||||
}
|
||||
|
||||
void DisableWatchdog(void)
|
||||
{
|
||||
// WDTCONbits.ON = 0;
|
||||
WDTCONCLR = _WDTCON_ON_MASK;
|
||||
}
|
||||
|
||||
void KickWatchdog(void)
|
||||
{
|
||||
// WDTCONbits.WDTCLR = 1;
|
||||
WDTCONSET = 0x01;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//EOF
|
||||
|
||||
|
||||
37
ChaloupeLora.X/Source/Watchdog.h
Normal file
37
ChaloupeLora.X/Source/Watchdog.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
#ifndef WATCHDOG_H
|
||||
#define WATCHDOG_H
|
||||
|
||||
void InitWatchdog(void);
|
||||
void EnableWatchdog(void);
|
||||
void DisableWatchdog(void);
|
||||
void KickWatchdog(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//EOF
|
||||
|
||||
785
ChaloupeLora.X/Source/WiFiCtrl.c
Normal file
785
ChaloupeLora.X/Source/WiFiCtrl.c
Normal file
@ -0,0 +1,785 @@
|
||||
#include "WiFiCtrl.h"
|
||||
#include "string.h"
|
||||
#include "driver/include/nmasic.h"
|
||||
#include <stdint.h>
|
||||
//#include "socket/include/socket.h"
|
||||
#include "define.h"
|
||||
#include "Terminal.h"
|
||||
#include "driver/include/m2m_periph.h"
|
||||
#include "ProtocolDefs.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "timer.h"
|
||||
#include "BootloaderProtocol.h"
|
||||
#include "SPI_Flash.h"
|
||||
#include "FlashMapping.h"
|
||||
|
||||
|
||||
/** IP address of host. */
|
||||
uint32 gu32HostIp = 0;
|
||||
|
||||
/** Retry count. */
|
||||
uint8 gu8RetryCount = 0;
|
||||
|
||||
/** TCP client socket handlers. */
|
||||
static SOCKET tcp_client_socket = -1;
|
||||
SOCKET TerminalSocket = -1, TerminalServerSocket = -1;
|
||||
uint8 TerminalRxBuf[1024];
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
SOCKET SyslogSocket = -1, SyslogServerSocket = -1;
|
||||
uint8 SyslogRxBuf[200]; //Syslog shall not receive much data
|
||||
#endif
|
||||
|
||||
|
||||
SOCKET NetworkSocket = -1, NetworkServerSocket = -1;
|
||||
uint8 NetworkRxBuf[1024];
|
||||
|
||||
SOCKET BootloaderSocket = -1, BootloaderServerSocket = -1;
|
||||
uint8 BootloaderRxBuf[1024];
|
||||
|
||||
/** Receive buffer definition. */
|
||||
static uint8 gau8ReceivedBuffer[MAIN_WIFI_M2M_BUFFER_SIZE] = {0};
|
||||
|
||||
/** Wi-Fi status variable. */
|
||||
static bool gbConnectedWifi = false;
|
||||
|
||||
/** Get host IP status variable. */
|
||||
static bool gbHostIpByName = false;
|
||||
|
||||
/** TCP Connection status variable. */
|
||||
static bool gbTcpConnection = false;
|
||||
|
||||
/** Server host name. */
|
||||
static char server_host_name[] = MAIN_WEATHER_SERVER_NAME;
|
||||
|
||||
|
||||
tstrWifiInitParam param;
|
||||
uint8 mac_addr[6];
|
||||
uint8 u8IsMacAddrValid;
|
||||
struct sockaddr_in addr_in;
|
||||
uint32 mCurIPAddress;
|
||||
|
||||
tstrM2MIPConfig mModuleIPConfig;
|
||||
|
||||
bool mWiFiInitOK = false;
|
||||
char mWiFiState = WIFI_MODULE_OFF_STATE; //JFM wifi module is always OFF at boot...
|
||||
|
||||
|
||||
/**
|
||||
* \brief Callback function of IP address.
|
||||
*
|
||||
* \param[in] hostName Domain name.
|
||||
* \param[in] hostIp Server IP.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
static void resolve_cb(uint8 *hostName, uint32 hostIp)
|
||||
{
|
||||
gu32HostIp = hostIp;
|
||||
gbHostIpByName = true;
|
||||
printf("Host IP is %d.%d.%d.%d\r\n",
|
||||
(int)IPV4_BYTE(hostIp, 0),
|
||||
(int)IPV4_BYTE(hostIp, 1),
|
||||
(int)IPV4_BYTE(hostIp, 2),
|
||||
(int)IPV4_BYTE(hostIp, 3));
|
||||
printf("Host Name is %s\r\n", hostName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void socket_cb(SOCKET sock, uint8 u8Msg, void *pvMsg)
|
||||
{
|
||||
/* Check for socket event on TCP socket. */
|
||||
|
||||
//if(sock == TerminalSocket)
|
||||
{
|
||||
switch(u8Msg)
|
||||
{
|
||||
case SOCKET_MSG_BIND:
|
||||
{
|
||||
tstrSocketBindMsg *pstrBind = (tstrSocketBindMsg*)pvMsg;
|
||||
if(pstrBind->status == 0)
|
||||
{
|
||||
if(sock == TerminalServerSocket)
|
||||
{
|
||||
listen(TerminalServerSocket, 0);
|
||||
}
|
||||
else if(sock == SyslogServerSocket)
|
||||
{
|
||||
listen(SyslogServerSocket,0);
|
||||
}
|
||||
else if(sock == NetworkServerSocket)
|
||||
{
|
||||
listen(NetworkServerSocket,0);
|
||||
}
|
||||
else if(sock == BootloaderServerSocket)
|
||||
{
|
||||
listen(BootloaderServerSocket,0);
|
||||
printf("Bootloader server started\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Bind Failed\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCKET_MSG_LISTEN:
|
||||
{
|
||||
|
||||
tstrSocketListenMsg *pstrListen = (tstrSocketListenMsg*)pvMsg;
|
||||
if(pstrListen->status != 0)
|
||||
{
|
||||
printf("socket %d listen Failed. Error: %d\n",(int)sock, pstrListen->status);
|
||||
break;
|
||||
}
|
||||
if(sock == SyslogServerSocket)
|
||||
{
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO3,1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SOCKET_MSG_ACCEPT:
|
||||
{
|
||||
// New Socket is accepted.
|
||||
tstrSocketAcceptMsg *pstrAccept = (tstrSocketAcceptMsg *)pvMsg;
|
||||
if(pstrAccept->sock >= 0)
|
||||
{
|
||||
if(sock == TerminalServerSocket)
|
||||
{
|
||||
memset(TerminalRxBuf,0,sizeof(TerminalRxBuf));
|
||||
// Get the accepted socket.
|
||||
TerminalSocket = pstrAccept->sock;
|
||||
recv(TerminalSocket, TerminalRxBuf, sizeof(TerminalRxBuf), 0);
|
||||
SendTerminalData("Bienvenue au chalet!\nLe chalet parle en anglais comme Mr. Pepin\nIf you need help... type help\n\n",strlen("Bienvenue au chalet!\nLe chalet parle en anglais comme Mr. Pepin\nIf you need help... type help\n\n"));
|
||||
// SendSyslogData("Terminal client connected\n",strlen("Terminal client connected\n"));
|
||||
printf("Terminal client connected\n");
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,1);
|
||||
}
|
||||
else if(sock == SyslogServerSocket)
|
||||
{
|
||||
memset(SyslogRxBuf,0,sizeof(SyslogRxBuf));
|
||||
// Get the accepted socket.
|
||||
SyslogSocket = pstrAccept->sock;
|
||||
recv(SyslogSocket, SyslogRxBuf, sizeof(SyslogRxBuf), 0);
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,1);
|
||||
SendSyslogData("Syslog Welcome\n",strlen("Syslog Welcome\n"));
|
||||
}
|
||||
else if(sock == NetworkServerSocket)
|
||||
{
|
||||
memset(NetworkRxBuf,0,sizeof(NetworkRxBuf));
|
||||
// Get the accepted socket.
|
||||
NetworkSocket = pstrAccept->sock;
|
||||
recv(NetworkSocket, NetworkRxBuf, sizeof(NetworkRxBuf), 0);
|
||||
printf("Network client connected\n");
|
||||
}
|
||||
else if(sock == BootloaderServerSocket)
|
||||
{
|
||||
memset(BootloaderRxBuf,0,sizeof(BootloaderRxBuf));
|
||||
// Get the accepted socket.
|
||||
BootloaderSocket = pstrAccept->sock;
|
||||
recv(BootloaderSocket, BootloaderRxBuf, sizeof(BootloaderRxBuf), 0);
|
||||
printf("Bootloader client connected\n");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Socket %d : Accept Failed\n", sock);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
case SOCKET_MSG_RECV:
|
||||
{
|
||||
tstrSocketRecvMsg *pstrRecvMsg = (tstrSocketRecvMsg*)pvMsg;
|
||||
if((pstrRecvMsg->pu8Buffer != NULL) && (pstrRecvMsg->s16BufferSize > 0))
|
||||
{
|
||||
// Process the received message
|
||||
if(sock == TerminalSocket)
|
||||
{
|
||||
//Fwd data to Terminal...
|
||||
recv(TerminalSocket, TerminalRxBuf, sizeof(TerminalRxBuf), 0);
|
||||
RxTerminalBuf(TerminalRxBuf, pstrRecvMsg->s16BufferSize);
|
||||
|
||||
}
|
||||
else if(sock == SyslogSocket)
|
||||
{
|
||||
//Fwd data to stdin...
|
||||
recv(SyslogSocket, SyslogRxBuf, sizeof(SyslogRxBuf), 0);
|
||||
//Syslog shall ignore data...
|
||||
}
|
||||
else if(sock == NetworkSocket)
|
||||
{
|
||||
//Fwd data to Network...
|
||||
recv(NetworkSocket, NetworkRxBuf, sizeof(NetworkRxBuf), 0);
|
||||
}
|
||||
else if(sock == BootloaderSocket)
|
||||
{
|
||||
//Fwd data to Network...
|
||||
|
||||
if(recv(BootloaderSocket, BootloaderRxBuf, sizeof(BootloaderRxBuf), 0) != 0)
|
||||
{
|
||||
char toto;
|
||||
toto = 1;
|
||||
}
|
||||
BootloaderProtocolProtocolAnalyzeNewData(pstrRecvMsg->pu8Buffer, pstrRecvMsg->s16BufferSize);
|
||||
|
||||
}
|
||||
}
|
||||
else //Socket must be closed.
|
||||
{
|
||||
if(sock == TerminalSocket)
|
||||
{
|
||||
close(TerminalSocket);
|
||||
TerminalSocket = -1;
|
||||
// SendSyslogData("Terminal client disconnected\n",strlen("Terminal client disconnected\n"));
|
||||
printf("Terminal client disconnected\n");
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,0);
|
||||
}
|
||||
else if(sock == SyslogSocket)
|
||||
{
|
||||
close(SyslogSocket);
|
||||
SyslogSocket = -1;
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,0);
|
||||
}
|
||||
else if(sock == NetworkSocket)
|
||||
{
|
||||
close(NetworkSocket);
|
||||
NetworkSocket = -1;
|
||||
printf("Network client disconnected\n");
|
||||
}
|
||||
else if(sock == BootloaderSocket)
|
||||
{
|
||||
close(BootloaderSocket);
|
||||
BootloaderSocket = -1;
|
||||
printf("Bootloader client disconnected\n");
|
||||
BootloaderDeactivateBootloader();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCKET_MSG_SEND:
|
||||
{
|
||||
if(sock == SyslogSocket)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void set_dev_name_to_mac(uint8 *name, uint8 *mac_addr)
|
||||
{
|
||||
/* Name must be in the format WINC1500_00:00 */
|
||||
uint16 len;
|
||||
|
||||
// len = m2m_strlen(name);
|
||||
if (len >= 5) {
|
||||
name[len - 1] = MAIN_HEX2ASCII((mac_addr[5] >> 0) & 0x0f);
|
||||
name[len - 2] = MAIN_HEX2ASCII((mac_addr[5] >> 4) & 0x0f);
|
||||
name[len - 4] = MAIN_HEX2ASCII((mac_addr[4] >> 0) & 0x0f);
|
||||
name[len - 5] = MAIN_HEX2ASCII((mac_addr[4] >> 4) & 0x0f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Callback to get the Wi-Fi status update.
|
||||
*
|
||||
* \param[in] u8MsgType Type of Wi-Fi notification.
|
||||
* \param[in] pvMsg A pointer to a buffer containing the notification parameters.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
static void wifi_cb(uint8 u8MsgType, void *pvMsg)
|
||||
{
|
||||
switch (u8MsgType) {
|
||||
case M2M_WIFI_RESP_CON_STATE_CHANGED: {
|
||||
tstrM2mWifiStateChanged *pstrWifiState = (tstrM2mWifiStateChanged *)pvMsg;
|
||||
if (pstrWifiState->u8CurrState == M2M_WIFI_CONNECTED)
|
||||
{
|
||||
printf("Wi-Fi connected\r\n");
|
||||
|
||||
#ifndef USE_STATIC_IP
|
||||
// m2m_wifi_request_dhcp_client();
|
||||
#else
|
||||
m2m_wifi_set_static_ip(&mModuleIPConfig);
|
||||
gbConnectedWifi = true;
|
||||
mCurIPAddress = mModuleIPConfig.u32StaticIP;
|
||||
#endif
|
||||
mWiFiState = WIFI_CONNECTED_STATE;
|
||||
} else if (pstrWifiState->u8CurrState == M2M_WIFI_DISCONNECTED)
|
||||
{
|
||||
printf("Wi-Fi disconnected\r\n");
|
||||
gbConnectedWifi = false;
|
||||
mWiFiState = WIFI_DISCONNECTED_STATE;
|
||||
CloseSockets();
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO3,0);
|
||||
mCurIPAddress = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case M2M_WIFI_REQ_DHCP_CONF:
|
||||
{
|
||||
// mCurIPAddress = *(uin32*)pvMsg;
|
||||
|
||||
// unsigned char ip1,ip2,ip3,ip4;
|
||||
// ip1 = IPV4_BYTE(pu8IPAddress,0);
|
||||
// ip2 = IPV4_BYTE(pu8IPAddress,1);
|
||||
// ip3 = IPV4_BYTE(pu8IPAddress,2);
|
||||
// ip4 = IPV4_BYTE(pu8IPAddress,3);
|
||||
|
||||
|
||||
/* Turn LED0 on to declare that IP address received. */
|
||||
// printf("Wi-Fi IP is %u.%u.%u.%u\r\n", pu8IPAddress[0], pu8IPAddress[1], pu8IPAddress[2], pu8IPAddress[3]);
|
||||
gbConnectedWifi = true;
|
||||
/* Obtain the IP Address by network name */
|
||||
gethostbyname((uint8 *)server_host_name);
|
||||
break;
|
||||
}
|
||||
|
||||
case M2M_WIFI_RESP_PROVISION_INFO:
|
||||
{
|
||||
tstrM2MProvisionInfo *pstrProvInfo = (tstrM2MProvisionInfo *)pvMsg;
|
||||
printf("wifi_cb: M2M_WIFI_RESP_PROVISION_INFO.\r\n");
|
||||
|
||||
if (pstrProvInfo->u8Status == M2M_SUCCESS) {
|
||||
m2m_wifi_connect((char *)pstrProvInfo->au8SSID,
|
||||
strlen((char *)pstrProvInfo->au8SSID),
|
||||
pstrProvInfo->u8SecType,
|
||||
pstrProvInfo->au8Password,
|
||||
M2M_WIFI_CH_ALL);
|
||||
} else {
|
||||
printf("wifi_cb: Provision failed.\r\n");
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int InitWiFi()
|
||||
{
|
||||
tstrWifiInitParam param;
|
||||
int8_t ret;
|
||||
|
||||
gbTcpConnection = false;
|
||||
TimerStart(WIFI_RECONNECT_TIMER,1);
|
||||
mCurIPAddress = 0xFFFFFFFF;
|
||||
|
||||
char IP1,IP2,IP3,IP4,GW1,GW2,GW3,GW4;
|
||||
|
||||
if(SPIFlashIsPresent() == 1)
|
||||
{
|
||||
char StoredIPConfig[8];
|
||||
if(SPIFlashReadBuffer(StoredIPConfig,8,FLASH_WIFI_IP_ADDRESS) != RET_ERROR)
|
||||
{
|
||||
IP1 = StoredIPConfig[0];
|
||||
IP2 = StoredIPConfig[1];
|
||||
IP3 = StoredIPConfig[2];
|
||||
IP4 = StoredIPConfig[3];
|
||||
|
||||
GW1 = StoredIPConfig[4];
|
||||
GW2 = StoredIPConfig[5];
|
||||
GW3 = StoredIPConfig[6];
|
||||
GW4 = StoredIPConfig[7];
|
||||
|
||||
if((IP1 == (char)0xFF) && (IP2 == (char)0xFF) && (IP3 == (char)0xFF) && (IP4 == (char)0xFF) || \
|
||||
((GW1 == (char)0xFF && GW2 == (char)0xFF && GW3 == (char)0xFF && GW4 == (char)0xFF)))
|
||||
{
|
||||
IP1 = STATIC_IP_ADDRESS_1;
|
||||
IP2 = STATIC_IP_ADDRESS_2;
|
||||
IP3 = STATIC_IP_ADDRESS_3;
|
||||
IP4 = STATIC_IP_ADDRESS_4;
|
||||
|
||||
GW1 = GATEWAY_ADDRESS_1;
|
||||
GW2 = GATEWAY_ADDRESS_2;
|
||||
GW3 = GATEWAY_ADDRESS_3;
|
||||
GW4 = GATEWAY_ADDRESS_4;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IP1 = STATIC_IP_ADDRESS_1;
|
||||
IP2 = STATIC_IP_ADDRESS_2;
|
||||
IP3 = STATIC_IP_ADDRESS_3;
|
||||
IP4 = STATIC_IP_ADDRESS_4;
|
||||
|
||||
GW1 = GATEWAY_ADDRESS_1;
|
||||
GW2 = GATEWAY_ADDRESS_2;
|
||||
GW3 = GATEWAY_ADDRESS_3;
|
||||
GW4 = GATEWAY_ADDRESS_4;
|
||||
}
|
||||
|
||||
|
||||
memset(&mModuleIPConfig,0,sizeof(mModuleIPConfig));
|
||||
// mModuleIPConfig.u32StaticIP = IP_TO_U32(STATIC_IP_ADDRESS_1,STATIC_IP_ADDRESS_2,STATIC_IP_ADDRESS_3,STATIC_IP_ADDRESS_4);
|
||||
mModuleIPConfig.u32StaticIP = IP_TO_U32(IP1,IP2,IP3,IP4);
|
||||
mModuleIPConfig.u32DNS = IP_TO_U32(DEFAULT_DNS_ADD_1,DEFAULT_DNS_ADD_2,DEFAULT_DNS_ADD_3,DEFAULT_DNS_ADD_4);
|
||||
// mModuleIPConfig.u32AlternateDNS = IP_TO_U32(ALT_DNS_ADD_1,ALT_DNS_ADD_2,ALT_DNS_ADD_3,ALT_DNS_ADD_4);
|
||||
// mModuleIPConfig.u32Gateway = IP_TO_U32(GATEWAY_ADDRESS_1,GATEWAY_ADDRESS_2,GATEWAY_ADDRESS_3,GATEWAY_ADDRESS_4);
|
||||
mModuleIPConfig.u32Gateway = IP_TO_U32(GW1,GW2,GW3,GW4);
|
||||
mModuleIPConfig.u32SubnetMask = IP_TO_U32(SUBNET_MASK_1,SUBNET_MASK_2,SUBNET_MASK_3,SUBNET_MASK_4);
|
||||
|
||||
/* Initialize the BSP. */
|
||||
// nm_bsp_init();
|
||||
/* Initialize Wi-Fi parameters structure. */
|
||||
memset((uint8_t *)¶m, 0, sizeof(tstrWifiInitParam));
|
||||
/* Initialize Wi-Fi driver with data and status callbacks. */
|
||||
param.pfAppWifiCb = (void*) &wifi_cb;
|
||||
ret = m2m_wifi_init(¶m);
|
||||
if (M2M_SUCCESS != ret)
|
||||
{
|
||||
mWiFiInitOK = false;
|
||||
mWiFiState = WIFI_INIT_ERROR_STATE;
|
||||
return RET_ERROR;
|
||||
}
|
||||
mWiFiInitOK = true;
|
||||
|
||||
mWiFiState = WIFI_DISCONNECTED_STATE;
|
||||
|
||||
socketInit();
|
||||
registerSocketCallback(socket_cb, resolve_cb);
|
||||
|
||||
//Get MAC address from the module
|
||||
m2m_wifi_get_otp_mac_address(mac_addr, &u8IsMacAddrValid);
|
||||
if (!u8IsMacAddrValid) {
|
||||
m2m_wifi_set_mac_address(gau8MacAddr);
|
||||
}
|
||||
|
||||
//Get the working MAC address from driver.
|
||||
m2m_wifi_get_mac_address(gau8MacAddr);
|
||||
|
||||
//Initialize the human readable MAC address based on the working MAC
|
||||
set_dev_name_to_mac((uint8 *)gacDeviceName, gau8MacAddr);
|
||||
|
||||
//Use the MAC to define the SSID of the module
|
||||
set_dev_name_to_mac((uint8 *)gstrM2MAPConfig.au8SSID, gau8MacAddr);
|
||||
|
||||
// m2m_wifi_set_device_name((uint8 *)gacDeviceName, (uint8)m2m_strlen((uint8 *)gacDeviceName));
|
||||
|
||||
#ifdef USE_STATIC_IP
|
||||
//Use static ip --> disable dhcp client before connecting
|
||||
m2m_wifi_enable_dhcp(0);
|
||||
#endif
|
||||
if(m2m_wifi_connect(HOME_AP_NAME,sizeof(HOME_AP_NAME),HOME_AP_SEC_TYPE,HOME_AP_PWD,M2M_WIFI_CH_ALL) != M2M_SUCCESS)
|
||||
{
|
||||
//wifi connect error...
|
||||
printf("error");
|
||||
}
|
||||
|
||||
tstrPerphInitParam tst;
|
||||
|
||||
m2m_periph_init(&tst);
|
||||
|
||||
//Set all IOs as inputs except the LED (IO3)..
|
||||
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO3,1);
|
||||
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO4,1);
|
||||
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO15,1);
|
||||
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO16,0);
|
||||
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO18,0);
|
||||
// m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO6,0);
|
||||
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO3,0);
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,0);
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO15,0);
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO16,0);
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO18,0);
|
||||
// m2m_periph_gpio_set_val(M2M_PERIPH_GPIO6,0);
|
||||
|
||||
|
||||
TimerStart(WIFI_RECONNECT_TIMER,WIFI_CONNECT_TIMEOUT);
|
||||
|
||||
|
||||
// m2m_wifi_start_provision_mode((tstrM2MAPConfig *)&gstrM2MAPConfig, (char *)gacHttpProvDomainName, 1);
|
||||
// printf("Provision Mode started.\r\nConnect to [%s] via AP[%s] and fill up the page.\r\n",
|
||||
// MAIN_HTTP_PROV_SERVER_DOMAIN_NAME,
|
||||
// gstrM2MAPConfig.au8SSID);
|
||||
}
|
||||
|
||||
int TurnOFFWiFi()
|
||||
{
|
||||
int shit;
|
||||
|
||||
CloseSockets();
|
||||
socketDeinit();
|
||||
m2m_wifi_disconnect();
|
||||
m2m_wifi_deinit(&shit);
|
||||
|
||||
WIFI_CHP_EN_PIN = 0;
|
||||
WIFI_CHP_RST_PIN = 0;
|
||||
mWiFiInitOK = false;
|
||||
gbConnectedWifi = false;
|
||||
HEARTBEAT_LED_2_PIN = LED_OFF;
|
||||
|
||||
// WIFI
|
||||
mWiFiState = WIFI_MODULE_OFF_STATE;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int CloseSockets()
|
||||
{
|
||||
gbTcpConnection = false;
|
||||
close(TerminalServerSocket);
|
||||
if(TerminalSocket != -1)
|
||||
{
|
||||
close(TerminalSocket);
|
||||
}
|
||||
|
||||
close(NetworkServerSocket);
|
||||
if(NetworkSocket != -1)
|
||||
{
|
||||
close(NetworkSocket);
|
||||
}
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
close(SyslogServerSocket);
|
||||
if(SyslogSocket != -1)
|
||||
{
|
||||
close(SyslogSocket);
|
||||
}
|
||||
#endif
|
||||
|
||||
close(BootloaderServerSocket);
|
||||
if(BootloaderSocket != -1)
|
||||
{
|
||||
close(BootloaderSocket);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char GetWiFiSate()
|
||||
{
|
||||
return mWiFiState;
|
||||
}
|
||||
|
||||
void TickWiFi()
|
||||
{
|
||||
if(mWiFiInitOK == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(mWiFiState == WIFI_DISCONNECTED_STATE && gbConnectedWifi == false)//we should be connected.. if the timer is expired, retry
|
||||
{
|
||||
if(IsTimerExpired(WIFI_RECONNECT_TIMER))
|
||||
{
|
||||
//m2m_wifi_disconnect();
|
||||
m2m_wifi_connect(HOME_AP_NAME,sizeof(HOME_AP_NAME),HOME_AP_SEC_TYPE,HOME_AP_PWD,M2M_WIFI_CH_ALL);
|
||||
TimerStart(WIFI_RECONNECT_TIMER,WIFI_CONNECT_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
// if(IsTimerExpired(WIFI_TICK_TIMER))
|
||||
// {
|
||||
m2m_wifi_handle_events();
|
||||
// TimerStart(WIFI_TICK_TIMER,1);
|
||||
// }
|
||||
|
||||
if (gbConnectedWifi && !gbTcpConnection)
|
||||
{
|
||||
|
||||
|
||||
OpenTerminalServer();
|
||||
//OpenNetworkServer();
|
||||
// OpenBootloaderServer();
|
||||
// BootloaderActivateBootloader();
|
||||
#ifdef USE_SYSLOG
|
||||
OpenSyslogServer();
|
||||
#endif
|
||||
gbTcpConnection = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Terminal server implementation
|
||||
|
||||
int OpenTerminalServer()
|
||||
{
|
||||
struct sockaddr_in strAddr;
|
||||
|
||||
TerminalServerSocket = socket(AF_INET, SOCK_STREAM,0);
|
||||
uint16 TerminalPort = TERMINAL_SERVER_PORT;
|
||||
if(TerminalServerSocket >= 0)
|
||||
{
|
||||
strAddr.sin_family = AF_INET;
|
||||
strAddr.sin_port = _htons(TerminalPort);
|
||||
strAddr.sin_addr.s_addr = 0;
|
||||
|
||||
bind(TerminalServerSocket, (struct sockaddr*)&strAddr, sizeof(struct sockaddr_in));
|
||||
return RET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
void SendTerminalData(uint8 *data, int size)
|
||||
{
|
||||
if(TerminalSocket != -1)
|
||||
{
|
||||
send(TerminalSocket,data,size,0);
|
||||
recv(TerminalSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
|
||||
}
|
||||
}
|
||||
void SentTerminalByte(uint8 data)
|
||||
{
|
||||
if(TerminalSocket != -1)
|
||||
{
|
||||
send(TerminalSocket,&data,1,0);
|
||||
recv(TerminalSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
|
||||
}
|
||||
}
|
||||
|
||||
int OpenNetworkServer()
|
||||
{
|
||||
struct sockaddr_in strAddr;
|
||||
|
||||
NetworkServerSocket = socket(AF_INET, SOCK_STREAM,0);
|
||||
uint16 ServerPort = NETWORK_SERVER_PORT;
|
||||
if(NetworkServerSocket >= 0)
|
||||
{
|
||||
strAddr.sin_family = AF_INET;
|
||||
strAddr.sin_port = _htons(ServerPort);
|
||||
strAddr.sin_addr.s_addr = 0;
|
||||
|
||||
bind(NetworkServerSocket, (struct sockaddr*)&strAddr, sizeof(struct sockaddr_in));
|
||||
return RET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
void SendNetworkData(uint8 *data, int size)
|
||||
{
|
||||
if(NetworkSocket != -1)
|
||||
{
|
||||
send(NetworkSocket,data,size,0);
|
||||
recv(NetworkSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
|
||||
}
|
||||
}
|
||||
void SentNetworkByte(uint8 data)
|
||||
{
|
||||
if(NetworkSocket != -1)
|
||||
{
|
||||
send(NetworkSocket,&data,1,0);
|
||||
recv(NetworkSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
|
||||
}
|
||||
}
|
||||
|
||||
//Printf Server Implementation
|
||||
#ifdef USE_SYSLOG
|
||||
int OpenSyslogServer()
|
||||
{
|
||||
struct sockaddr_in strAddr;
|
||||
|
||||
SyslogServerSocket = socket(AF_INET, SOCK_STREAM,0);
|
||||
uint16 ServerPort = SYSLOG_SERVER_PORT;
|
||||
if(SyslogServerSocket >= 0)
|
||||
{
|
||||
strAddr.sin_family = AF_INET;
|
||||
strAddr.sin_port = _htons(ServerPort);
|
||||
strAddr.sin_addr.s_addr = 0;
|
||||
|
||||
bind(SyslogServerSocket, (struct sockaddr*)&strAddr, sizeof(struct sockaddr_in));
|
||||
return RET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
void SendSyslogData(uint8 *data, int size)
|
||||
{
|
||||
if(SyslogSocket != -1);
|
||||
{
|
||||
send(SyslogSocket,data,size,0);
|
||||
recv(SyslogSocket,SyslogRxBuf,sizeof(SyslogRxBuf),0);
|
||||
}
|
||||
}
|
||||
void SendSyslogByte(uint8 data)
|
||||
{
|
||||
if(SyslogSocket != -1)
|
||||
{
|
||||
send(SyslogSocket,&data,1,0);
|
||||
recv(SyslogSocket,SyslogRxBuf,sizeof(SyslogRxBuf),0);
|
||||
}
|
||||
}
|
||||
|
||||
int IsSyslogClientConnected()
|
||||
{
|
||||
if(SyslogSocket == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int OpenBootloaderServer()
|
||||
{
|
||||
struct sockaddr_in strAddr;
|
||||
|
||||
BootloaderServerSocket = socket(AF_INET, SOCK_STREAM,0);
|
||||
uint16 ServerPort = BOOTLOADER_SERVER_PORT;
|
||||
if(BootloaderServerSocket >= 0)
|
||||
{
|
||||
strAddr.sin_family = AF_INET;
|
||||
strAddr.sin_port = _htons(ServerPort);
|
||||
strAddr.sin_addr.s_addr = 0;
|
||||
|
||||
bind(BootloaderServerSocket, (struct sockaddr*)&strAddr, sizeof(struct sockaddr_in));
|
||||
return RET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
int CloseBootloaderServer()
|
||||
{
|
||||
close(BootloaderServerSocket);
|
||||
BootloaderServerSocket = -1;
|
||||
if(BootloaderSocket != -1)
|
||||
{
|
||||
close(BootloaderSocket);
|
||||
BootloaderSocket = -1;
|
||||
}
|
||||
}
|
||||
void SendBootloaderData(uint8 *data, int size)
|
||||
{
|
||||
if(BootloaderSocket != -1);
|
||||
{
|
||||
send(BootloaderSocket,data,size,0);
|
||||
recv(BootloaderSocket,SyslogRxBuf,sizeof(SyslogRxBuf),0);
|
||||
}
|
||||
}
|
||||
void SendSBootloaderByte(uint8 data)
|
||||
{
|
||||
if(BootloaderSocket != -1)
|
||||
{
|
||||
send(BootloaderSocket,&data,1,0);
|
||||
recv(BootloaderSocket,SyslogRxBuf,sizeof(SyslogRxBuf),0);
|
||||
}
|
||||
}
|
||||
|
||||
int IsBootloaderClientConnected()
|
||||
{
|
||||
if(BootloaderSocket == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
264
ChaloupeLora.X/Source/WiFiCtrl.h
Normal file
264
ChaloupeLora.X/Source/WiFiCtrl.h
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* File: WiFiCtrl.h
|
||||
* Author: JF
|
||||
*
|
||||
* Created on December 8, 2018, 6:52 AM
|
||||
*/
|
||||
|
||||
#ifndef WIFICTRL_H
|
||||
#define WIFICTRL_H
|
||||
|
||||
#include "driver/include/m2m_wifi.h"
|
||||
#include "socket/include/socket.h"
|
||||
|
||||
/*!
|
||||
* Used for code portability.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @typedef void (*tpfNmBspIsr) (void);
|
||||
* @brief Pointer to function.\n
|
||||
* Used as a data type of ISR function registered by \ref nm_bsp_register_isr
|
||||
* @return None
|
||||
*/
|
||||
typedef void (*tpfNmBspIsr)(void);
|
||||
|
||||
/*!
|
||||
* @ingroup DataTypes
|
||||
* @typedef unsigned char uint8;
|
||||
* @brief Range of values between 0 to 255
|
||||
*/
|
||||
typedef unsigned char uint8;
|
||||
|
||||
/*!
|
||||
* @ingroup DataTypes
|
||||
* @typedef unsigned short uint16;
|
||||
* @brief Range of values between 0 to 65535
|
||||
*/
|
||||
typedef unsigned short uint16;
|
||||
|
||||
/*!
|
||||
* @ingroup Data Types
|
||||
* @typedef unsigned long uint32;
|
||||
* @brief Range of values between 0 to 4294967295
|
||||
*/
|
||||
typedef unsigned long uint32;
|
||||
|
||||
|
||||
/*!
|
||||
* @ingroup Data Types
|
||||
* @typedef signed char sint8;
|
||||
* @brief Range of values between -128 to 127
|
||||
*/
|
||||
typedef signed char sint8;
|
||||
|
||||
/*!
|
||||
* @ingroup DataTypes
|
||||
* @typedef signed short sint16;
|
||||
* @brief Range of values between -32768 to 32767
|
||||
*/
|
||||
typedef signed short sint16;
|
||||
|
||||
/*!
|
||||
* @ingroup DataTypes
|
||||
* @typedef signed long sint32;
|
||||
* @brief Range of values between -2147483648 to 2147483647
|
||||
*/
|
||||
|
||||
typedef signed long sint32;
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int InitWiFi();
|
||||
void TickWiFi();
|
||||
int TurnOFFWiFi();
|
||||
int CloseSockets();
|
||||
char GetWiFiSate();
|
||||
|
||||
int OpenTerminalServer();
|
||||
void SendTerminalData(uint8 *data, int size);
|
||||
void SentTerminalByte(uint8 data);
|
||||
|
||||
int OpenNetworkServer();
|
||||
void SendNetworkData(uint8 *data, int size);
|
||||
void SentNetworkByte(uint8 data);
|
||||
|
||||
int OpenSyslogServer();
|
||||
void SendSyslogData(uint8 *data, int size);
|
||||
void SendSyslogByte(uint8 data);
|
||||
int IsSyslogClientConnected();
|
||||
|
||||
int OpenBootloaderServer();
|
||||
int CloseBootloaderServer();
|
||||
void SendBootloaderData(uint8 *data, int size);
|
||||
void SendBootloaderByte(uint8 data);
|
||||
int IsBootloaderClientConnected();
|
||||
|
||||
//#define USE_STATIC_IP
|
||||
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
//<h> General network settings in AP (access point) mode
|
||||
// <s> Network SSID
|
||||
// <id> app_main_m2m_device_name
|
||||
#ifndef MAIN_M2M_SSID
|
||||
#define MAIN_M2M_SSID "WINC3400_00:00"
|
||||
#endif
|
||||
|
||||
// <o> Security type
|
||||
// <1=> Wi-Fi network is not secured
|
||||
// <2=> WPA/WPA2 personal(PSK)
|
||||
// <3=> WEP (40 or 104) OPEN OR SHARED
|
||||
// <4=> WPA/WPA2 Enterprise.IEEE802.1x
|
||||
// <id> app_main_m2m_ap_sec
|
||||
#ifndef MAIN_M2M_AP_SEC
|
||||
#define MAIN_M2M_AP_SEC 1
|
||||
#endif
|
||||
|
||||
// <s> Security key
|
||||
// <id> app_main_m2m_ap_key
|
||||
#ifndef MAIN_M2M_AP_KEY
|
||||
#define MAIN_M2M_AP_KEY "12345FFFFF"
|
||||
#endif
|
||||
|
||||
// <o> SSID mode
|
||||
// <0=>SSID is visible to others
|
||||
// <1=>SSID is hidden
|
||||
// <id> app_main_m2m_ap_ssid_mode
|
||||
#ifndef MAIN_M2M_AP_SSID_MODE
|
||||
#define MAIN_M2M_AP_SSID_MODE 0
|
||||
#endif
|
||||
//</h>
|
||||
//<h> DHCP server IP address in AP (access point) mode
|
||||
// <o> DHCP server IP address 1 <0-255>
|
||||
// <id> app_ip_address_1
|
||||
#ifndef DHCP_IP_ADDRESS_1
|
||||
#define DHCP_IP_ADDRESS_1 192
|
||||
#endif
|
||||
|
||||
// <o> DHCP server IP address 2 <0-255>
|
||||
// <id> app_ip_address_2
|
||||
#ifndef DHCP_IP_ADDRESS_2
|
||||
#define DHCP_IP_ADDRESS_2 168
|
||||
#endif
|
||||
|
||||
// <o> DHCP server IP address 3 <0-255>
|
||||
// <id> app_ip_address_3
|
||||
#ifndef DHCP_IP_ADDRESS_3
|
||||
#define DHCP_IP_ADDRESS_3 50
|
||||
#endif
|
||||
|
||||
// <o> DHCP server IP address 4 <0-255>
|
||||
// <id> app_ip_address_4
|
||||
#ifndef DHCP_IP_ADDRESS_4
|
||||
#define DHCP_IP_ADDRESS_4 1
|
||||
#endif
|
||||
//</h>
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
//Acces Point settings
|
||||
#define HOME_AP_SEC_TYPE M2M_WIFI_SEC_WPA_PSK
|
||||
//#define HOME_AP_NAME "ImprVEmard"
|
||||
//#define HOME_AP_PWD "12345fffff"
|
||||
|
||||
#define HOME_AP_NAME "ChaletVilleEmard"
|
||||
//#define HOME_AP_NAME "ElRouteurDuChalet"
|
||||
//#define HOME_AP_NAME "LeChalet"
|
||||
#define HOME_AP_PWD "Evinrude30"
|
||||
|
||||
#define TERMINAL_SERVER_PORT 85
|
||||
#define NETWORK_SERVER_PORT 86
|
||||
#define SYSLOG_SERVER_PORT 87
|
||||
#define BOOTLOADER_SERVER_PORT 99
|
||||
|
||||
#define AUTH_CREDENTIALS {M2M_802_1X_USR_NAME, M2M_802_1X_PWD }
|
||||
|
||||
//Module Static IP settings
|
||||
#define STATIC_IP_ADDRESS_1 192
|
||||
#define STATIC_IP_ADDRESS_2 168
|
||||
#define STATIC_IP_ADDRESS_3 30
|
||||
#define STATIC_IP_ADDRESS_4 127
|
||||
|
||||
#define GATEWAY_ADDRESS_1 192
|
||||
#define GATEWAY_ADDRESS_2 168
|
||||
#define GATEWAY_ADDRESS_3 30
|
||||
#define GATEWAY_ADDRESS_4 1
|
||||
|
||||
#define DEFAULT_DNS_ADD_1 8
|
||||
#define DEFAULT_DNS_ADD_2 8
|
||||
#define DEFAULT_DNS_ADD_3 8
|
||||
#define DEFAULT_DNS_ADD_4 8
|
||||
|
||||
#define ALT_DNS_ADD_1 8
|
||||
#define ALT_DNS_ADD_2 8
|
||||
#define ALT_DNS_ADD_3 4
|
||||
#define ALT_DNS_ADD_4 4
|
||||
|
||||
#define SUBNET_MASK_1 255
|
||||
#define SUBNET_MASK_2 255
|
||||
#define SUBNET_MASK_3 255
|
||||
#define SUBNET_MASK_4 0
|
||||
|
||||
#define IP_TO_U32(add1,add2,add3,add4) (((add4<<24)&0xFF000000) | ((add3<<16)&0x00FF0000) | ((add2<<8)&0x0000FF00) | (add1&0x000000FF))
|
||||
|
||||
/** Using broadcast address for simplicity. */
|
||||
#define MAIN_SERVER_PORT (80)
|
||||
|
||||
/** Using IP address. */
|
||||
#define IPV4_BYTE(val, index) ((val >> (index * 8)) & 0xFF)
|
||||
|
||||
/** Send buffer of TCP socket. */
|
||||
#define MAIN_PREFIX_BUFFER "GET /data/2.5/weather?q="
|
||||
#define MAIN_POST_BUFFER \
|
||||
"&mode=xml&units=metric&appid=c592e14137c3471fa9627b44f6649db4 HTTP/1.1\r\nHost: " \
|
||||
"api.openweathermap.org\r\nAccept: */*\r\n\r\n"
|
||||
/** Weather information provider server. */
|
||||
#define MAIN_WEATHER_SERVER_NAME "openweathermap.org"
|
||||
|
||||
/** Input City Name. */
|
||||
#define MAIN_CITY_NAME "london"
|
||||
|
||||
/** Receive buffer size. */
|
||||
#define MAIN_WIFI_M2M_BUFFER_SIZE 1024
|
||||
|
||||
#define MAIN_M2M_DHCP_SERVER_IP \
|
||||
{ \
|
||||
DHCP_IP_ADDRESS_1, DHCP_IP_ADDRESS_2, DHCP_IP_ADDRESS_3, DHCP_IP_ADDRESS_4 \
|
||||
}
|
||||
#define MAIN_HTTP_PROV_SERVER_DOMAIN_NAME "JF.com"
|
||||
|
||||
#define MAIN_MAC_ADDRESS \
|
||||
{ \
|
||||
0xf8, 0xf0, 0x05, 0x45, 0xD4, 0x84 \
|
||||
}
|
||||
|
||||
#define MAIN_HEX2ASCII(x) (((x) >= 10) ? (((x)-10) + 'A') : ((x) + '0'))
|
||||
|
||||
#define TEMPERATURE_ABS(a) (((a) > 0) ? (a) : -(a))
|
||||
|
||||
static tstrM2MAPConfig gstrM2MAPConfig = {MAIN_M2M_SSID,
|
||||
1,
|
||||
0,
|
||||
sizeof(MAIN_M2M_AP_KEY) - 1,
|
||||
MAIN_M2M_AP_KEY,
|
||||
MAIN_M2M_AP_SEC,
|
||||
MAIN_M2M_AP_SSID_MODE,
|
||||
MAIN_M2M_DHCP_SERVER_IP};
|
||||
|
||||
static const char gacHttpProvDomainName[] = MAIN_HTTP_PROV_SERVER_DOMAIN_NAME;
|
||||
|
||||
static uint8 gau8MacAddr[] = MAIN_MAC_ADDRESS;
|
||||
static sint8 gacDeviceName[] = MAIN_M2M_SSID;
|
||||
|
||||
#define MAIN_WAITING_TIME 3000
|
||||
#define MAIN_RETRY_COUNT 10
|
||||
|
||||
extern SOCKET TerminalSocket;
|
||||
|
||||
|
||||
#endif /* WIFICTRL_H */
|
||||
|
||||
94
ChaloupeLora.X/Source/checksum.h
Normal file
94
ChaloupeLora.X/Source/checksum.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Library: libcrc
|
||||
* File: include/checksum.h
|
||||
* Author: Lammert Bies
|
||||
*
|
||||
* This file is licensed under the MIT License as stated below
|
||||
*
|
||||
* Copyright (c) 1999-2016 Lammert Bies
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Description
|
||||
* -----------
|
||||
* The headerfile include/checksum.h contains the definitions and prototypes
|
||||
* for routines that can be used to calculate several kinds of checksums.
|
||||
*/
|
||||
|
||||
#ifndef DEF_LIBCRC_CHECKSUM_H
|
||||
#define DEF_LIBCRC_CHECKSUM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* #define CRC_POLY_xxxx
|
||||
*
|
||||
* The constants of the form CRC_POLY_xxxx define the polynomials for some well
|
||||
* known CRC calculations.
|
||||
*/
|
||||
|
||||
#define CRC_POLY_16 0xA001
|
||||
#define CRC_POLY_32 0xEDB88320L
|
||||
#define CRC_POLY_CCITT 0x1021
|
||||
#define CRC_POLY_DNP 0xA6BC
|
||||
#define CRC_POLY_KERMIT 0x8408
|
||||
#define CRC_POLY_SICK 0x8005
|
||||
|
||||
/*
|
||||
* #define CRC_START_xxxx
|
||||
*
|
||||
* The constants of the form CRC_START_xxxx define the values that are used for
|
||||
* initialization of a CRC value for common used calculation methods.
|
||||
*/
|
||||
|
||||
#define CRC_START_8 0x00
|
||||
#define CRC_START_16 0x0000
|
||||
#define CRC_START_MODBUS 0xFFFF
|
||||
#define CRC_START_XMODEM 0x0000
|
||||
#define CRC_START_CCITT_1D0F 0x1D0F
|
||||
#define CRC_START_CCITT_FFFF 0xFFFF
|
||||
#define CRC_START_KERMIT 0x0000
|
||||
#define CRC_START_SICK 0x0000
|
||||
#define CRC_START_DNP 0x0000
|
||||
#define CRC_START_32 0xFFFFFFFFL
|
||||
|
||||
/*
|
||||
* Prototype list of global functions
|
||||
*/
|
||||
|
||||
unsigned char * checksum_NMEA( const unsigned char *input_str, unsigned char *result );
|
||||
uint8_t crc_8( const unsigned char *input_str, size_t num_bytes );
|
||||
uint16_t crc_16( const unsigned char *input_str, size_t num_bytes );
|
||||
uint32_t crc_32( const unsigned char *input_str, size_t num_bytes );
|
||||
uint16_t crc_ccitt_1d0f( const unsigned char *input_str, size_t num_bytes );
|
||||
uint16_t crc_ccitt_ffff( const unsigned char *input_str, size_t num_bytes );
|
||||
uint16_t crc_dnp( const unsigned char *input_str, size_t num_bytes );
|
||||
uint16_t crc_kermit( const unsigned char *input_str, size_t num_bytes );
|
||||
uint16_t crc_modbus( const unsigned char *input_str, size_t num_bytes );
|
||||
uint16_t crc_sick( const unsigned char *input_str, size_t num_bytes );
|
||||
uint16_t crc_xmodem( const unsigned char *input_str, size_t num_bytes );
|
||||
uint8_t update_crc_8( uint8_t crc, unsigned char c );
|
||||
uint16_t update_crc_16( uint16_t crc, unsigned char c );
|
||||
uint32_t update_crc_32( uint32_t crc, unsigned char c );
|
||||
uint16_t update_crc_ccitt( uint16_t crc, unsigned char c );
|
||||
uint16_t update_crc_dnp( uint16_t crc, unsigned char c );
|
||||
uint16_t update_crc_kermit( uint16_t crc, unsigned char c );
|
||||
uint16_t update_crc_sick( uint16_t crc, unsigned char c, unsigned char prev_byte );
|
||||
|
||||
#endif // DEF_LIBCRC_CHECKSUM_H
|
||||
131
ChaloupeLora.X/Source/crc32.c
Normal file
131
ChaloupeLora.X/Source/crc32.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Library: libcrc
|
||||
* File: src/crc32.c
|
||||
* Author: Lammert Bies
|
||||
*
|
||||
* This file is licensed under the MIT License as stated below
|
||||
*
|
||||
* Copyright (c) 1999-2016 Lammert Bies
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Description
|
||||
* -----------
|
||||
* The source file src/crc32.c contains the routines which are needed to
|
||||
* calculate a 32 bit CRC value of a sequence of bytes.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "checksum.h"
|
||||
|
||||
static void init_crc32_tab( void );
|
||||
|
||||
static bool crc_tab32_init = false;
|
||||
static uint32_t crc_tab32[256];
|
||||
|
||||
/*
|
||||
* uint32_t crc_32( const unsigned char *input_str, size_t num_bytes );
|
||||
*
|
||||
* The function crc_32() calculates in one pass the common 32 bit CRC value for
|
||||
* a byte string that is passed to the function together with a parameter
|
||||
* indicating the length.
|
||||
*/
|
||||
|
||||
uint32_t crc_32( const unsigned char *input_str, size_t num_bytes ) {
|
||||
|
||||
uint32_t crc;
|
||||
uint32_t tmp;
|
||||
uint32_t long_c;
|
||||
const unsigned char *ptr;
|
||||
size_t a;
|
||||
|
||||
if ( ! crc_tab32_init ) init_crc32_tab();
|
||||
|
||||
crc = CRC_START_32;
|
||||
ptr = input_str;
|
||||
|
||||
if ( ptr != NULL ) for (a=0; a<num_bytes; a++) {
|
||||
|
||||
long_c = 0x000000FFL & (uint32_t) *ptr;
|
||||
tmp = crc ^ long_c;
|
||||
crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
crc ^= 0xffffffffL;
|
||||
|
||||
return crc & 0xffffffffL;
|
||||
|
||||
} /* crc_32 */
|
||||
|
||||
/*
|
||||
* uint32_t update_crc_32( uint32_t crc, unsigned char c );
|
||||
*
|
||||
* The function update_crc_32() calculates a new CRC-32 value based on the
|
||||
* previous value of the CRC and the next byte of the data to be checked.
|
||||
*/
|
||||
|
||||
uint32_t update_crc_32( uint32_t crc, unsigned char c ) {
|
||||
|
||||
uint32_t tmp;
|
||||
uint32_t long_c;
|
||||
|
||||
long_c = 0x000000ffL & (uint32_t) c;
|
||||
|
||||
if ( ! crc_tab32_init ) init_crc32_tab();
|
||||
|
||||
tmp = crc ^ long_c;
|
||||
crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];
|
||||
|
||||
return crc & 0xffffffffL;;
|
||||
|
||||
} /* update_crc_32 */
|
||||
|
||||
/*
|
||||
* static void init_crc32_tab( void );
|
||||
*
|
||||
* For optimal speed, the CRC32 calculation uses a table with pre-calculated
|
||||
* bit patterns which are used in the XOR operations in the program. This table
|
||||
* is generated once, the first time the CRC update routine is called.
|
||||
*/
|
||||
|
||||
static void init_crc32_tab( void ) {
|
||||
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t crc;
|
||||
|
||||
for (i=0; i<256; i++) {
|
||||
|
||||
crc = i;
|
||||
|
||||
for (j=0; j<8; j++) {
|
||||
|
||||
if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ CRC_POLY_32;
|
||||
else crc = crc >> 1;
|
||||
}
|
||||
|
||||
crc_tab32[i] = crc;
|
||||
}
|
||||
|
||||
crc_tab32_init = true;
|
||||
|
||||
} /* init_crc32_tab */
|
||||
253
ChaloupeLora.X/Source/define.h
Normal file
253
ChaloupeLora.X/Source/define.h
Normal file
@ -0,0 +1,253 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/* ¤Revision:
|
||||
000 20100616 HCAM,
|
||||
Original version.
|
||||
|
||||
|
||||
,----.. ,----..
|
||||
/ / \ / / \ ,--,
|
||||
| : : __ ,-. ,---. | : : ,--.'| ,---,
|
||||
. | ;. / ,' ,'/ /| ' ,'\ .--.--. . | ;. / | |, ,-+-. / |
|
||||
. ; /--` ' | |' | / / | / / ' . ; /--` `--'_ ,--.'|' |
|
||||
; | ; __ | | ,'. ; ,. :| : /`./ ; | ; __ ,' ,'| | | ,"' |
|
||||
| : |.' .'' : / ' | |: :| : ;_ | : |.' .'' | | | | / | |
|
||||
. | '_.' :| | ' ' | .; : \ \ `. . | '_.' :| | : | | | | |
|
||||
' ; : \ |; : | | : | `----. \ ' ; : \ |' : |__ | | | |/
|
||||
' | '/ .'| , ; \ \ / / /`--' / ' | '/ .'| | '.'|| | |--'
|
||||
| : / ---' `----' '--'. / | : / ; : ;| |/
|
||||
\ \ .' `--'---' \ \ .' | , / '---'
|
||||
`---` `---` ---`-'
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************** NOTES ***************************************
|
||||
-> Timers assignment <-
|
||||
|
||||
- Timer1 used by TCP Stack (tick.c)
|
||||
- Timer2 used by general timer module (timer.c) (see GP_TIMER_USE_TIMER_X definition below)
|
||||
- timer3 used by input capture to detect PWM
|
||||
- timer4 used by hall acquisition module (HallAcquisition.c)
|
||||
- timer5 used by FPGAInterface to time-base SPI the transfer to the FPGA
|
||||
|
||||
|
||||
-> Interrupt priority assignment <-
|
||||
|
||||
Priority.SubPriority - Assignment
|
||||
HIGHEST
|
||||
7.3
|
||||
7.2
|
||||
7.1
|
||||
7.0
|
||||
6.3
|
||||
6.2
|
||||
6.1
|
||||
6.0
|
||||
5.3
|
||||
5.2
|
||||
5.1
|
||||
5.0
|
||||
4.3
|
||||
4.2
|
||||
4.1
|
||||
4.0
|
||||
3.3
|
||||
3.2
|
||||
3.1
|
||||
3.0 - Wifi chip IRQ (Ext INT 0)
|
||||
2.3 - TIMER2 (General purpose timer)
|
||||
2.2
|
||||
2.1 - Ext Interrupt 1 (Led dimming knob) NOT USED!!!
|
||||
1.0
|
||||
1.3
|
||||
1.2
|
||||
1.1
|
||||
1.0
|
||||
LOWEST
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef DEFINE_H
|
||||
#define DEFINE_H
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include <plib.h>
|
||||
|
||||
//#include "CUHelperFcns.h"
|
||||
|
||||
enum eWiFiState
|
||||
{
|
||||
WIFI_MODULE_OFF_STATE = 0,
|
||||
WIFI_CONNECTED_STATE,
|
||||
WIFI_DISCONNECTED_STATE,
|
||||
WIFI_INIT_ERROR_STATE,
|
||||
WIFI_UNKNOWN_STATE
|
||||
};
|
||||
|
||||
#define WIFI_MODULE_SPI_BAUDRATE 15000000
|
||||
|
||||
#define WIFI_CONNECT_TIMEOUT 10000 //The delay we allow the module to establish a connection.
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
|
||||
#define PIN_INPUT 1
|
||||
#define PIN_OUTPUT 0
|
||||
#define LED_ON 0
|
||||
#define LED_OFF 1
|
||||
#define false 0
|
||||
#define true 1
|
||||
#define MSB8(x) ((x >> 8) & 0xFF)
|
||||
#define LSB8(x) (x & 0xFF)
|
||||
|
||||
#define RET_OK true
|
||||
#define RET_ERROR false
|
||||
|
||||
#define bool unsigned int
|
||||
|
||||
#define PI 3.1415926536
|
||||
|
||||
//#define ENABLE_DEBUG_LOG
|
||||
#ifdef ENABLE_DEBUG_LOG
|
||||
#include "util.h"
|
||||
#endif
|
||||
|
||||
////#define USE_HALL_ACQ_SIMULATOR //Use this switch for development to test hall acquisition traces
|
||||
//#define USE_ENGINEERING_MODE //Use this switch to disable speed, position and halls traces and traces buffer allocation (all traces !)
|
||||
////#define USE_TRACE_SIMULATOR //Use this switch to simulate trace data for development
|
||||
////#define USE_SPI_DONGLE_SIMULATOR //Use this switch if you use the CUMUX as a SPI dongle instead of the CS16IS74 dongle.
|
||||
////#define USE_PMP_AUTOINCREMENT //Use to speed-up AD2S data transfer
|
||||
////#define USE_PWM_DETECTION //Use PWM detection to enable/disable bridge
|
||||
////#define USE_AUTO_BRIDGE_CONTROL //Execute drive bridge control
|
||||
////#define FORCE_BRIDGE_ON
|
||||
////#define DRIVE_BOARD_NOT_INSTALLED
|
||||
//#define DISABLE_PRINT_FAULT
|
||||
//#define SPI_FAST
|
||||
////#define USE_DMA_WITH_PMP
|
||||
////#define USE_RESOLVER_STATEMACHINE
|
||||
////#define DISABLE_DRIVE_PARAM_MGMT // uncomment to avoid setting the drive at power-up
|
||||
#define NO_EXTERNAL_UART
|
||||
|
||||
//Choose which timer to use for general purpose timer
|
||||
#define GP_TIMER_USE_TIMER_1
|
||||
|
||||
|
||||
//#define POLL_UART1_RX
|
||||
//#define POLL_UART2_RX
|
||||
|
||||
|
||||
//#define NO_WIFI
|
||||
|
||||
//Define the com port assignations
|
||||
//----------------------------
|
||||
#define NETWORK_UART_PORT UART_1
|
||||
|
||||
#ifndef NO_WIFI
|
||||
#define WIFI_MODULE_UART_PORT UART_2
|
||||
#endif
|
||||
|
||||
//
|
||||
//----------------------------
|
||||
//Enable only one of those 3 options
|
||||
//#define USE_BLOCKING_PRINTF
|
||||
//#define USE_UART_PRINTF
|
||||
#define USE_SYSLOG
|
||||
|
||||
#ifdef USE_UART_PRINTF
|
||||
#ifdef USE_SYSLOG
|
||||
#error "USE_UART_PRINTF and USE_SYSLOG defined simultaneously"
|
||||
#endif
|
||||
#endif
|
||||
//#error test
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
#ifdef NO_WIFI
|
||||
#undef USE_SYSLOG
|
||||
#error "USE_SYSLOG defined with NO_WIFI"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_UART_PRINTF
|
||||
#define PRINTF(n, a...) printf(n, ## a)
|
||||
#elif defined USE_SYSLOG
|
||||
#define PRINTF(n, a...) printf(n, ## a)
|
||||
#else
|
||||
#define PRINTF(n, a...)
|
||||
#endif
|
||||
|
||||
#ifndef NO_WIFI
|
||||
// #define USE_WIFI_PRINTF
|
||||
#endif
|
||||
|
||||
//#define USE_UART_PRINTF
|
||||
//#else
|
||||
//
|
||||
// #define NO_EXTERNAL_UART
|
||||
//#endif
|
||||
|
||||
//#define CONNECT_DEVICE_TO_NETWORK
|
||||
//#define TERMINAL_USE_TELNET
|
||||
//#define TERMINAL_USE_TCP_SERVER
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
|
||||
|
||||
//----- STDINT.H TYPE DEFINITIONS -----
|
||||
//(Valid for XC16 & XC32 microchip PIC compilers)
|
||||
#ifndef uint8_t
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
|
||||
#ifndef int8_t
|
||||
typedef signed char int8_t;
|
||||
#endif
|
||||
|
||||
#ifndef uint16_t
|
||||
typedef unsigned short uint16_t;
|
||||
#endif
|
||||
|
||||
#ifndef int16_t
|
||||
typedef signed short int16_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifndef uint32_t
|
||||
typedef unsigned long uint32_t;
|
||||
#endif
|
||||
|
||||
#ifndef int32_t
|
||||
typedef signed long int32_t;
|
||||
#endif
|
||||
*/
|
||||
|
||||
#ifndef uint64_t
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif
|
||||
|
||||
#ifndef int64_t
|
||||
typedef signed long long int64_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
//EOF
|
||||
|
||||
168
ChaloupeLora.X/Source/define_WITT.h
Normal file
168
ChaloupeLora.X/Source/define_WITT.h
Normal file
@ -0,0 +1,168 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Copyright 2010 Rheinmetall Canada Inc. *
|
||||
* *
|
||||
* No part of this document may be reproduced, stored in *
|
||||
* a retrieval system, or transmitted, in any form or by any means, *
|
||||
* electronic, mechanical, photocopying, recording, or otherwise, *
|
||||
* without the prior written permission of Rheinmetall Canada Inc. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/* ¤Revision:
|
||||
000 20100616 HCAM,
|
||||
Original version.
|
||||
|
||||
|
||||
,----.. ,----..
|
||||
/ / \ / / \ ,--,
|
||||
| : : __ ,-. ,---. | : : ,--.'| ,---,
|
||||
. | ;. / ,' ,'/ /| ' ,'\ .--.--. . | ;. / | |, ,-+-. / |
|
||||
. ; /--` ' | |' | / / | / / ' . ; /--` `--'_ ,--.'|' |
|
||||
; | ; __ | | ,'. ; ,. :| : /`./ ; | ; __ ,' ,'| | | ,"' |
|
||||
| : |.' .'' : / ' | |: :| : ;_ | : |.' .'' | | | | / | |
|
||||
. | '_.' :| | ' ' | .; : \ \ `. . | '_.' :| | : | | | | |
|
||||
' ; : \ |; : | | : | `----. \ ' ; : \ |' : |__ | | | |/
|
||||
' | '/ .'| , ; \ \ / / /`--' / ' | '/ .'| | '.'|| | |--'
|
||||
| : / ---' `----' '--'. / | : / ; : ;| |/
|
||||
\ \ .' `--'---' \ \ .' | , / '---'
|
||||
`---` `---` ---`-'
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************** NOTES ***************************************
|
||||
-> Timers assignment <-
|
||||
|
||||
- Timer1 used by general timer module (timer.c)
|
||||
- Timer2 used by time based Resolver data acquisition module (resolver.c)
|
||||
- timer3 used by input capture to detect PWM
|
||||
- timer4 used by hall acquisition module (HallAcquisition.c)
|
||||
- timer5 used by FPGAInterface to time-base SPI the transfer to the FPGA
|
||||
|
||||
|
||||
-> Interrupt priority assignment <-
|
||||
|
||||
Priority.SubPriority - Assignment
|
||||
HIGHEST
|
||||
7.3
|
||||
7.2
|
||||
7.1 - UART1
|
||||
7.0 - UART2
|
||||
6.3 - TIMER2 (Resolver acquisition & halls computation)
|
||||
6.2 - PMP
|
||||
6.1
|
||||
6.0 - Input Capture
|
||||
5.3 - ADC
|
||||
5.2 - SPI
|
||||
5.1
|
||||
5.0
|
||||
4.3 - Drive Enable pin interrupt
|
||||
4.2 - AD2S DOS Pin
|
||||
4.1 - AD2S LOT Pin
|
||||
4.0
|
||||
3.3
|
||||
3.2
|
||||
3.1
|
||||
3.0 - TIMER5 (FPGA TX)
|
||||
2.3 - TIMER1 (General purpose timer)
|
||||
2.2 - TIMER3 (PWM Detection)
|
||||
2.1
|
||||
1.0
|
||||
1.3
|
||||
1.2
|
||||
1.1
|
||||
1.0
|
||||
LOWEST
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef DEFINE_H
|
||||
#define DEFINE_H
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include <plib.h>
|
||||
//#include "CUHelperFcns.h"
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
#define SYS_FREQ (77824000L) //Clock period = 12.85 ns
|
||||
#define PERIPHERAL_FREQ (77824000L)
|
||||
#define PIN_INPUT 1
|
||||
#define PIN_OUTPUT 0
|
||||
#define LED_ON 0
|
||||
#define LED_OFF 1
|
||||
#define false 0
|
||||
#define true 1
|
||||
#define MSB8(x) ((x >> 8) & 0xFF)
|
||||
#define LSB8(x) (x & 0xFF)
|
||||
|
||||
#define PI 3.1415926536
|
||||
|
||||
//#define ENABLE_DEBUG_LOG
|
||||
#ifdef ENABLE_DEBUG_LOG
|
||||
#include "util.h"
|
||||
#endif
|
||||
|
||||
//#define USE_HALL_ACQ_SIMULATOR //Use this switch for development to test hall acquisition traces
|
||||
#define USE_ENGINEERING_MODE //Use this switch to disable speed, position and halls traces and traces buffer allocation (all traces !)
|
||||
//#define USE_TRACE_SIMULATOR //Use this switch to simulate trace data for development
|
||||
//#define USE_SPI_DONGLE_SIMULATOR //Use this switch if you use the CUMUX as a SPI dongle instead of the CS16IS74 dongle.
|
||||
//#define USE_PMP_AUTOINCREMENT //Use to speed-up AD2S data transfer
|
||||
#define USE_PWM_DETECTION //Use PWM detection to enable/disable bridge
|
||||
#define USE_AUTO_BRIDGE_CONTROL //Execute drive bridge control
|
||||
//#define FORCE_BRIDGE_ON
|
||||
//#define DRIVE_BOARD_NOT_INSTALLED
|
||||
#define DISABLE_PRINT_FAULT
|
||||
#define SPI_FAST
|
||||
//#define USE_DMA_WITH_PMP
|
||||
//#define USE_RESOLVER_STATEMACHINE
|
||||
//#define DISABLE_DRIVE_PARAM_MGMT // uncomment to avoid setting the drive at power-up
|
||||
|
||||
#define POLL_UART1_RX
|
||||
#define POLL_UART2_RX
|
||||
|
||||
// Uncomment next #define for testing with ICCA board
|
||||
// #define USE_ICCA_CU_PA_UART_SNOOPING
|
||||
|
||||
|
||||
//Define the com port assignations
|
||||
//----------------------------
|
||||
#define DRIVE_UART_PORT UART_1
|
||||
#ifdef USE_ICCA_CU_PA_UART_SNOOPING
|
||||
// Note: With this configuration there is no CU command going to the PA
|
||||
#define CU_UART_PORT UART_3
|
||||
#define CONSOLE_UART_PORT UART_2
|
||||
#else
|
||||
// Normal setting using PA SPI for UART_3 (CONSOLE_UART_PORT)
|
||||
#define CU_UART_PORT UART_2
|
||||
#define CONSOLE_UART_PORT UART_3
|
||||
#endif
|
||||
|
||||
#define ACTUATOR_WITTENSTEIN
|
||||
//#define ACTUATOR_DS50
|
||||
|
||||
//
|
||||
//----------------------------
|
||||
//#define USE_BLOCKING_PRINTF
|
||||
#define USE_PRINTF
|
||||
|
||||
#ifdef USE_PRINTF
|
||||
#define PRINTF(n, a...) printf(n, ## a)
|
||||
#else
|
||||
#define PRINTF(n, a...)
|
||||
#define NO_EXTERNAL_UART
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
typedef int bool;
|
||||
|
||||
#endif
|
||||
//EOF
|
||||
|
||||
129
ChaloupeLora.X/Source/exceptions.c
Normal file
129
ChaloupeLora.X/Source/exceptions.c
Normal file
@ -0,0 +1,129 @@
|
||||
/******************************************************************************/
|
||||
/* Files to Include */
|
||||
/******************************************************************************/
|
||||
|
||||
#include <plib.h> /* Include to use PIC32 peripheral libraries */
|
||||
#include <stdint.h> /* For uint32_t definition */
|
||||
#include <stdbool.h> /* For true/false definition */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Exception Macro Definitions */
|
||||
/******************************************************************************/
|
||||
|
||||
/*When WRITE_EXCEPTION_CAUSE_TO_FLASH is defined the PIC32 executes a self
|
||||
write routine to save the exception cause register.*/
|
||||
|
||||
/* #define WRITE_EXCEPTION_CAUSE_TO_FLASH */
|
||||
|
||||
#ifdef WRITE_EXCEPTION_CAUSE_TO_FLASH
|
||||
|
||||
/* Physical Addresses which are at the end of KSEG 0 program memory. */
|
||||
/* User may want to adjust these values */
|
||||
#define EXCEPTION_CAUSE 0x1D007FFC
|
||||
#define EXCEPTION_ADDR 0x1D007FF8
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* Exception Variable Declaration */
|
||||
/******************************************************************************/
|
||||
|
||||
/* static in case exception condition would stop auto variable being created */
|
||||
static enum {
|
||||
EXCEP_IRQ = 0, /* interrupt */
|
||||
EXCEP_AdEL = 4, /* address error exception (load or ifetch) */
|
||||
EXCEP_AdES, /* address error exception (store) */
|
||||
EXCEP_IBE, /* bus error (ifetch) */
|
||||
EXCEP_DBE, /* bus error (load/store) */
|
||||
EXCEP_Sys, /* syscall */
|
||||
EXCEP_Bp, /* breakpoint */
|
||||
EXCEP_RI, /* reserved instruction */
|
||||
EXCEP_CpU, /* coprocessor unusable */
|
||||
EXCEP_Overflow, /* arithmetic overflow */
|
||||
EXCEP_Trap, /* trap (possible divide by zero) */
|
||||
EXCEP_IS1 = 16, /* implementation specfic 1 */
|
||||
EXCEP_CEU, /* CorExtend Unuseable */
|
||||
EXCEP_C2E /* coprocessor 2 */
|
||||
} _excep_code;
|
||||
|
||||
/* static in case exception condition would stop auto variable being created */
|
||||
static unsigned int _epc_code;
|
||||
static unsigned int _excep_addr;
|
||||
|
||||
/******************************************************************************/
|
||||
/* Exception Handling */
|
||||
/******************************************************************************/
|
||||
|
||||
/* This function overrides the normal _weak_ _generic_exception_handler which
|
||||
is defined in the C32 User's Guide. The _weak_ _generic_exception_handler
|
||||
just does an infinite loop. */
|
||||
void _general_exception_handler(void)
|
||||
{
|
||||
unsigned long t0 = _CP0_GET_COUNT(); /* Used for NVMOP 6 us Delay */
|
||||
|
||||
/* Mask off Mask of the ExcCode Field from the Cause Register
|
||||
Refer to the MIPs M4K Software User's manual */
|
||||
_excep_code=_CP0_GET_CAUSE() & 0x0000007C >> 2;
|
||||
_excep_addr=_CP0_GET_EPC();
|
||||
|
||||
_CP0_SET_STATUS(_CP0_GET_STATUS()&0xFFFFFFE); /* Disable Interrupts */
|
||||
|
||||
#ifdef WRITE_EXCEPTION_CAUSE_TO_FLASH
|
||||
|
||||
/* Store the exception causes in program memory in case the part exhibited
|
||||
the problem in release mode. Gives user a place to start debugging
|
||||
the problem. */
|
||||
|
||||
NVMCON = 0x4001; /* set WREN and Word Programing mode */
|
||||
NVMADDR = EXCEPTION_CAUSE; /* PM Address at which we'll store the */
|
||||
/* cause register */
|
||||
NVMDATA = _excep_code;
|
||||
|
||||
/* wait at least 6 us for LVD start-up
|
||||
assume we're running at max frequency
|
||||
(80 MHz) so we're always safe */
|
||||
{
|
||||
while (_CP0_GET_COUNT() - t0 < (80/2)*6);
|
||||
}
|
||||
|
||||
NVMKEY = 0xAA996655;
|
||||
NVMKEY = 0x556699AA; /* unlock sequence */
|
||||
NVMCONSET = NVMCON_WR;
|
||||
while(NVMCON & NVMCON_WR); /* wait on write to finish */
|
||||
|
||||
NVMCON = 0x4001; /* set WREN and Word Programing mode */
|
||||
NVMADDR = EXCEPTION_ADDR; /* PM Address at which we'll store the */
|
||||
/* exception address register */
|
||||
NVMDATA = _excep_addr;
|
||||
|
||||
/* wait at least 6 us for LVD start-up
|
||||
assume we're running at max frequency
|
||||
(80 MHz) so we're always safe */
|
||||
{
|
||||
while (_CP0_GET_COUNT() - t0 < (80/2)*6);
|
||||
}
|
||||
|
||||
NVMKEY = 0xAA996655;
|
||||
NVMKEY = 0x556699AA; /* unlock sequence */
|
||||
NVMCONSET = NVMCON_WR;
|
||||
while(NVMCON & NVMCON_WR);
|
||||
|
||||
/* Write the exception cause and address to the part can be read and
|
||||
the cause determined. */
|
||||
NVMWriteWord((void*)EXCEPTION_CAUSE, _excep_code);
|
||||
NVMWriteWord((void*)EXCEPTION_ADDR, _excep_addr);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Examine _excep_code to identify the type of exception */
|
||||
/* Examine _excep_addr to find the address that caused the exception */
|
||||
Nop();
|
||||
Nop();
|
||||
Nop();
|
||||
SoftReset();
|
||||
Nop();
|
||||
}
|
||||
}
|
||||
649
ChaloupeLora.X/Source/hd44780.c
Normal file
649
ChaloupeLora.X/Source/hd44780.c
Normal file
@ -0,0 +1,649 @@
|
||||
/**
|
||||
* ---------------------------------------------------------------+
|
||||
* @desc HD44780 LCD Driver
|
||||
* ---------------------------------------------------------------+
|
||||
* Copyright (C) 2020 Marian Hrinko.
|
||||
* Written by Marian Hrinko (mato.hrinko@gmail.com)
|
||||
*
|
||||
* @author Marian Hrinko
|
||||
* @datum 18.11.2020
|
||||
* @file hd44780.c
|
||||
* @tested AVR Atmega16a
|
||||
*
|
||||
* @depend hd44780.h
|
||||
* ---------------------------------------------------------------+
|
||||
* @usage default set 16x2 LCD
|
||||
* 4-bit with 3 control wires (RW, RS, E)
|
||||
*/
|
||||
|
||||
// include libraries
|
||||
#include <stdio.h>
|
||||
//#include <util/delay.h>
|
||||
//#include <avr/io.h>
|
||||
#include "hd44780.h"
|
||||
#include "timer.h"
|
||||
|
||||
// +---------------------------+
|
||||
// | Power on |
|
||||
// | Wait for more than 15 ms | // 15 ms wait
|
||||
// | after VCC rises to 4.5 V |
|
||||
// +---------------------------+
|
||||
// |
|
||||
// +---------------------------+
|
||||
// | RS R/W DB7 DB6 DB5 DB4 |
|
||||
// | 0 0 0 0 1 1 | // Initial sequence 0x30
|
||||
// | Wait for more than 4.1 ms | // 4.1 ms us writing DATA into DDRAM or CGRAM
|
||||
// +---------------------------+
|
||||
// |
|
||||
// +---------------------------+
|
||||
// | RS R/W DB7 DB6 DB5 DB4 |
|
||||
// | 0 0 0 0 1 1 | // Initial sequence 0x30
|
||||
// | Wait for more than 0.1 ms | // 100 us writing DATA into DDRAM or CGRAM
|
||||
// +---------------------------+
|
||||
// |
|
||||
// +---------------------------+
|
||||
// | RS R/W DB7 DB6 DB5 DB4 | // Initial sequence 0x30
|
||||
// | 0 0 0 0 1 1 | // 37 us writing DATA into DDRAM or CGRAM 4 us tadd - time after busy flag disapeared
|
||||
// | Wait for more than 45 us | // 37 us + 4 us = 41 us * (270/250) = 45us
|
||||
// +---------------------------+
|
||||
// |
|
||||
// +---------------------------+ // 4bit mode 0x20 !!! MUST BE SET TIME, BF CHECK DOESN'T WORK CORRECTLY !!!
|
||||
// | RS R/W DB7 DB6 DB5 DB4 | //
|
||||
// | 0 0 0 0 1 0 | // 37 us writing DATA into DDRAM or CGRAM 4 us tadd - time after busy flag disapeared
|
||||
// | Wait for more than 45 us | // !!! MUST BE SET DELAY TIME, BUSY FLAG CHECK DOESN'T WORK CORRECTLY !!!
|
||||
// +---------------------------+
|
||||
// |
|
||||
// +---------------------------+
|
||||
// | RS R/W DB7 DB6 DB5 DB4 | // Display off 0x08
|
||||
// | 0 0 0 0 1 0 | //
|
||||
// | 0 0 1 0 0 0 | //
|
||||
// | Wait for BF Cleared | // Wait for BF Cleared
|
||||
// +---------------------------+
|
||||
// |
|
||||
// +---------------------------+
|
||||
// | RS R/W DB7 DB6 DB5 DB4 | // Display clear 0x01
|
||||
// | 0 0 0 0 0 0 | //
|
||||
// | 0 0 0 0 0 1 | //
|
||||
// | Wait for BF Cleared | // Wait for BF Cleared
|
||||
// +---------------------------+
|
||||
// |
|
||||
// +---------------------------+
|
||||
// | RS R/W DB7 DB6 DB5 DB4 | // Entry mode set 0x06
|
||||
// | 0 0 0 0 0 0 | //
|
||||
// | 0 0 0 1 1 0 | // shift cursor to the left, without text shifting
|
||||
// | Wait for BF Cleared | // Wait for BF Cleared
|
||||
// +---------------------------+
|
||||
|
||||
/**
|
||||
* @desc LCD display clear
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_DisplayClear (void)
|
||||
{
|
||||
// Diplay clear
|
||||
HD44780_SendInstruction(HD44780_DISP_CLEAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD display on
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_DisplayOn (void)
|
||||
{
|
||||
// send instruction - display on
|
||||
HD44780_SendInstruction(HD44780_DISP_ON);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD cursor on, display on
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CursorOn (void)
|
||||
{
|
||||
// send instruction - cursor on
|
||||
HD44780_SendInstruction(HD44780_CURSOR_ON);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD cursor off
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CursorOff (void)
|
||||
{
|
||||
// send instruction - cursor on
|
||||
HD44780_SendInstruction(HD44780_CURSOR_OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD cursor blink, cursor on, display on
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CursorBlink (void)
|
||||
{
|
||||
// send instruction - Cursor blink
|
||||
HD44780_SendInstruction(HD44780_CURSOR_BLINK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD draw char
|
||||
*
|
||||
* @param char
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_DrawChar (char character)
|
||||
{
|
||||
// Diplay clear
|
||||
HD44780_SendData(character);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD draw string
|
||||
*
|
||||
* @param char *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_DrawString (char *str)
|
||||
{
|
||||
unsigned char i = 0;
|
||||
// loop through 5 bytes
|
||||
while (str[i] != '\0') {
|
||||
//read characters and increment index
|
||||
HD44780_SendData(str[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Got to position x,y
|
||||
*
|
||||
* @param char
|
||||
* @param char
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
char HD44780_PositionXY (char x, char y)
|
||||
{
|
||||
if (x > HD44780_COLS || y > HD44780_ROWS) {
|
||||
// error
|
||||
return ERROR;
|
||||
}
|
||||
// check which row
|
||||
if (y == 0) {
|
||||
// send instruction 1st row
|
||||
HD44780_SendInstruction(HD44780_POSITION | (HD44780_ROW1_START + x));
|
||||
} else if (y == 1) {
|
||||
// send instruction 2nd row
|
||||
HD44780_SendInstruction(HD44780_POSITION | (HD44780_ROW2_START + x));
|
||||
}
|
||||
// success
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Shift cursor / display to left / right
|
||||
*
|
||||
* @param char item {HD44780_CURSOR; HD44780_DISPLAY}
|
||||
* @param char direction {HD44780_RIGHT; HD44780_LEFT}
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
char HD44780_Shift (char item, char direction)
|
||||
{
|
||||
// check if item is cursor or display or direction is left or right
|
||||
if ((item != HD44780_DISPLAY) && (item != HD44780_CURSOR)) {
|
||||
// error
|
||||
return ERROR;
|
||||
}
|
||||
// check if direction is left or right
|
||||
if ((direction != HD44780_RIGHT) && (direction != HD44780_LEFT)) {
|
||||
// error
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// cursor shift
|
||||
if (item == HD44780_CURSOR) {
|
||||
// right shift
|
||||
if (direction == HD44780_RIGHT) {
|
||||
// shit cursor / display to right / left
|
||||
HD44780_SendInstruction(HD44780_SHIFT | HD44780_CURSOR | HD44780_RIGHT);
|
||||
} else {
|
||||
// shit cursor / display to right / left
|
||||
HD44780_SendInstruction(HD44780_SHIFT | HD44780_CURSOR | HD44780_LEFT);
|
||||
}
|
||||
// display shift
|
||||
} else {
|
||||
// right shift
|
||||
if (direction == HD44780_RIGHT) {
|
||||
// shit cursor / display to right / left
|
||||
HD44780_SendInstruction(HD44780_SHIFT | HD44780_DISPLAY | HD44780_RIGHT);
|
||||
} else {
|
||||
// shit cursor / display to right / left
|
||||
HD44780_SendInstruction(HD44780_SHIFT | HD44780_DISPLAY | HD44780_LEFT);
|
||||
}
|
||||
}
|
||||
// success
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD init - initialisation routine
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_Init (void)
|
||||
{
|
||||
// set E as output
|
||||
SETBIT(HD44780_DDR_E, HD44780_E);
|
||||
// set RS as output
|
||||
SETBIT(HD44780_DDR_RS, HD44780_RS);
|
||||
// set RW as output
|
||||
SETBIT(HD44780_DDR_RW, HD44780_RW);
|
||||
|
||||
// set DB7-DB4 as output
|
||||
HD44780_SetDDR_DATA4to7();
|
||||
|
||||
// clear RS
|
||||
CLRBIT(HD44780_PORT_RS, HD44780_RS);
|
||||
// clear RW
|
||||
CLRBIT(HD44780_PORT_RW, HD44780_RW);
|
||||
// clear E
|
||||
CLRBIT(HD44780_PORT_E, HD44780_E);
|
||||
|
||||
// delay > 15ms
|
||||
_delay_ms(16);
|
||||
|
||||
|
||||
// Busy Flag (BF) cannot be checked in these instructions
|
||||
// ---------------------------------------------------------------------
|
||||
// Initial sequence 0x30 - send 4 bits in 4 bit mode
|
||||
HD44780_SendInstruction(HD44780_INIT_SEQ);
|
||||
// delay > 4.1ms
|
||||
_delay_ms(5);
|
||||
|
||||
// pulse E
|
||||
HD44780_PulseE();
|
||||
// delay > 100us
|
||||
_delay_us(110);
|
||||
|
||||
// pulse E
|
||||
HD44780_PulseE();
|
||||
// delay > 45us (=37+4 * 270/250)
|
||||
_delay_us(50);
|
||||
|
||||
// 4 bit mode 0x20 - send 4 bits in 4 bit mode
|
||||
HD44780_Send4bitsIn4bitMode(HD44780_4BIT_MODE);
|
||||
// pulse E
|
||||
HD44780_PulseE();
|
||||
// delay > 45us (=37+4 * 270/250)
|
||||
_delay_us(50);
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// 4-bit & 2-lines & 5x8-dots 0x28 - send 8 bits in 4 bit mode
|
||||
HD44780_SendInstruction(HD44780_4BIT_MODE | HD44780_2_ROWS | HD44780_FONT_5x8);
|
||||
|
||||
// display off 0x08 - send 8 bits in 4 bit mode
|
||||
HD44780_SendInstruction(HD44780_DISP_OFF);
|
||||
|
||||
// display clear 0x01 - send 8 bits in 4 bit mode
|
||||
HD44780_SendInstruction(HD44780_DISP_CLEAR);
|
||||
|
||||
// entry mode set 0x06 - send 8 bits in 4 bit mode
|
||||
HD44780_SendInstruction(HD44780_ENTRY_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Check Busy Flag (BF) in 4 bit mode
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CheckBFin4bitMode (void)
|
||||
{
|
||||
unsigned char input = 0;
|
||||
|
||||
// clear DB7-DB4 as input
|
||||
HD44780_ClearDDR_DATA4to7();
|
||||
// set pull-up resistors for DB7-DB4
|
||||
HD44780_SetPORT_DATA4to7();
|
||||
|
||||
// clear RS
|
||||
CLRBIT(HD44780_PORT_RS, HD44780_RS);
|
||||
// set RW - read instruction
|
||||
SETBIT(HD44780_PORT_RW, HD44780_RW);
|
||||
|
||||
// test HIGH level on PIN DB7
|
||||
// after clear PIN DB7 should continue
|
||||
// -------------------------------------
|
||||
// us: 0.5|0.5|0.5
|
||||
// ___ ___
|
||||
// E: ___/ \___/ \__
|
||||
// ___ ___
|
||||
// DB7: \___/ \___/ \__
|
||||
//
|
||||
while (1) {
|
||||
|
||||
// Read upper nibble
|
||||
// --------------------------------
|
||||
// Set E
|
||||
SETBIT(HD44780_PORT_E, HD44780_E);
|
||||
// PWeh > 0.5us
|
||||
_delay_us(0.5);
|
||||
// read upper nibble (tDDR > 360ns)
|
||||
input = HD44780_PIN_DATA;
|
||||
// Clear E
|
||||
CLRBIT(HD44780_PORT_E, HD44780_E);
|
||||
// TcycE > 1000ns -> delay depends on PWeh delay time
|
||||
// delay = TcycE - PWeh = 1000 - 500 = 500ns
|
||||
_delay_us(0.5);
|
||||
|
||||
// Read lower nibble
|
||||
// --------------------------------
|
||||
// Set E
|
||||
SETBIT(HD44780_PORT_E, HD44780_E);
|
||||
// PWeh > 0.5us
|
||||
_delay_us(0.5);
|
||||
// read lower nibble (tDDR > 360ns)
|
||||
input |= HD44780_PIN_DATA >> 4;
|
||||
// Clear E
|
||||
CLRBIT(HD44780_PORT_E, HD44780_E);
|
||||
// TcycE > 1000ns -> delay depends on PWeh delay time
|
||||
// delay = TcycE - PWeh = 1000 - 500 = 500ns
|
||||
_delay_us(0.5);
|
||||
|
||||
// check if DB7 is cleared
|
||||
if (!(input & (1 << HD44780_DATA7))) {
|
||||
// if BF cleared -> end loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// clear RW
|
||||
CLRBIT(HD44780_PORT_RW, HD44780_RW);
|
||||
|
||||
// set DB7-DB4 as output
|
||||
HD44780_SetDDR_DATA4to7();
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Check Busy Flag (BF) in 8 bit mode
|
||||
*
|
||||
* @param void
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CheckBFin8bitMode (void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD send instruction
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SendInstruction (unsigned short int data)
|
||||
{
|
||||
// Clear RS
|
||||
HD44780_PORT_RS &= ~(1 << HD44780_RS);
|
||||
|
||||
// 4bit mode
|
||||
// ------------------------------------------
|
||||
if (HD44780_MODE == HD44780_4BIT_MODE) {
|
||||
// send required data in required mode
|
||||
HD44780_Send8bitsIn4bitMode(data);
|
||||
// check busy flag
|
||||
HD44780_CheckBFin4bitMode();
|
||||
// 8 bit mode
|
||||
// ------------------------------------------
|
||||
} else if (HD44780_MODE == HD44780_8BIT_MODE) {
|
||||
// send required data in required mode
|
||||
HD44780_Send8bitsIn8bitMode(data);
|
||||
// check busy flag
|
||||
HD44780_CheckBFin8bitMode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD send data
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SendData (unsigned short int data)
|
||||
{
|
||||
// Set RS
|
||||
SETBIT(HD44780_PORT_RS, HD44780_RS);
|
||||
|
||||
// 4bit mode
|
||||
// ------------------------------------------
|
||||
if (HD44780_MODE == HD44780_4BIT_MODE) {
|
||||
// send required data in required mode
|
||||
HD44780_Send8bitsIn4bitMode(data);
|
||||
// check busy flag
|
||||
HD44780_CheckBFin4bitMode();
|
||||
// 8 bit mode
|
||||
// ------------------------------------------
|
||||
} else if (HD44780_MODE == HD44780_8BIT_MODE) {
|
||||
// send required data in required mode
|
||||
HD44780_Send8bitsIn8bitMode(data);
|
||||
// check busy flag
|
||||
HD44780_CheckBFin8bitMode();
|
||||
}
|
||||
|
||||
// Clear RS
|
||||
CLRBIT(HD44780_PORT_RS, HD44780_RS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD send 4bits instruction in 4 bit mode
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_Send4bitsIn4bitMode (unsigned short int data)
|
||||
{
|
||||
// Set E
|
||||
SETBIT(HD44780_PORT_E, HD44780_E);
|
||||
// send data to LCD
|
||||
HD44780_SetUppNibble(data);
|
||||
// PWeh delay time > 450ns
|
||||
_delay_us(0.5);
|
||||
// Clear E
|
||||
CLRBIT(HD44780_PORT_E, HD44780_E);
|
||||
// TcycE > 1000ns -> delay depends on PWeh delay time
|
||||
// delay = TcycE - PWeh = 1000 - 500 = 500ns
|
||||
_delay_us(0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD send 8bits instruction in 4 bit mode
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_Send8bitsIn4bitMode (unsigned short int data)
|
||||
{
|
||||
// Send upper nibble
|
||||
// ----------------------------------
|
||||
// Set E
|
||||
SETBIT(HD44780_PORT_E, HD44780_E);
|
||||
// send data to LCD
|
||||
HD44780_SetUppNibble(data);
|
||||
// PWeh delay time > 450ns
|
||||
_delay_us(0.5);
|
||||
// Clear E
|
||||
CLRBIT(HD44780_PORT_E, HD44780_E);
|
||||
// TcycE > 1000ns -> delay depends on PWeh delay time
|
||||
// delay = TcycE - PWeh = 1000 - 500 = 500ns
|
||||
_delay_us(0.5);
|
||||
|
||||
// Send lower nibble
|
||||
// ----------------------------------
|
||||
// Set E
|
||||
SETBIT(HD44780_PORT_E, HD44780_E);
|
||||
// send data to LCD
|
||||
HD44780_SetUppNibble(data << 4);
|
||||
// PWeh delay time > 450ns
|
||||
_delay_us(0.5);
|
||||
// Clear E
|
||||
CLRBIT(HD44780_PORT_E, HD44780_E);
|
||||
// TcycE > 1000ns -> delay depends on PWeh delay time
|
||||
// delay = TcycE - PWeh = 1000 - 500 = 500ns
|
||||
_delay_us(0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD send 8bits instruction in 8 bit mode
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_Send8bitsIn8bitMode (unsigned short int data)
|
||||
{
|
||||
// Set E
|
||||
SETBIT(HD44780_PORT_E, HD44780_E);
|
||||
// send data to LCD
|
||||
HD44780_SetUppNibble(data);
|
||||
// send data to LCD
|
||||
HD44780_SetLowNibble(data);
|
||||
// PWeh delay time > 450ns
|
||||
_delay_us(0.5);
|
||||
// Clear E
|
||||
CLRBIT(HD44780_PORT_E, HD44780_E);
|
||||
// TcycE > 1000ns -> delay depends on PWeh delay time
|
||||
// delay = TcycE - PWeh = 1000 - 500 = 500ns
|
||||
_delay_us(0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD send upper nibble
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SetUppNibble (unsigned short int data)
|
||||
{
|
||||
// clear bits DB7-DB4
|
||||
CLRBIT(HD44780_PORT_DATA, HD44780_DATA7);
|
||||
CLRBIT(HD44780_PORT_DATA, HD44780_DATA6);
|
||||
CLRBIT(HD44780_PORT_DATA, HD44780_DATA5);
|
||||
CLRBIT(HD44780_PORT_DATA, HD44780_DATA4);
|
||||
// set DB7-DB4 if corresponding bit is set
|
||||
if (data & 0x80) { SETBIT(HD44780_PORT_DATA, HD44780_DATA7); }
|
||||
if (data & 0x40) { SETBIT(HD44780_PORT_DATA, HD44780_DATA6); }
|
||||
if (data & 0x20) { SETBIT(HD44780_PORT_DATA, HD44780_DATA5); }
|
||||
if (data & 0x10) { SETBIT(HD44780_PORT_DATA, HD44780_DATA4); }
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD send lower nibble
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SetLowNibble (unsigned short int data)
|
||||
{
|
||||
// clear bits DB7-DB4
|
||||
CLRBIT(HD44780_PORT_DATA, HD44780_DATA3);
|
||||
CLRBIT(HD44780_PORT_DATA, HD44780_DATA2);
|
||||
CLRBIT(HD44780_PORT_DATA, HD44780_DATA1);
|
||||
CLRBIT(HD44780_PORT_DATA, HD44780_DATA0);
|
||||
// set DB7-DB4 if corresponding bit is set
|
||||
if (data & 0x08) { SETBIT(HD44780_PORT_DATA, HD44780_DATA3); }
|
||||
if (data & 0x04) { SETBIT(HD44780_PORT_DATA, HD44780_DATA2); }
|
||||
if (data & 0x02) { SETBIT(HD44780_PORT_DATA, HD44780_DATA1); }
|
||||
if (data & 0x01) { SETBIT(HD44780_PORT_DATA, HD44780_DATA0); }
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc LCD pulse E
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_PulseE (void)
|
||||
{
|
||||
// Set E
|
||||
SETBIT(HD44780_PORT_E, HD44780_E);
|
||||
// PWeh delay time > 450ns
|
||||
_delay_us(0.5);
|
||||
// Clear E
|
||||
CLRBIT(HD44780_PORT_E, HD44780_E);
|
||||
// TcycE > 1000ns -> delay depends on PWeh delay time
|
||||
// delay = TcycE - PWeh = 1000 - 500 = 500ns
|
||||
_delay_us(0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Set PORT DB4 to DB7
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SetPORT_DATA4to7 (void)
|
||||
{
|
||||
// set DB4-DB7
|
||||
SETBIT(HD44780_PORT_DATA, HD44780_DATA4);
|
||||
SETBIT(HD44780_PORT_DATA, HD44780_DATA5);
|
||||
SETBIT(HD44780_PORT_DATA, HD44780_DATA6);
|
||||
SETBIT(HD44780_PORT_DATA, HD44780_DATA7);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Clear DDR DB4 to DB7
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_ClearDDR_DATA4to7 (void)
|
||||
{
|
||||
// set DB4-DB7
|
||||
CLRBIT(HD44780_DDR_DATA, HD44780_DATA4);
|
||||
CLRBIT(HD44780_DDR_DATA, HD44780_DATA5);
|
||||
CLRBIT(HD44780_DDR_DATA, HD44780_DATA6);
|
||||
CLRBIT(HD44780_DDR_DATA, HD44780_DATA7);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Set DDR DB4 to DB7
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SetDDR_DATA4to7 (void)
|
||||
{
|
||||
// set DB7-DB4 as output
|
||||
SETBIT(HD44780_DDR_DATA, HD44780_DATA4);
|
||||
SETBIT(HD44780_DDR_DATA, HD44780_DATA5);
|
||||
SETBIT(HD44780_DDR_DATA, HD44780_DATA6);
|
||||
SETBIT(HD44780_DDR_DATA, HD44780_DATA7);
|
||||
}
|
||||
386
ChaloupeLora.X/Source/hd44780.h
Normal file
386
ChaloupeLora.X/Source/hd44780.h
Normal file
@ -0,0 +1,386 @@
|
||||
/**
|
||||
* ---------------------------------------------------------------+
|
||||
* @desc HD44780 LCD Driver
|
||||
* ---------------------------------------------------------------+
|
||||
* Copyright (C) 2020 Marian Hrinko.
|
||||
* Written by Marian Hrinko (mato.hrinko@gmail.com)
|
||||
*
|
||||
* @author Marian Hrinko
|
||||
* @datum 18.11.2020
|
||||
* @file hd44780.c
|
||||
* @tested AVR Atmega16a
|
||||
*
|
||||
* @depend
|
||||
* ---------------------------------------------------------------+
|
||||
* @usage default set 16x2 LCD
|
||||
* 4-bit with 3 control wires (RW, RS, E)
|
||||
*
|
||||
*/
|
||||
#ifndef __HD44780_H__
|
||||
#define __HD44780_H__
|
||||
|
||||
// Success
|
||||
#ifndef SUCCESS
|
||||
#define SUCCESS 0
|
||||
#endif
|
||||
|
||||
// Error
|
||||
#ifndef ERROR
|
||||
#define ERROR 1
|
||||
#endif
|
||||
|
||||
// define clock
|
||||
#if defined(__AVR_ATmega8__)
|
||||
#define _FCPU 8000000
|
||||
#elif defined(__AVR_ATmega16__)
|
||||
#define _FCPU 16000000
|
||||
#endif
|
||||
|
||||
//#if defined(__AVR_ATmega16__)
|
||||
|
||||
// E port
|
||||
// --------------------------------------
|
||||
#ifndef HD44780_DDR_E
|
||||
#define HD44780_DDR_E TRISB
|
||||
#endif
|
||||
#ifndef HD44780_PORT_E
|
||||
#define HD44780_PORT_E PORTB
|
||||
#endif
|
||||
#ifndef HD44780_E
|
||||
#define HD44780_E 12
|
||||
#endif
|
||||
|
||||
// RW port
|
||||
// --------------------------------------
|
||||
#ifndef HD44780_DDR_RW
|
||||
#define HD44780_DDR_RW TRISB
|
||||
#endif
|
||||
#ifndef HD44780_PORT_RW
|
||||
#define HD44780_PORT_RW PORTB
|
||||
#endif
|
||||
#ifndef HD44780_RW
|
||||
#define HD44780_RW 13
|
||||
#endif
|
||||
|
||||
// RS port
|
||||
// --------------------------------------
|
||||
#ifndef HD44780_DDR_RS
|
||||
#define HD44780_DDR_RS TRISD
|
||||
#endif
|
||||
#ifndef HD44780_PORT_RS
|
||||
#define HD44780_PORT_RS PORTD
|
||||
#endif
|
||||
#ifndef HD44780_RS
|
||||
#define HD44780_RS 5
|
||||
#endif
|
||||
|
||||
// DATA port / pin
|
||||
// --------------------------------------
|
||||
#ifndef HD44780_DDR_DATA
|
||||
#define HD44780_DDR_DATA TRISB
|
||||
#endif
|
||||
#ifndef HD44780_PORT_DATA
|
||||
#define HD44780_PORT_DATA PORTB
|
||||
#endif
|
||||
#ifndef HD44780_PIN_DATA
|
||||
#define HD44780_PIN_DATA PORTB
|
||||
#endif
|
||||
// pins
|
||||
#ifndef HD44780_DATA7
|
||||
#define HD44780_DATA7 11 // LCD PORT DB7
|
||||
#endif
|
||||
#ifndef HD44780_DATA6
|
||||
#define HD44780_DATA6 10 // LCD PORT DB6
|
||||
#endif
|
||||
#ifndef HD44780_DATA5
|
||||
#define HD44780_DATA5 9 // LCD PORT DB5
|
||||
#endif
|
||||
#ifndef HD44780_DATA4
|
||||
#define HD44780_DATA4 3 // LCD PORT DB4
|
||||
#endif
|
||||
#ifndef HD44780_DATA3
|
||||
#define HD44780_DATA3 0 // LCD PORT DB3
|
||||
#endif
|
||||
#ifndef HD44780_DATA2
|
||||
#define HD44780_DATA2 0 // LCD PORT DB2
|
||||
#endif
|
||||
#ifndef HD44780_DATA1
|
||||
#define HD44780_DATA1 0 // LCD PORT DB1
|
||||
#endif
|
||||
#ifndef HD44780_DATA0
|
||||
#define HD44780_DATA0 0 // LCD PORT DB0
|
||||
#endif
|
||||
|
||||
// #endif
|
||||
|
||||
#define _delay_ms(x) Sleep(x)
|
||||
#define _delay_us(x) Sleep(1)
|
||||
|
||||
#define BIT7 0x80
|
||||
#define BIT6 0x40
|
||||
#define BIT5 0x20
|
||||
#define BIT4 0x10
|
||||
#define BIT3 0x08
|
||||
#define BIT2 0x04
|
||||
#define BIT1 0x02
|
||||
#define BIT0 0x01
|
||||
|
||||
#define HD44780_BUSY_FLAG HD44780_DATA7
|
||||
#define HD44780_INIT_SEQ 0x30
|
||||
#define HD44780_DISP_CLEAR 0x01
|
||||
#define HD44780_DISP_OFF 0x08
|
||||
#define HD44780_DISP_ON 0x0C
|
||||
#define HD44780_CURSOR_ON 0x0E
|
||||
#define HD44780_CURSOR_OFF 0x0C
|
||||
#define HD44780_CURSOR_BLINK 0x0F
|
||||
#define HD44780_RETURN_HOME 0x02
|
||||
#define HD44780_ENTRY_MODE 0x06
|
||||
#define HD44780_4BIT_MODE 0x20
|
||||
#define HD44780_8BIT_MODE 0x30
|
||||
#define HD44780_2_ROWS 0x08
|
||||
#define HD44780_FONT_5x8 0x00
|
||||
#define HD44780_FONT_5x10 0x04
|
||||
#define HD44780_POSITION 0x80
|
||||
|
||||
#define HD44780_SHIFT 0x10
|
||||
#define HD44780_CURSOR 0x00
|
||||
#define HD44780_DISPLAY 0x08
|
||||
#define HD44780_LEFT 0x00
|
||||
#define HD44780_RIGHT 0x04
|
||||
|
||||
#define HD44780_ROWS 2
|
||||
#define HD44780_COLS 16
|
||||
|
||||
#define HD44780_ROW1_START 0x00
|
||||
#define HD44780_ROW1_END HD44780_COLS
|
||||
#define HD44780_ROW2_START 0x40
|
||||
#define HD44780_ROW2_END HD44780_COLS
|
||||
|
||||
// **********************************************
|
||||
// !!!
|
||||
// MODE DEFINITION - CORRECTLY DEFINED
|
||||
//
|
||||
// ----------------------------------------------
|
||||
//
|
||||
// HD44780_4BIT_MODE - 4 bit mode / 4 data wires
|
||||
// HD44780_8BIT_MODE - 8 bit mode / 8 data wires
|
||||
//
|
||||
// **********************************************
|
||||
#define HD44780_MODE HD44780_4BIT_MODE
|
||||
|
||||
// set bit
|
||||
#define SETBIT(REG, BIT) { REG |= (1 << BIT); }
|
||||
// clear bit
|
||||
#define CLRBIT(REG, BIT) { REG &= ~(1 << BIT); }
|
||||
// set port / pin if bit is set
|
||||
#define SET_IF_BIT_IS_SET(REG, PORT, DATA, BIT) { if((DATA & BIT) > 0) { SETBIT(REG, PORT); } }
|
||||
|
||||
/**
|
||||
* @desc LCD init - initialisation routine
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_Init (void);
|
||||
|
||||
/**
|
||||
* @desc LCD display clear
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_DisplayClear (void);
|
||||
|
||||
/**
|
||||
* @desc LCD display on
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_DisplayOn (void);
|
||||
|
||||
/**
|
||||
* @desc LCD cursor on, display on
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CursorOn (void);
|
||||
|
||||
/**
|
||||
* @desc LCD cursor off
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CursorOff (void);
|
||||
|
||||
/**
|
||||
* @desc LCD cursor blink, cursor on, display on
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CursorBlink (void);
|
||||
|
||||
/**
|
||||
* @desc LCD draw char
|
||||
*
|
||||
* @param char
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_DrawChar (char character);
|
||||
|
||||
/**
|
||||
* @desc LCD draw string
|
||||
*
|
||||
* @param char *
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_DrawString (char *str);
|
||||
|
||||
/**
|
||||
* @desc Got to position x,y
|
||||
*
|
||||
* @param char
|
||||
* @param char
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
char HD44780_PositionXY (char x, char y);
|
||||
|
||||
/**
|
||||
* @desc Shift cursor / display to left / right
|
||||
*
|
||||
* @param char item {HD44780_CURSOR; HD44780_DISPLAY}
|
||||
* @param char direction {HD44780_RIGHT; HD44780_LEFT}
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
char HD44780_Shift (char item, char direction);
|
||||
|
||||
/**
|
||||
* @desc Check Busy Flag (BF) in 8 bit mode
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CheckBFin8bitMode (void);
|
||||
|
||||
/**
|
||||
* @desc Check Busy Flag (BF) in 4 bit mode
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_CheckBFin4bitMode (void);
|
||||
|
||||
/**
|
||||
* @desc LCD send instruction
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SendInstruction (unsigned short int);
|
||||
|
||||
/**
|
||||
* @desc LCD send data
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SendData (unsigned short int);
|
||||
|
||||
/**
|
||||
* @desc LCD send 4bits instruction in 4 bit mode
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_Send4bitsIn4bitMode (unsigned short int);
|
||||
|
||||
/**
|
||||
* @desc LCD send 8bits instruction in 4 bit mode
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_Send8bitsIn4bitMode (unsigned short int);
|
||||
|
||||
/**
|
||||
* @desc LCD send 8bits instruction in 8 bit mode
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_Send8bitsIn8bitMode (unsigned short int);
|
||||
|
||||
/**
|
||||
* @desc LCD send upper nibble
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SetUppNibble (unsigned short int);
|
||||
|
||||
/**
|
||||
* @desc LCD send lower nibble
|
||||
*
|
||||
* @param unsigned short int
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SetLowNibble (unsigned short int);
|
||||
|
||||
/**
|
||||
* @desc LCD pulse E
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_PulseE (void);
|
||||
|
||||
/**
|
||||
* @desc Set PORT DB4 to DB7
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SetPORT_DATA4to7 (void);
|
||||
|
||||
/**
|
||||
* @desc Set DDR DB4 to DB7
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_SetDDR_DATA4to7 (void);
|
||||
|
||||
/**
|
||||
* @desc Clear DDR DB4 to DB7
|
||||
*
|
||||
* @param void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void HD44780_ClearDDR_DATA4to7 (void);
|
||||
|
||||
#endif
|
||||
678
ChaloupeLora.X/Source/ina219.c
Normal file
678
ChaloupeLora.X/Source/ina219.c
Normal file
@ -0,0 +1,678 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file ina219.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
|
||||
@brief Driver for the TI INA219 current/power monitor
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
The INA219 is an I2C-based current/power monitor that monitors the
|
||||
voltage drop across a shunt resistor, as well as the supply voltage.
|
||||
|
||||
@section EXAMPLE
|
||||
@code
|
||||
ina219Init();
|
||||
|
||||
int16_t current = 0;
|
||||
int16_t power = 0;
|
||||
int16_t current_mA = 0;
|
||||
int16_t power_mW = 0;
|
||||
int16_t busvoltage = 0;
|
||||
int16_t shuntvoltage = 0;
|
||||
int16_t loadVoltage = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
shuntvoltage = ina219GetShuntVoltage();
|
||||
busvoltage = ina219GetBusVoltage();
|
||||
power = ina219GetPower();
|
||||
current = ina219GetCurrent();
|
||||
power_mW = ina219GetPower_mW();
|
||||
current_mA = ina219GetCurrent_mA();
|
||||
loadVoltage = busvoltage + (shuntvoltage / 100);
|
||||
printf("%-15s %6d = %d.%dmV (%duV) \r\n", "Shunt Voltage:", shuntvoltage, shuntvoltage / 100, shuntvoltage % 100, shuntvoltage * 10);
|
||||
printf("%-15s %6d = %d.%dV \r\n", "Bus Voltage:", busvoltage, busvoltage / 1000, busvoltage % 1000);
|
||||
printf("%-15s %6d = %d.%dV \r\n", "Load Voltage:", loadVoltage, loadVoltage / 1000, loadVoltage % 1000);
|
||||
printf("%-15s %6d = %dmW \r\n", "Power:", power, power_mW);
|
||||
printf("%-15s %6d = %dmA \r\n", "Current:", current, current_mA);
|
||||
printf("\r\n");
|
||||
systickDelay(5000);
|
||||
}
|
||||
@endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2012 Kevin Townsend
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#include "ina219.h"
|
||||
#include "I2C.h"
|
||||
#include <stdint.h>
|
||||
|
||||
unsigned char I2CMasterBuffer[I2C_BUFSIZE];
|
||||
unsigned char I2CSlaveBuffer[I2C_BUFSIZE];
|
||||
|
||||
// The following multipliers are used to convert raw current and power
|
||||
// values to mA and mW, taking into account the current config settings
|
||||
uint32_t ina219_currentDivider_mA = 0;
|
||||
uint32_t ina219_powerDivider_mW = 0;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sends a single command byte over I2C
|
||||
*/
|
||||
/**************************************************************************/
|
||||
static int ina219WriteRegister (uint8_t reg, uint16_t value)
|
||||
{
|
||||
// Clear write buffers
|
||||
uint32_t i;
|
||||
for ( i = 0; i < I2C_BUFSIZE; i++ )
|
||||
{
|
||||
I2CMasterBuffer[i] = 0x00;
|
||||
}
|
||||
|
||||
//I2CWriteLength = 4;
|
||||
// I2CReadLength = 0;
|
||||
I2CMasterBuffer[0] = INA219_ADDRESS; // I2C device address
|
||||
I2CMasterBuffer[1] = reg; // Register
|
||||
I2CMasterBuffer[2] = value >> 8; // Upper 8-bits
|
||||
I2CMasterBuffer[3] = value & 0xFF; // Lower 8-bits
|
||||
|
||||
return I2CWrite(I2CMasterBuffer,4);
|
||||
|
||||
|
||||
|
||||
//i2cEngine();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads a 16 bit values over I2C
|
||||
*/
|
||||
/**************************************************************************/
|
||||
static void ina219Read16(uint8_t reg, uint16_t *value)
|
||||
{
|
||||
// Clear write buffers
|
||||
int RET = RET_OK;
|
||||
uint32_t i;
|
||||
for ( i = 0; i < I2C_BUFSIZE; i++ )
|
||||
{
|
||||
I2CMasterBuffer[i] = 0x00;
|
||||
}
|
||||
|
||||
// I2CWriteLength = 2;
|
||||
//I2CReadLength = 2;
|
||||
I2CMasterBuffer[0] = INA219_ADDRESS; // I2C device address
|
||||
I2CMasterBuffer[1] = reg; // Command register
|
||||
// Append address w/read bit
|
||||
I2CMasterBuffer[2] = INA219_ADDRESS | INA219_READ;
|
||||
// i2cEngine();
|
||||
|
||||
I2CWrite(I2CMasterBuffer,2); //write pointer to the good register
|
||||
RET = I2CRead(I2CMasterBuffer[2],&I2CSlaveBuffer[0],2); //read the data
|
||||
|
||||
if(RET != RET_OK)
|
||||
{
|
||||
* value = 0;
|
||||
return;
|
||||
}
|
||||
// Shift values to create properly formed integer
|
||||
*value = ((I2CSlaveBuffer[0] << 8) | I2CSlaveBuffer[1]);
|
||||
}
|
||||
|
||||
void ina219SetCalibration_13V_10A(void)
|
||||
{
|
||||
// By default we use a pretty huge range for the input voltage,
|
||||
// which probably isn't the most appropriate choice for system
|
||||
// that don't use a lot of power. But all of the calculations
|
||||
// are shown below if you want to change the settings. You will
|
||||
// also need to change any relevant register settings, such as
|
||||
// setting the VBUS_MAX to 16V instead of 32V, etc.
|
||||
|
||||
// VBUS_MAX = 13V (Assumes 32V, can also be set to 16V)
|
||||
// VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04)
|
||||
// RSHUNT = 0.1 (Resistor value in ohms)
|
||||
|
||||
// 1. Determine max possible current
|
||||
// MaxPossible_I = VSHUNT_MAX / RSHUNT
|
||||
// MaxPossible_I = 3.2A
|
||||
|
||||
// 2. Determine max expected current
|
||||
// MaxExpected_I = 3.2A
|
||||
|
||||
// 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
|
||||
// MinimumLSB = MaxExpected_I/32767
|
||||
// MinimumLSB = 0.00009765 (98µA per bit)
|
||||
// MaximumLSB = MaxExpected_I/4096
|
||||
// MaximumLSB = 0,000488 (488µA per bit)
|
||||
|
||||
// 4. Choose an LSB between the min and max values
|
||||
// (Preferrably a roundish number close to MinLSB)
|
||||
// CurrentLSB = 0.0001 (100µA per bit)
|
||||
|
||||
// 5. Compute the calibration register
|
||||
// Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
|
||||
// Cal = 4096 (0x1000)
|
||||
|
||||
// 6. Calculate the power LSB
|
||||
// PowerLSB = 20 * CurrentLSB
|
||||
// PowerLSB = 0.002 (2mW per bit)
|
||||
|
||||
// 7. Compute the maximum current and shunt voltage values before overflow
|
||||
//
|
||||
// Max_Current = Current_LSB * 32767
|
||||
// Max_Current = 3.2767A before overflow
|
||||
//
|
||||
// If Max_Current > Max_Possible_I then
|
||||
// Max_Current_Before_Overflow = MaxPossible_I
|
||||
// Else
|
||||
// Max_Current_Before_Overflow = Max_Current
|
||||
// End If
|
||||
//
|
||||
// Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
|
||||
// Max_ShuntVoltage = 0.32V
|
||||
//
|
||||
// If Max_ShuntVoltage >= VSHUNT_MAX
|
||||
// Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
|
||||
// Else
|
||||
// Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
|
||||
// End If
|
||||
|
||||
// 8. Computer the Maximum Power
|
||||
// MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
|
||||
// MaximumPower = 3.2 * 32V
|
||||
// MaximumPower = 102.4W
|
||||
|
||||
// Set multipliers to convert raw current/power values
|
||||
ina219_currentDivider_mA = 10; // Current LSB = 100uA per bit (1000/100 = 10)
|
||||
ina219_powerDivider_mW = 2; // Power LSB = 1mW per bit (2/1)
|
||||
|
||||
// Set Calibration register to 'Cal' calculated above
|
||||
ina219WriteRegister(INA219_REG_CALIBRATION, 0x1000);
|
||||
|
||||
// Set Config register to take into account the settings above
|
||||
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
|
||||
INA219_CONFIG_GAIN_8_320MV |
|
||||
INA219_CONFIG_BADCRES_12BIT |
|
||||
INA219_CONFIG_SADCRES_12BIT_1S_532US |
|
||||
// INA219_CONFIG_MODE_SVOLT_CONTINUOUS;
|
||||
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
|
||||
|
||||
ina219WriteRegister(INA219_REG_CONFIG, config);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Configures to INA219 to be able to measure up to 32V and 2A
|
||||
of current. Each unit of current corresponds to 100uA, and
|
||||
each unit of power corresponds to 2mW. Counter overflow
|
||||
occurs at 3.2A.
|
||||
|
||||
@note These calculations assume a 0.1 ohm resistor is present
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void ina219SetCalibration_32V_2A(void)
|
||||
{
|
||||
// By default we use a pretty huge range for the input voltage,
|
||||
// which probably isn't the most appropriate choice for system
|
||||
// that don't use a lot of power. But all of the calculations
|
||||
// are shown below if you want to change the settings. You will
|
||||
// also need to change any relevant register settings, such as
|
||||
// setting the VBUS_MAX to 16V instead of 32V, etc.
|
||||
|
||||
// VBUS_MAX = 32V (Assumes 32V, can also be set to 16V)
|
||||
// VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04)
|
||||
// RSHUNT = 0.1 (Resistor value in ohms)
|
||||
|
||||
// 1. Determine max possible current
|
||||
// MaxPossible_I = VSHUNT_MAX / RSHUNT
|
||||
// MaxPossible_I = 3.2A
|
||||
|
||||
// 2. Determine max expected current
|
||||
// MaxExpected_I = 2.0A
|
||||
|
||||
// 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
|
||||
// MinimumLSB = MaxExpected_I/32767
|
||||
// MinimumLSB = 0.000061 (61µA per bit)
|
||||
// MaximumLSB = MaxExpected_I/4096
|
||||
// MaximumLSB = 0,000488 (488µA per bit)
|
||||
|
||||
// 4. Choose an LSB between the min and max values
|
||||
// (Preferrably a roundish number close to MinLSB)
|
||||
// CurrentLSB = 0.0001 (100µA per bit)
|
||||
|
||||
// 5. Compute the calibration register
|
||||
// Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
|
||||
// Cal = 4096 (0x1000)
|
||||
|
||||
// 6. Calculate the power LSB
|
||||
// PowerLSB = 20 * CurrentLSB
|
||||
// PowerLSB = 0.002 (2mW per bit)
|
||||
|
||||
// 7. Compute the maximum current and shunt voltage values before overflow
|
||||
//
|
||||
// Max_Current = Current_LSB * 32767
|
||||
// Max_Current = 3.2767A before overflow
|
||||
//
|
||||
// If Max_Current > Max_Possible_I then
|
||||
// Max_Current_Before_Overflow = MaxPossible_I
|
||||
// Else
|
||||
// Max_Current_Before_Overflow = Max_Current
|
||||
// End If
|
||||
//
|
||||
// Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
|
||||
// Max_ShuntVoltage = 0.32V
|
||||
//
|
||||
// If Max_ShuntVoltage >= VSHUNT_MAX
|
||||
// Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
|
||||
// Else
|
||||
// Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
|
||||
// End If
|
||||
|
||||
// 8. Computer the Maximum Power
|
||||
// MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
|
||||
// MaximumPower = 3.2 * 32V
|
||||
// MaximumPower = 102.4W
|
||||
|
||||
// Set multipliers to convert raw current/power values
|
||||
ina219_currentDivider_mA = 10; // Current LSB = 100uA per bit (1000/100 = 10)
|
||||
ina219_powerDivider_mW = 2; // Power LSB = 1mW per bit (2/1)
|
||||
|
||||
// Set Calibration register to 'Cal' calculated above
|
||||
ina219WriteRegister(INA219_REG_CALIBRATION, 0x1000);
|
||||
|
||||
// Set Config register to take into account the settings above
|
||||
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
|
||||
INA219_CONFIG_GAIN_8_320MV |
|
||||
INA219_CONFIG_BADCRES_12BIT |
|
||||
INA219_CONFIG_SADCRES_12BIT_1S_532US |
|
||||
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
|
||||
ina219WriteRegister(INA219_REG_CONFIG, config);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Configures to INA219 to be able to measure up to 32V and 1A
|
||||
of current. Each unit of current corresponds to 40uA, and each
|
||||
unit of power corresponds to 800µW. Counter overflow occurs at
|
||||
1.3A.
|
||||
|
||||
@note These calculations assume a 0.1 ohm resistor is present
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void ina219SetCalibration_32V_1A(void)
|
||||
{
|
||||
// By default we use a pretty huge range for the input voltage,
|
||||
// which probably isn't the most appropriate choice for system
|
||||
// that don't use a lot of power. But all of the calculations
|
||||
// are shown below if you want to change the settings. You will
|
||||
// also need to change any relevant register settings, such as
|
||||
// setting the VBUS_MAX to 16V instead of 32V, etc.
|
||||
|
||||
// VBUS_MAX = 32V (Assumes 32V, can also be set to 16V)
|
||||
// VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04)
|
||||
// RSHUNT = 0.1 (Resistor value in ohms)
|
||||
|
||||
// 1. Determine max possible current
|
||||
// MaxPossible_I = VSHUNT_MAX / RSHUNT
|
||||
// MaxPossible_I = 3.2A
|
||||
|
||||
// 2. Determine max expected current
|
||||
// MaxExpected_I = 1.0A
|
||||
|
||||
// 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
|
||||
// MinimumLSB = MaxExpected_I/32767
|
||||
// MinimumLSB = 0.0000305 (30.5µA per bit)
|
||||
// MaximumLSB = MaxExpected_I/4096
|
||||
// MaximumLSB = 0.000244 (244µA per bit)
|
||||
|
||||
// 4. Choose an LSB between the min and max values
|
||||
// (Preferrably a roundish number close to MinLSB)
|
||||
// CurrentLSB = 0.0000400 (40µA per bit)
|
||||
|
||||
// 5. Compute the calibration register
|
||||
// Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
|
||||
// Cal = 10240 (0x2800)
|
||||
|
||||
// 6. Calculate the power LSB
|
||||
// PowerLSB = 20 * CurrentLSB
|
||||
// PowerLSB = 0.0008 (800µW per bit)
|
||||
|
||||
// 7. Compute the maximum current and shunt voltage values before overflow
|
||||
//
|
||||
// Max_Current = Current_LSB * 32767
|
||||
// Max_Current = 1.31068A before overflow
|
||||
//
|
||||
// If Max_Current > Max_Possible_I then
|
||||
// Max_Current_Before_Overflow = MaxPossible_I
|
||||
// Else
|
||||
// Max_Current_Before_Overflow = Max_Current
|
||||
// End If
|
||||
//
|
||||
// ... In this case, we're good though since Max_Current is less than MaxPossible_I
|
||||
//
|
||||
// Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
|
||||
// Max_ShuntVoltage = 0.131068V
|
||||
//
|
||||
// If Max_ShuntVoltage >= VSHUNT_MAX
|
||||
// Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
|
||||
// Else
|
||||
// Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
|
||||
// End If
|
||||
|
||||
// 8. Computer the Maximum Power
|
||||
// MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
|
||||
// MaximumPower = 1.31068 * 32V
|
||||
// MaximumPower = 41.94176W
|
||||
|
||||
// Set multipliers to convert raw current/power values
|
||||
ina219_currentDivider_mA = 25; // Current LSB = 40uA per bit (1000/40 = 25)
|
||||
ina219_powerDivider_mW = 1; // Power LSB = 800µW per bit
|
||||
|
||||
// Set Calibration register to 'Cal' calculated above
|
||||
ina219WriteRegister(INA219_REG_CALIBRATION, 0x2800);
|
||||
|
||||
// Set Config register to take into account the settings above
|
||||
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
|
||||
INA219_CONFIG_GAIN_8_320MV |
|
||||
INA219_CONFIG_BADCRES_12BIT |
|
||||
INA219_CONFIG_SADCRES_12BIT_1S_532US |
|
||||
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
|
||||
ina219WriteRegister(INA219_REG_CONFIG, config);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Configures to INA219 to be able to measure up to 16V and 500mA
|
||||
of current. Each unit of current corresponds to 25uA, and each
|
||||
unit of power corresponds to 500µW. Counter overflow occurs at
|
||||
800mA.
|
||||
|
||||
@note These calculations assume a 0.1 ohm resistor is present
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void ina219SetCalibration_16V_500mA(void)
|
||||
{
|
||||
// VBUS_MAX = 16V
|
||||
// VSHUNT_MAX = 0.08 (Assumes Gain 2, 80mV, can also be 0.32, 0.16, 0.04)
|
||||
// RSHUNT = 0.1 (Resistor value in ohms)
|
||||
|
||||
// 1. Determine max possible current
|
||||
// MaxPossible_I = VSHUNT_MAX / RSHUNT
|
||||
// MaxPossible_I = 0.8A
|
||||
|
||||
// 2. Determine max expected current
|
||||
// MaxExpected_I = 0.5A
|
||||
|
||||
// 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
|
||||
// MinimumLSB = MaxExpected_I/32767
|
||||
// MinimumLSB = 0.0000153 (15.3µA per bit)
|
||||
// MaximumLSB = MaxExpected_I/4096
|
||||
// MaximumLSB = 0.0001221 (122µA per bit)
|
||||
|
||||
// 4. Choose an LSB between the min and max values
|
||||
// (Preferrably a roundish number close to MinLSB)
|
||||
// CurrentLSB = 0.0000250 (25µA per bit)
|
||||
|
||||
// 5. Compute the calibration register
|
||||
// Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
|
||||
// Cal = 16384 (0x4000)
|
||||
|
||||
// 6. Calculate the power LSB
|
||||
// PowerLSB = 20 * CurrentLSB
|
||||
// PowerLSB = 0.0005 (500µW per bit)
|
||||
|
||||
// 7. Compute the maximum current and shunt voltage values before overflow
|
||||
//
|
||||
// Max_Current = Current_LSB * 32767
|
||||
// Max_Current = 0.819175 (819 mA before overflow)
|
||||
//
|
||||
// If Max_Current > Max_Possible_I then
|
||||
// Max_Current_Before_Overflow = MaxPossible_I
|
||||
// Else
|
||||
// Max_Current_Before_Overflow = Max_Current
|
||||
// End If
|
||||
//
|
||||
// Max_Current_Before_Overflow = 0.8A
|
||||
//
|
||||
// Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
|
||||
// Max_ShuntVoltage = 0.8 * 0.1
|
||||
// Max_ShuntVoltage = 0.08V
|
||||
//
|
||||
// If Max_ShuntVoltage >= VSHUNT_MAX
|
||||
// Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
|
||||
// Else
|
||||
// Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
|
||||
// End If
|
||||
|
||||
// 8. Computer the Maximum Power
|
||||
// MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
|
||||
// MaximumPower = 0.8 * 16V
|
||||
// MaximumPower = 12.8W
|
||||
|
||||
// Set multipliers to convert raw current/power values
|
||||
ina219_currentDivider_mA = 40; // Current LSB = 25uA per bit (1000/25 = 40)
|
||||
ina219_powerDivider_mW = 1; // Power LSB = 500µW per bit
|
||||
|
||||
// Set Calibration register to 'Cal' calculated above
|
||||
ina219WriteRegister(INA219_REG_CALIBRATION, 0x4000);
|
||||
|
||||
// Set Config register to take into account the settings above
|
||||
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V |
|
||||
INA219_CONFIG_GAIN_2_80MV |
|
||||
INA219_CONFIG_BADCRES_12BIT |
|
||||
INA219_CONFIG_SADCRES_12BIT_1S_532US |
|
||||
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
|
||||
ina219WriteRegister(INA219_REG_CONFIG, config);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Configures to INA219 to be able to measure up to 16V and 200mA
|
||||
of current. Each unit of current corresponds to 10uA, and each
|
||||
unit of power corresponds to 200µW. Counter overflow occurs at
|
||||
327mA.
|
||||
|
||||
@note These calculations assume a 0.1 ohm resistor is present
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void ina219SetCalibration_16V_200mA(void)
|
||||
{
|
||||
// VBUS_MAX = 16V
|
||||
// VSHUNT_MAX = 0.04 (Assumes Gain 1, 40mV, can also be 0.32, 0.16, 0.08)
|
||||
// RSHUNT = 0.1 (Resistor value in ohms)
|
||||
|
||||
// 1. Determine max possible current
|
||||
// MaxPossible_I = VSHUNT_MAX / RSHUNT
|
||||
// MaxPossible_I = 0.4A
|
||||
|
||||
// 2. Determine max expected current
|
||||
// MaxExpected_I = 0.2A
|
||||
|
||||
// 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
|
||||
// MinimumLSB = MaxExpected_I/32767
|
||||
// MinimumLSB = 0.000006104 (6.104µA per bit)
|
||||
// MaximumLSB = MaxExpected_I/4096
|
||||
// MaximumLSB = 0,000048828 (48.82µA per bit)
|
||||
|
||||
// 4. Choose an LSB between the min and max values
|
||||
// CurrentLSB = 0.000010 (10µA per bit)
|
||||
|
||||
// 5. Compute the calibration register
|
||||
// Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
|
||||
// Cal = 40960 (0xA000)
|
||||
|
||||
// 6. Calculate the power LSB
|
||||
// PowerLSB = 20 * CurrentLSB
|
||||
// PowerLSB = 0.0002 (200µW per bit)
|
||||
|
||||
// 7. Compute the maximum current and shunt voltage values before overflow
|
||||
//
|
||||
// Max_Current = Current_LSB * 32767
|
||||
// Max_Current = 0.32767 (328 mA before overflow)
|
||||
//
|
||||
// If Max_Current > Max_Possible_I then
|
||||
// Max_Current_Before_Overflow = MaxPossible_I
|
||||
// Else
|
||||
// Max_Current_Before_Overflow = Max_Current
|
||||
// End If
|
||||
//
|
||||
// Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
|
||||
// Max_ShuntVoltage = 0.032767V
|
||||
//
|
||||
// If Max_ShuntVoltage >= VSHUNT_MAX
|
||||
// Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
|
||||
// Else
|
||||
// Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
|
||||
// End If
|
||||
|
||||
// 8. Computer the Maximum Power
|
||||
// MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
|
||||
// MaximumPower = 0.32767 * 16V
|
||||
// MaximumPower = 5.24W
|
||||
|
||||
// Set multipliers to convert raw current/power values
|
||||
ina219_currentDivider_mA = 100; // Current LSB = 10uA per bit (1000/10 = 100)
|
||||
ina219_powerDivider_mW = 1; // Power LSB = 200µW per bit
|
||||
|
||||
// Set Calibration register to 'Cal' calculated above
|
||||
ina219WriteRegister(INA219_REG_CALIBRATION, 0xA000);
|
||||
|
||||
// Set Config register to take into account the settings above
|
||||
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V |
|
||||
INA219_CONFIG_GAIN_1_40MV |
|
||||
INA219_CONFIG_BADCRES_12BIT |
|
||||
INA219_CONFIG_SADCRES_12BIT_1S_532US |
|
||||
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
|
||||
ina219WriteRegister(INA219_REG_CONFIG, config);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the I2C block
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int ina219Init(void)
|
||||
{
|
||||
int RET = RET_OK;
|
||||
uint16_t ReadBack;
|
||||
// Reset INA219 (set to default values)
|
||||
RET = ina219WriteRegister(INA219_REG_CONFIG, INA219_CONFIG_RESET);
|
||||
ina219Read16(INA219_REG_CONFIG,&ReadBack);
|
||||
|
||||
if(ReadBack != INA219_CONFIG_RESET_READBACK)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Setup chip for 32V and 2A by default
|
||||
// ina219SetCalibration_32V_2A();
|
||||
ina219SetCalibration_13V_10A();
|
||||
|
||||
return RET;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the shunt voltage (16-bit signed integer, so +-32767)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int16_t ina219GetShuntVoltage(void)
|
||||
{
|
||||
uint16_t value;
|
||||
ina219Read16(INA219_REG_SHUNTVOLTAGE, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the shunt voltage (16-bit signed integer, so +-32767)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int16_t ina219GetBusVoltage(void)
|
||||
{
|
||||
uint16_t value;
|
||||
ina219Read16(INA219_REG_BUSVOLTAGE, &value);
|
||||
// Shift to the right 3 to drop CNVR and OVF and then multiply by LSB
|
||||
return (value >> 3) * 4;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the raw power value (16-bit signed integer, so +-32767)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int16_t ina219GetPower(void)
|
||||
{
|
||||
uint16_t value;
|
||||
ina219Read16(INA219_REG_POWER, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the power value in mW, taking into account the config
|
||||
settings and power LSB
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int16_t ina219GetPower_mW(void)
|
||||
{
|
||||
uint16_t value;
|
||||
ina219Read16(INA219_REG_POWER, &value);
|
||||
return value / ina219_powerDivider_mW;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the raw current value (16-bit signed integer, so +-32767)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int16_t ina219GetCurrent(void)
|
||||
{
|
||||
uint16_t value;
|
||||
ina219Read16(INA219_REG_CURRENT, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the current value in mA, taking into account the
|
||||
config settings and current LSB
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int16_t ina219GetCurrent_mA(void)
|
||||
{
|
||||
uint16_t value;
|
||||
ina219Read16(INA219_REG_CURRENT, &value);
|
||||
return value / ina219_currentDivider_mA;
|
||||
}
|
||||
|
||||
|
||||
141
ChaloupeLora.X/Source/ina219.h
Normal file
141
ChaloupeLora.X/Source/ina219.h
Normal file
@ -0,0 +1,141 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file ina219.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2012 Kevin Townsend
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _INA219_H_
|
||||
#define _INS219_H_
|
||||
|
||||
#include "define.h"
|
||||
//#include "projectconfig.h"
|
||||
//#include "core/i2c/i2c.h"
|
||||
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
I2C ADDRESS/BITS
|
||||
-----------------------------------------------------------------------*/
|
||||
#define INA219_ADDRESS (0x80) // 1000000x (A0+A1=GND)
|
||||
#define INA219_READ (0x01)
|
||||
/*=========================================================================*/
|
||||
|
||||
/*=========================================================================
|
||||
CONFIG REGISTER (R/W)
|
||||
-----------------------------------------------------------------------*/
|
||||
#define INA219_REG_CONFIG (0x00)
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define INA219_CONFIG_RESET (0x8000) // Reset Bit
|
||||
#define INA219_CONFIG_RESET_READBACK 0x39FF
|
||||
|
||||
#define INA219_CONFIG_BVOLTAGERANGE_MASK (0x4000) // Bus Voltage Range Mask
|
||||
#define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range
|
||||
#define INA219_CONFIG_BVOLTAGERANGE_32V (0x4000) // 0-32V Range
|
||||
|
||||
#define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask
|
||||
#define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range
|
||||
#define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range
|
||||
#define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range
|
||||
#define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range
|
||||
|
||||
#define INA219_CONFIG_BADCRES_MASK (0x0780) // Bus ADC Resolution Mask
|
||||
#define INA219_CONFIG_BADCRES_9BIT (0x0080) // 9-bit bus res = 0..511
|
||||
#define INA219_CONFIG_BADCRES_10BIT (0x0100) // 10-bit bus res = 0..1023
|
||||
#define INA219_CONFIG_BADCRES_11BIT (0x0200) // 11-bit bus res = 0..2047
|
||||
#define INA219_CONFIG_BADCRES_12BIT (0x0400) // 12-bit bus res = 0..4097
|
||||
|
||||
#define INA219_CONFIG_SADCRES_MASK (0x0078) // Shunt ADC Resolution and Averaging Mask
|
||||
#define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample
|
||||
#define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample
|
||||
#define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample
|
||||
#define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample
|
||||
#define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together
|
||||
|
||||
#define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask
|
||||
#define INA219_CONFIG_MODE_POWERDOWN (0x0000)
|
||||
#define INA219_CONFIG_MODE_SVOLT_TRIGGERED (0x0001)
|
||||
#define INA219_CONFIG_MODE_BVOLT_TRIGGERED (0x0002)
|
||||
#define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED (0x0003)
|
||||
#define INA219_CONFIG_MODE_ADCOFF (0x0004)
|
||||
#define INA219_CONFIG_MODE_SVOLT_CONTINUOUS (0x0005)
|
||||
#define INA219_CONFIG_MODE_BVOLT_CONTINUOUS (0x0006)
|
||||
#define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS (0x0007)
|
||||
/*=========================================================================*/
|
||||
|
||||
/*=========================================================================
|
||||
SHUNT VOLTAGE REGISTER (R)
|
||||
-----------------------------------------------------------------------*/
|
||||
#define INA219_REG_SHUNTVOLTAGE (0x01)
|
||||
/*=========================================================================*/
|
||||
|
||||
/*=========================================================================
|
||||
BUS VOLTAGE REGISTER (R)
|
||||
-----------------------------------------------------------------------*/
|
||||
#define INA219_REG_BUSVOLTAGE (0x02)
|
||||
/*=========================================================================*/
|
||||
|
||||
/*=========================================================================
|
||||
POWER REGISTER (R)
|
||||
-----------------------------------------------------------------------*/
|
||||
#define INA219_REG_POWER (0x03)
|
||||
/*=========================================================================*/
|
||||
|
||||
/*=========================================================================
|
||||
CURRENT REGISTER (R)
|
||||
-----------------------------------------------------------------------*/
|
||||
#define INA219_REG_CURRENT (0x04)
|
||||
/*=========================================================================*/
|
||||
|
||||
/*=========================================================================
|
||||
CALIBRATION REGISTER (R/W)
|
||||
-----------------------------------------------------------------------*/
|
||||
#define INA219_REG_CALIBRATION (0x05)
|
||||
/*=========================================================================*/
|
||||
|
||||
int ina219Init(void);
|
||||
int16_t ina219GetShuntVoltage(void);
|
||||
int16_t ina219GetBusVoltage(void);
|
||||
int16_t ina219GetPower(void);
|
||||
int16_t ina219GetPower_mW(void);
|
||||
int16_t ina219GetCurrent(void);
|
||||
int16_t ina219GetCurrent_mA(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
75
ChaloupeLora.X/Source/interrupts.c
Normal file
75
ChaloupeLora.X/Source/interrupts.c
Normal file
@ -0,0 +1,75 @@
|
||||
/******************************************************************************/
|
||||
/* Files to Include */
|
||||
/******************************************************************************/
|
||||
|
||||
#include <plib.h> /* Include to use PIC32 peripheral libraries */
|
||||
#include <sys/attribs.h> /* For __ISR definition */
|
||||
#include <stdint.h> /* For uint32_t definition */
|
||||
#include <stdbool.h> /* For true/false definition */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Interrupt Vector Options */
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* VECTOR NAMES: */
|
||||
/* */
|
||||
/* _CORE_TIMER_VECTOR _COMPARATOR_2_VECTOR */
|
||||
/* _CORE_SOFTWARE_0_VECTOR _UART_2A_VECTOR */
|
||||
/* _CORE_SOFTWARE_1_VECTOR _I2C_2A_VECTOR */
|
||||
/* _EXTERNAL_0_VECTOR _SPI_2_VECTOR */
|
||||
/* _TIMER_1_VECTOR _SPI_2A_VECTOR */
|
||||
/* _INPUT_CAPTURE_1_VECTOR _I2C_4_VECTOR */
|
||||
/* _OUTPUT_COMPARE_1_VECTOR _UART_3_VECTOR */
|
||||
/* _EXTERNAL_1_VECTOR _UART_2_VECTOR */
|
||||
/* _TIMER_2_VECTOR _SPI_3A_VECTOR */
|
||||
/* _INPUT_CAPTURE_2_VECTOR _I2C_3A_VECTOR */
|
||||
/* _OUTPUT_COMPARE_2_VECTOR _UART_3A_VECTOR */
|
||||
/* _EXTERNAL_2_VECTOR _SPI_4_VECTOR */
|
||||
/* _TIMER_3_VECTOR _I2C_5_VECTOR */
|
||||
/* _INPUT_CAPTURE_3_VECTOR _I2C_2_VECTOR */
|
||||
/* _OUTPUT_COMPARE_3_VECTOR _FAIL_SAFE_MONITOR_VECTOR */
|
||||
/* _EXTERNAL_3_VECTOR _RTCC_VECTOR */
|
||||
/* _TIMER_4_VECTOR _DMA_0_VECTOR */
|
||||
/* _INPUT_CAPTURE_4_VECTOR _DMA_1_VECTOR */
|
||||
/* _OUTPUT_COMPARE_4_VECTOR _DMA_2_VECTOR */
|
||||
/* _EXTERNAL_4_VECTOR _DMA_3_VECTOR */
|
||||
/* _TIMER_5_VECTOR _DMA_4_VECTOR */
|
||||
/* _INPUT_CAPTURE_5_VECTOR _DMA_5_VECTOR */
|
||||
/* _OUTPUT_COMPARE_5_VECTOR _DMA_6_VECTOR */
|
||||
/* _SPI_1_VECTOR _DMA_7_VECTOR */
|
||||
/* _I2C_3_VECTOR _FCE_VECTOR */
|
||||
/* _UART_1A_VECTOR _USB_1_VECTOR */
|
||||
/* _UART_1_VECTOR _CAN_1_VECTOR */
|
||||
/* _SPI_1A_VECTOR _CAN_2_VECTOR */
|
||||
/* _I2C_1A_VECTOR _ETH_VECTOR */
|
||||
/* _SPI_3_VECTOR _UART_4_VECTOR */
|
||||
/* _I2C_1_VECTOR _UART_1B_VECTOR */
|
||||
/* _CHANGE_NOTICE_VECTOR _UART_6_VECTOR */
|
||||
/* _ADC_VECTOR _UART_2B_VECTOR */
|
||||
/* _PMP_VECTOR _UART_5_VECTOR */
|
||||
/* _COMPARATOR_1_VECTOR _UART_3B_VECTOR */
|
||||
/* */
|
||||
/* Refer to the device specific .h file in the C32 Compiler */
|
||||
/* pic32mx\include\proc directory for a complete Vector and IRQ mnemonic */
|
||||
/* listings for the PIC32 device. */
|
||||
/* */
|
||||
/* PRIORITY OPTIONS: */
|
||||
/* */
|
||||
/* (default) IPL0AUTO, IPL1, IPL2, ... IPL7 (highest) */
|
||||
/* */
|
||||
/* Example Shorthand Syntax */
|
||||
/* */
|
||||
/* void __ISR(<Vector Name>,<PRIORITY>) user_interrupt_routine_name(void) */
|
||||
/* { */
|
||||
/* <Clear Interrupt Flag> */
|
||||
/* } */
|
||||
/* */
|
||||
/* For more interrupt macro examples refer to the C compiler User Guide in */
|
||||
/* the C compiler /doc directory. */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
/* Interrupt Routines */
|
||||
/******************************************************************************/
|
||||
|
||||
/* TODO Add interrupt routine code here. */
|
||||
|
||||
239
ChaloupeLora.X/Source/main.c
Normal file
239
ChaloupeLora.X/Source/main.c
Normal file
@ -0,0 +1,239 @@
|
||||
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
### 20120515 JFM
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
//JFM WINC TODO
|
||||
|
||||
|
||||
#include "define.h"
|
||||
|
||||
|
||||
#include "Uart.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "timer.h"
|
||||
#include "Watchdog.h"
|
||||
//#include "PWMCtrl.h"
|
||||
//#include "KnobEncoderCtrl.h"
|
||||
//#include "LedLightCtrl.h"
|
||||
//#include "PrintfServer.h"
|
||||
|
||||
//#include "MasterCtrlInterface.h"
|
||||
//#include "SDCardMgr.h"
|
||||
//#include "FatFS/ff.h"
|
||||
#include "main.h"
|
||||
#include "NetworkProtocol.h"
|
||||
#include "ChaletPowerRelay.h"
|
||||
#include "BatteryMonitor.h"
|
||||
#include "CurrentSensor.h"
|
||||
#include "I2C.h"
|
||||
#include "SPI_Flash.h"
|
||||
#include "TemperatureSensor.h"
|
||||
#include "LoraWatchdog.h"
|
||||
|
||||
|
||||
#include "BootloaderInterface.h"
|
||||
|
||||
|
||||
//#define NO_WIFI
|
||||
#ifndef NO_WIFI
|
||||
#include "Terminal.h"
|
||||
#include "WiFiCtrl.h"
|
||||
#include "InternalUart.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_PRINTF
|
||||
void _mon_putc(char c); //override from stdio to redirect stdout on uart 3B
|
||||
#elif defined USE_SYSLOG
|
||||
#include "Syslog.h"
|
||||
void _mon_putc(char c); //override from stdio to redirect stdout on uart 3B
|
||||
#endif
|
||||
|
||||
#define HEARTBEAT_LED_TIMEOUT 400
|
||||
#define VOLTS_PER_BITS (float)3.3/1023
|
||||
|
||||
static void InitializeBoard(void);
|
||||
|
||||
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF, WDTPS = PS4096 //Watchdog timeout = 4,096s
|
||||
#pragma config POSCMOD = EC, FNOSC = PRIPLL, FPBDIV = DIV_1
|
||||
//#pragma config POSCMOD = XT, FNOSC = PRIPLL, FPBDIV = DIV_1
|
||||
#pragma config ICESEL = ICS_PGx2, BWP = OFF
|
||||
#pragma config FSOSCEN = OFF
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int mRetCode = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); //Use peripheral library to optimize configuration
|
||||
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);// configure for multi-vectored mode interrupts
|
||||
OSCCONbits.SOSCEN = 0;
|
||||
|
||||
#ifndef __32MX330F064H__
|
||||
AD1PCFG = 0xFFFF; //Sart with I/O pins configured as digital I/O
|
||||
#endif
|
||||
|
||||
InitBoard();
|
||||
INTEnableInterrupts();
|
||||
|
||||
TimerInit();
|
||||
InitWatchdog();
|
||||
// I2CInit();
|
||||
InitChaletPowerRelay();
|
||||
InitBatteryMonitor();
|
||||
InitHarakiriRelay();
|
||||
InitTempSensor();
|
||||
|
||||
|
||||
InitUart();
|
||||
ProtocolInit();
|
||||
InitLoraWatchdog();
|
||||
|
||||
InitSPIFlash();
|
||||
|
||||
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
InitSyslog();
|
||||
#endif
|
||||
|
||||
|
||||
printf("ChaletDuino V2 Initialized\n");
|
||||
|
||||
SPIFlashCheckAndConfigure();
|
||||
TempSensorCheckAndConfigure();
|
||||
|
||||
BootloaderInterfaceInit();
|
||||
|
||||
|
||||
// SPIFlashErase64KSector(0x180000,1);
|
||||
//
|
||||
// unsigned char test[100];
|
||||
// int i = 0;
|
||||
//
|
||||
// for(i = 0; i < 100; i++)
|
||||
// {
|
||||
// test[i] = i;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// SPIFlashWriteBuffer(test,100,0x180000);
|
||||
//
|
||||
// for(i = 0; i < 100; i++)
|
||||
// {
|
||||
// test[i] = 0;
|
||||
// }
|
||||
//
|
||||
// SPIFlashReadBuffer(test,100,0x180000);
|
||||
//
|
||||
|
||||
|
||||
#ifndef NO_WIFI
|
||||
InitTerminal();
|
||||
|
||||
InitWiFi();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// unsigned int bw;
|
||||
|
||||
// FRESULT res;
|
||||
// res = f_mount(&FatFs, "", 0); /* Give a work area to the default drive */
|
||||
// if(!res)
|
||||
// {
|
||||
// printf("Could not mount SD card\n");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// printf("SD Card mounted successfuly");
|
||||
// }
|
||||
//
|
||||
// if (f_open(&File[0], "newfile.txt", FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) /* Create a file */
|
||||
//// {
|
||||
//
|
||||
// res = f_write(&File[0], "It works!\r\n", 11, &bw); /* Write data to the file */
|
||||
//
|
||||
// res = f_close(&File[0]); /* Close the file */
|
||||
//
|
||||
// }
|
||||
|
||||
// int res = OpenPrintfServer();
|
||||
|
||||
TimerStart(HEARTBEAT_LED_TMR,HEARTBEAT_LED_TIMEOUT);
|
||||
|
||||
|
||||
|
||||
|
||||
// printf("Lora Monitor Started\n");
|
||||
printf("test %d\n", 1);
|
||||
|
||||
EnableWatchdog();
|
||||
KickWatchdog();
|
||||
mRetCode = 1;
|
||||
|
||||
|
||||
|
||||
while(mRetCode == 1)
|
||||
{
|
||||
|
||||
KickWatchdog();
|
||||
|
||||
#ifndef NO_WIFI
|
||||
TickWiFi();
|
||||
#endif
|
||||
TickTerminal();
|
||||
UartTick();
|
||||
ChaletPowerRelayTick();
|
||||
BatteryMonitorTick();
|
||||
SyslogTick();
|
||||
TickTempSensor();
|
||||
BootloaderInterfaceTick();
|
||||
TickLoraWatchdog();
|
||||
|
||||
if(IsTimerExpired(HEARTBEAT_LED_TMR))
|
||||
{
|
||||
HEARTBEAT_LED_2_PIN = ~HEARTBEAT_LED_2_PIN;
|
||||
TimerStart(HEARTBEAT_LED_TMR,HEARTBEAT_LED_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
return mRetCode;
|
||||
}
|
||||
|
||||
|
||||
void InitializeBoard()
|
||||
{
|
||||
InitBoard();
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_PRINTF
|
||||
void _mon_putc(char c)
|
||||
{
|
||||
U2TXREG = c;
|
||||
while (U2STAbits.TRMT==0);
|
||||
}
|
||||
#elif defined USE_SYSLOG
|
||||
void _mon_putc(char c)
|
||||
{
|
||||
SyslogNewByte(c);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//EOF
|
||||
|
||||
165
ChaloupeLora.X/Source/main.h
Normal file
165
ChaloupeLora.X/Source/main.h
Normal file
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief MAIN configuration.
|
||||
*
|
||||
* Copyright (c) 2015 - 2018 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAIN_H_INCLUDED
|
||||
#define MAIN_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#include "driver/include/m2m_wifi.h"
|
||||
//
|
||||
//// <<< Use Configuration Wizard in Context Menu >>>
|
||||
////<h> General network settings in AP (access point) mode
|
||||
//// <s> Network SSID
|
||||
//// <id> app_main_m2m_device_name
|
||||
//#ifndef MAIN_M2M_SSID
|
||||
//#define MAIN_M2M_SSID "WINC1500_00:00"
|
||||
//#endif
|
||||
//
|
||||
//// <o> Security type
|
||||
//// <1=> Wi-Fi network is not secured
|
||||
//// <2=> WPA/WPA2 personal(PSK)
|
||||
//// <3=> WEP (40 or 104) OPEN OR SHARED
|
||||
//// <4=> WPA/WPA2 Enterprise.IEEE802.1x
|
||||
//// <id> app_main_m2m_ap_sec
|
||||
//#ifndef MAIN_M2M_AP_SEC
|
||||
//#define MAIN_M2M_AP_SEC 1
|
||||
//#endif
|
||||
//
|
||||
//// <s> Security key
|
||||
//// <id> app_main_m2m_ap_key
|
||||
//#ifndef MAIN_M2M_AP_KEY
|
||||
//#define MAIN_M2M_AP_KEY "12345FFFFF"
|
||||
//#endif
|
||||
//
|
||||
//// <o> SSID mode
|
||||
//// <0=>SSID is visible to others
|
||||
//// <1=>SSID is hidden
|
||||
//// <id> app_main_m2m_ap_ssid_mode
|
||||
//#ifndef MAIN_M2M_AP_SSID_MODE
|
||||
//#define MAIN_M2M_AP_SSID_MODE 0
|
||||
//#endif
|
||||
////</h>
|
||||
////<h> DHCP server IP address in AP (access point) mode
|
||||
//// <o> DHCP server IP address 1 <0-255>
|
||||
//// <id> app_ip_address_1
|
||||
//#ifndef DHCP_IP_ADDRESS_1
|
||||
//#define DHCP_IP_ADDRESS_1 192
|
||||
//#endif
|
||||
//
|
||||
//// <o> DHCP server IP address 2 <0-255>
|
||||
//// <id> app_ip_address_2
|
||||
//#ifndef DHCP_IP_ADDRESS_2
|
||||
//#define DHCP_IP_ADDRESS_2 168
|
||||
//#endif
|
||||
//
|
||||
//// <o> DHCP server IP address 3 <0-255>
|
||||
//// <id> app_ip_address_3
|
||||
//#ifndef DHCP_IP_ADDRESS_3
|
||||
//#define DHCP_IP_ADDRESS_3 1
|
||||
//#endif
|
||||
//
|
||||
//// <o> DHCP server IP address 4 <0-255>
|
||||
//// <id> app_ip_address_4
|
||||
//#ifndef DHCP_IP_ADDRESS_4
|
||||
//#define DHCP_IP_ADDRESS_4 1
|
||||
//#endif
|
||||
////</h>
|
||||
//// <<< end of configuration section >>>
|
||||
//
|
||||
///** Using broadcast address for simplicity. */
|
||||
//#define MAIN_SERVER_PORT (80)
|
||||
//
|
||||
///** Using IP address. */
|
||||
//#define IPV4_BYTE(val, index) ((val >> (index * 8)) & 0xFF)
|
||||
//
|
||||
///** Send buffer of TCP socket. */
|
||||
//#define MAIN_PREFIX_BUFFER "GET /data/2.5/weather?q="
|
||||
//#define MAIN_POST_BUFFER \
|
||||
// "&mode=xml&units=metric&appid=c592e14137c3471fa9627b44f6649db4 HTTP/1.1\r\nHost: " \
|
||||
// "api.openweathermap.org\r\nAccept: */*\r\n\r\n"
|
||||
///** Weather information provider server. */
|
||||
//#define MAIN_WEATHER_SERVER_NAME "openweathermap.org"
|
||||
//
|
||||
///** Input City Name. */
|
||||
//#define MAIN_CITY_NAME "london"
|
||||
//
|
||||
///** Receive buffer size. */
|
||||
//#define MAIN_WIFI_M2M_BUFFER_SIZE 1024
|
||||
//
|
||||
//#define MAIN_M2M_DHCP_SERVER_IP \
|
||||
// { \
|
||||
// DHCP_IP_ADDRESS_1, DHCP_IP_ADDRESS_2, DHCP_IP_ADDRESS_3, DHCP_IP_ADDRESS_4 \
|
||||
// }
|
||||
//#define MAIN_HTTP_PROV_SERVER_DOMAIN_NAME "atmel.com"
|
||||
//
|
||||
//#define MAIN_MAC_ADDRESS \
|
||||
// { \
|
||||
// 0xf8, 0xf0, 0x05, 0x45, 0xD4, 0x84 \
|
||||
// }
|
||||
//
|
||||
//#define MAIN_HEX2ASCII(x) (((x) >= 10) ? (((x)-10) + 'A') : ((x) + '0'))
|
||||
//
|
||||
//#define TEMPERATURE_ABS(a) (((a) > 0) ? (a) : -(a))
|
||||
//
|
||||
//static tstrM2MAPConfig gstrM2MAPConfig = {MAIN_M2M_SSID,
|
||||
// 1,
|
||||
// 0,
|
||||
// sizeof(MAIN_M2M_AP_KEY) - 1,
|
||||
// MAIN_M2M_AP_KEY,
|
||||
// MAIN_M2M_AP_SEC,
|
||||
// MAIN_M2M_AP_SSID_MODE,
|
||||
// MAIN_M2M_DHCP_SERVER_IP};
|
||||
//
|
||||
//static CONST char gacHttpProvDomainName[] = MAIN_HTTP_PROV_SERVER_DOMAIN_NAME;
|
||||
//
|
||||
//static uint8 gau8MacAddr[] = MAIN_MAC_ADDRESS;
|
||||
//static sint8 gacDeviceName[] = MAIN_M2M_SSID;
|
||||
//
|
||||
//#define MAIN_WAITING_TIME 3000
|
||||
//#define MAIN_RETRY_COUNT 10
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MAIN_H_INCLUDED */
|
||||
20
ChaloupeLora.X/Source/system.c
Normal file
20
ChaloupeLora.X/Source/system.c
Normal file
@ -0,0 +1,20 @@
|
||||
/******************************************************************************/
|
||||
/* Files to Include */
|
||||
/******************************************************************************/
|
||||
|
||||
#include <plib.h> /* Include to use PIC32 peripheral libraries */
|
||||
#include <stdint.h> /* For uint32_t definition */
|
||||
#include <stdbool.h> /* For true/false definition */
|
||||
#include "system.h" /* variables/params used by system.c */
|
||||
|
||||
/******************************************************************************/
|
||||
/* System Level Functions */
|
||||
/* */
|
||||
/* Custom oscillator configuration funtions, reset source evaluation */
|
||||
/* functions, and other non-peripheral microcontroller initialization */
|
||||
/* functions get placed in system.c */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
|
||||
/* <Initialize variables in system.h and put code for system algorithms here.>*/
|
||||
|
||||
19
ChaloupeLora.X/Source/system.h
Normal file
19
ChaloupeLora.X/Source/system.h
Normal file
@ -0,0 +1,19 @@
|
||||
/******************************************************************************/
|
||||
/* System Level #define Macros */
|
||||
/******************************************************************************/
|
||||
|
||||
/* TODO Define system operating frequency */
|
||||
|
||||
/* Microcontroller MIPs (FCY) */
|
||||
#define SYS_FREQ 80000000L
|
||||
#define FCY SYS_FREQ
|
||||
|
||||
/******************************************************************************/
|
||||
/* System Function Prototypes */
|
||||
/******************************************************************************/
|
||||
|
||||
/* Custom oscillator configuration funtions, reset source evaluation
|
||||
functions, and other non-peripheral microcontroller initialization functions
|
||||
go here. */
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user