First Commit
This commit is contained in:
commit
e42833c1ca
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.o
|
||||
*.o.d
|
||||
113
ChaletLora.X/Makefile
Normal file
113
ChaletLora.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
ChaletLora.X/Source/ADC.c
Normal file
265
ChaletLora.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
ChaletLora.X/Source/ADC.h
Normal file
73
ChaletLora.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
|
||||
|
||||
137
ChaletLora.X/Source/BatteryMonitor.c
Normal file
137
ChaletLora.X/Source/BatteryMonitor.c
Normal file
@ -0,0 +1,137 @@
|
||||
//#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;
|
||||
bool mCurrentModuleOK;
|
||||
|
||||
void InitBatteryMonitor()
|
||||
{
|
||||
mBatteryVoltage = 0;
|
||||
mBatteryCurrent = 0;
|
||||
mBatterySOC = 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))
|
||||
{
|
||||
int adc;
|
||||
float conv, raw;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if(NetworkSendCounter++ == 10)
|
||||
{
|
||||
NetworkSendCounter = 0;
|
||||
SendNetworkBatteryData();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float GetBatteryVoltage()
|
||||
{
|
||||
mBatteryVoltage = (mVoltageMeanSum/mVoltageMeanCount);
|
||||
mVoltageMeanSum = 0.0;
|
||||
mVoltageMeanCount = 0;
|
||||
|
||||
return mBatteryVoltage;
|
||||
|
||||
}
|
||||
|
||||
int GetSolarPanelCurrent()
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool GetCurrentModuleOK()
|
||||
{
|
||||
return mCurrentModuleOK;
|
||||
}
|
||||
26
ChaletLora.X/Source/BatteryMonitor.h
Normal file
26
ChaletLora.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
ChaletLora.X/Source/BoardCfg.h
Normal file
49
ChaletLora.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
ChaletLora.X/Source/BoardCfg_Chaletduino.h
Normal file
120
ChaletLora.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 */
|
||||
|
||||
166
ChaletLora.X/Source/BoardCfg_ChaletduinoV2.h
Normal file
166
ChaletLora.X/Source/BoardCfg_ChaletduinoV2.h
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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.TRISD15
|
||||
#define CHALET_12V_PRESENCE_PIN PORTBbits.RD15 //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.TRISD11
|
||||
#define LORA_MODULE_M0_PIN_DIR TRISEbits.TRISE7
|
||||
#define LORA_MODULE_M0_PIN LATEDbits.TRISE7
|
||||
#define LORA_MODULE_M1_PIN_DIR TRISDbits.TRISD9
|
||||
#define LORA_MODULE_M1_PIN LATDbits.TRISD9
|
||||
#define LORA_MODULE_INT_PIN_DIR TRISDbits.TRISD8
|
||||
#define LORA_MODULE_INT_PIN LATDbits.TRISD8
|
||||
#define LORA_MODULE_RX_LED_PIN_DIR TRISCbits.TRISC14
|
||||
#define LORA_MODULE_RX_LED_PIN LATCbits.TRISC14
|
||||
#define LORA_MODULE_TX_LED_PIN_DIR TRISCbits.TRISC13
|
||||
#define LORA_MODULE_TX_LED_PIN LATCbits.TRISC13
|
||||
|
||||
//LCD Screen
|
||||
#define LCD_RS_PIN_DIR TRISDbits.TRISD5
|
||||
#define LCD_RS_PIN LATDbits.LATSD5
|
||||
#define LCD_RW_PIN_DIR TRISBbits.TRISB13
|
||||
#define LCD_RW_PIN LATBbits.LATSB13
|
||||
#define LCD_E_PIN_DIR TRISBbits.TRISB12
|
||||
#define LCD_E_PIN LATBbits.LATSB12
|
||||
#define LCD_DB4_PIN_DIR TRISBbits.TRISB3
|
||||
#define LCD_DB4_PIN LATBbits.LATSB3
|
||||
#define LCD_DB5_PIN_DIR TRISBbits.TRISB9
|
||||
#define LCD_DB5_PIN LATBbits.LATSB9
|
||||
#define LCD_DB6_PIN_DIR TRISBbits.TRISB10
|
||||
#define LCD_DB6_PIN LATBbits.LATSB10
|
||||
#define LCD_DB7_PIN_DIR TRISBbits.TRISB11
|
||||
#define LCD_DB7_PIN LATBbits.LATSB11
|
||||
|
||||
#define LCD_SCROLL_BTN_PIN_DIR TRISCbits.TRISC13
|
||||
#define LCD_SCROLL_BTN_PIN PORTCbits.PORTC13
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
void InitDigitalIO(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DIGITALIO_PINGUINO_H */
|
||||
|
||||
58
ChaletLora.X/Source/BoardCfg_Fubarino.h
Normal file
58
ChaletLora.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
ChaletLora.X/Source/BoardCfg_Pinguino.h
Normal file
104
ChaletLora.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 */
|
||||
|
||||
319
ChaletLora.X/Source/BootloaderProtocol.c
Normal file
319
ChaletLora.X/Source/BootloaderProtocol.c
Normal file
@ -0,0 +1,319 @@
|
||||
/**********************************************************************
|
||||
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"
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
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] = ACK; //CMD
|
||||
}
|
||||
else
|
||||
{
|
||||
data[0] = 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];
|
||||
}
|
||||
72
ChaletLora.X/Source/BootloaderProtocol.h
Normal file
72
ChaletLora.X/Source/BootloaderProtocol.h
Normal file
@ -0,0 +1,72 @@
|
||||
/**********************************************************************
|
||||
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
|
||||
**********************************************************************/
|
||||
|
||||
//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();
|
||||
71
ChaletLora.X/Source/ChaletPowerRelay.c
Normal file
71
ChaletLora.X/Source/ChaletPowerRelay.c
Normal file
@ -0,0 +1,71 @@
|
||||
//#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)
|
||||
{
|
||||
PowerRelayState = CHALET_POWER_RELAY_ON_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
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
ChaletLora.X/Source/ChaletPowerRelay.h
Normal file
37
ChaletLora.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 100 //ms
|
||||
|
||||
void InitChaletPowerRelay();
|
||||
|
||||
void ChaletPowerRelayTick();
|
||||
bool ChaletPowerRelayTurnOn();
|
||||
bool ChaletPowerRelayTurnOff();
|
||||
char GetChaletPowerRelayState();
|
||||
void ChaletPowerRelayKickTimer();
|
||||
|
||||
|
||||
|
||||
#endif /* CHALETPOWERRELAY_H */
|
||||
|
||||
130
ChaletLora.X/Source/ChaletduinoBoard.c
Normal file
130
ChaletLora.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;
|
||||
}
|
||||
130
ChaletLora.X/Source/ChaletduinoV2Board.c
Normal file
130
ChaletLora.X/Source/ChaletduinoV2Board.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;
|
||||
}
|
||||
15
ChaletLora.X/Source/CurrentSensor.c
Normal file
15
ChaletLora.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
ChaletLora.X/Source/CurrentSensor.h
Normal file
16
ChaletLora.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
ChaletLora.X/Source/DigitalIO.c
Normal file
42
ChaletLora.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
ChaletLora.X/Source/DigitalIO.h
Normal file
36
ChaletLora.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
ChaletLora.X/Source/FatFS/diskio.c
Normal file
225
ChaletLora.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
ChaletLora.X/Source/FatFS/diskio.h
Normal file
101
ChaletLora.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
ChaletLora.X/Source/FatFS/ff.c
Normal file
6555
ChaletLora.X/Source/FatFS/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
366
ChaletLora.X/Source/FatFS/ff.h
Normal file
366
ChaletLora.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
ChaletLora.X/Source/FatFS/ffconf.h
Normal file
283
ChaletLora.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
ChaletLora.X/Source/FatFS/ffsystem.c
Normal file
171
ChaletLora.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
ChaletLora.X/Source/FatFS/ffunicode.c
Normal file
15586
ChaletLora.X/Source/FatFS/ffunicode.c
Normal file
File diff suppressed because it is too large
Load Diff
38
ChaletLora.X/Source/FatFS/integer.h
Normal file
38
ChaletLora.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
ChaletLora.X/Source/FatFS/mmc_drv.c
Normal file
660
ChaletLora.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;
|
||||
}
|
||||
|
||||
6
ChaletLora.X/Source/FubarinoBoard.c
Normal file
6
ChaletLora.X/Source/FubarinoBoard.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "BoardCfg.h"
|
||||
|
||||
int InitBoard()
|
||||
{
|
||||
return RET_OK;
|
||||
}
|
||||
21
ChaletLora.X/Source/HarakiriRelay.c
Normal file
21
ChaletLora.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
ChaletLora.X/Source/HarakiriRelay.h
Normal file
19
ChaletLora.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
ChaletLora.X/Source/I2C.c
Normal file
171
ChaletLora.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
ChaletLora.X/Source/I2C.h
Normal file
21
ChaletLora.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 */
|
||||
|
||||
584
ChaletLora.X/Source/InternalUart.c
Normal file
584
ChaletLora.X/Source/InternalUart.c
Normal file
@ -0,0 +1,584 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* 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 < p_iDataSize; i++)
|
||||
{
|
||||
// KickWatchdog();
|
||||
U1TXREG = *p_pcDataBuf++;
|
||||
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 < p_iDataSize; i++)
|
||||
{
|
||||
// KickWatchdog();
|
||||
U2TXREG = *p_pcDataBuf++;
|
||||
while(U2STAbits.TRMT == 0);
|
||||
}
|
||||
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;
|
||||
for(i = 0; i < p_iDataSize; i++)
|
||||
{
|
||||
U2TXREG = *p_pcDataBuf++;
|
||||
while(U2STAbits.TRMT == 0);
|
||||
}
|
||||
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)
|
||||
{
|
||||
if(U2STAbits.OERR) //Buffer overrun error. Data is lost.
|
||||
{
|
||||
U2STAbits.OERR = 0;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while(U2STAbits.URXDA && i < INTERNAL_UART_BUFFER_DEPTH)
|
||||
{
|
||||
char NewByte = U2RXREG;
|
||||
//acIntUartRxBuff[INTERNAL_UART_PORT_2][i++] = NewByte;
|
||||
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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
U2TXREG = *p_acUartDataPtr->pcTxDataPtr++; //send data
|
||||
p_acUartDataPtr->iNbFIFOPendingBytes--;
|
||||
|
||||
}
|
||||
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;
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while(U2STAbits.URXDA)
|
||||
{
|
||||
NewByte = U2RXREG;
|
||||
acIntUartRxBuff[INTERNAL_UART_PORT_2][i++] = NewByte;
|
||||
}
|
||||
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 = 1; //enable tx interrupt
|
||||
IEC1bits.U2RXIE = 0; //disable rx interrupts
|
||||
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
|
||||
|
||||
|
||||
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
ChaletLora.X/Source/InternalUart.h
Normal file
98
ChaletLora.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
ChaletLora.X/Source/KnobEncoderCtrl.c
Normal file
123
ChaletLora.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
ChaletLora.X/Source/KnobEncoderCtrl.h
Normal file
31
ChaletLora.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
ChaletLora.X/Source/LedLightCtrl.c
Normal file
96
ChaletLora.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
ChaletLora.X/Source/LedLightCtrl.h
Normal file
33
ChaletLora.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 */
|
||||
|
||||
204
ChaletLora.X/Source/LoraNetworkInterface.c
Normal file
204
ChaletLora.X/Source/LoraNetworkInterface.c
Normal file
@ -0,0 +1,204 @@
|
||||
#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 "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};
|
||||
|
||||
|
||||
void ExecuteMasterCommand(int Command, unsigned char *Data)
|
||||
{
|
||||
//Whatever was the command, we are online...
|
||||
ChaletPowerRelayKickTimer();
|
||||
switch(Command)
|
||||
{
|
||||
case CHALET_INTERFACE_ACK:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case CHALET_GENERAL_STATUS_REQUEST:
|
||||
{
|
||||
float FloatVoltage = GetBatteryVoltage();
|
||||
unsigned int BattVoltage = *((int*)&FloatVoltage);
|
||||
int SolarPanelCurrent = GetSolarPanelCurrent();
|
||||
int SOC = GetBatterySOC();
|
||||
|
||||
char GeneralStatus = 0;
|
||||
char ChaletStatus[10];
|
||||
|
||||
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
|
||||
|
||||
|
||||
SendLoraNetworkCommand(CHALET_GENERAL_STATUS_RESPONSE,ChaletStatus,10);
|
||||
|
||||
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);
|
||||
HEARTBEAT_LED_2_PIN = ~HEARTBEAT_LED_2_PIN;
|
||||
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)
|
||||
SendLoraNetworkCommand(CHALET_REBOOT_CPU_RESPONSE,&response,1);
|
||||
Sleep(100);
|
||||
TurnOFFWiFi();
|
||||
Sleep(100);
|
||||
SoftReset();
|
||||
}
|
||||
else
|
||||
{
|
||||
response = 0x00;
|
||||
SendLoraNetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&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);
|
||||
|
||||
|
||||
SendInternalUartDataBlocking(mLoraPreamble,3,NETWORK_UART_PORT);
|
||||
SendInternalUartDataBlocking(Payload,PayloadSize,NETWORK_UART_PORT);
|
||||
|
||||
}
|
||||
16
ChaletLora.X/Source/LoraNetworkInterface.h
Normal file
16
ChaletLora.X/Source/LoraNetworkInterface.h
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
|
||||
#endif /* LORANEETWORKINTERFACE_H */
|
||||
281
ChaletLora.X/Source/MasterCtrlInterface.c
Normal file
281
ChaletLora.X/Source/MasterCtrlInterface.c
Normal file
@ -0,0 +1,281 @@
|
||||
#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
ChaletLora.X/Source/MasterCtrlInterface.h
Normal file
27
ChaletLora.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 */
|
||||
|
||||
323
ChaletLora.X/Source/NetworkProtocol.c
Normal file
323
ChaletLora.X/Source/NetworkProtocol.c
Normal file
@ -0,0 +1,323 @@
|
||||
/**********************************************************************
|
||||
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;
|
||||
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] = ACK; //CMD
|
||||
}
|
||||
else
|
||||
{
|
||||
data[0] = 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];
|
||||
}
|
||||
71
ChaletLora.X/Source/NetworkProtocol.h
Normal file
71
ChaletLora.X/Source/NetworkProtocol.h
Normal file
@ -0,0 +1,71 @@
|
||||
/**********************************************************************
|
||||
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
|
||||
**********************************************************************/
|
||||
|
||||
//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();
|
||||
31
ChaletLora.X/Source/PWMCtrl.c
Normal file
31
ChaletLora.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
ChaletLora.X/Source/PWMCtrl.h
Normal file
18
ChaletLora.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
ChaletLora.X/Source/PinguinoBoard.c
Normal file
97
ChaletLora.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
ChaletLora.X/Source/PrintfServer.c
Normal file
104
ChaletLora.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
ChaletLora.X/Source/PrintfServer.h
Normal file
17
ChaletLora.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
|
||||
319
ChaletLora.X/Source/ProtocolDefs.h
Normal file
319
ChaletLora.X/Source/ProtocolDefs.h
Normal file
@ -0,0 +1,319 @@
|
||||
/**********************************************************************
|
||||
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 ACK 0xA3
|
||||
#define 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,
|
||||
|
||||
MAX_CHALET_CMD
|
||||
};
|
||||
|
||||
enum BOOTLOADER_CMDS
|
||||
{
|
||||
BOOTLOADER_ACK = 1,
|
||||
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,
|
||||
|
||||
MAX_BOOTLOADER_CMD
|
||||
};
|
||||
#endif
|
||||
212
ChaletLora.X/Source/SDCardMgr.c
Normal file
212
ChaletLora.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
ChaletLora.X/Source/SDCardMgr.h
Normal file
45
ChaletLora.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
ChaletLora.X/Source/SPI.c
Normal file
20
ChaletLora.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
ChaletLora.X/Source/SPI.h
Normal file
14
ChaletLora.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 */
|
||||
|
||||
343
ChaletLora.X/Source/SPI_Flash.c
Normal file
343
ChaletLora.X/Source/SPI_Flash.c
Normal file
@ -0,0 +1,343 @@
|
||||
#include "SPI_Flash.h"
|
||||
#include "SPI.h"
|
||||
#include "BoardCfg.h"
|
||||
|
||||
unsigned char mSPIFlashBaudrate;
|
||||
unsigned char mSPIFlashHighSpeedBaudrate;
|
||||
unsigned char mFlashSectorBuffer[SPI_FLASH_SECTOR_SIZE];
|
||||
|
||||
int InitSPIFlash()
|
||||
{
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
mSPIFlashBaudrate = SPICalculateBRG(PERIPHERAL_FREQ, 25000000);
|
||||
mSPIFlashHighSpeedBaudrate = SPICalculateBRG(PERIPHERAL_FREQ, 50000000);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
printf("SPI Flash configured\n");
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
printf("ERROR: SPI Flash not detected\n");
|
||||
return RET_ERROR;
|
||||
|
||||
}
|
||||
|
||||
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 > SPI_FLASH_MAX_ADDRESS)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
FLASH_SS_PIN = 0;
|
||||
SPITransaction(SPI_FLASH_HI_SPEED_READ,mSPIFlashBaudrate);
|
||||
SPITransaction(((StartAddress & 0xFF0000) >> 16),mSPIFlashBaudrate);
|
||||
SPITransaction(((StartAddress & 0x00FF00) >> 8),mSPIFlashBaudrate);
|
||||
SPITransaction((StartAddress & 0x0000FF),mSPIFlashBaudrate);
|
||||
SPITransaction((0x00),mSPIFlashBaudrate); //Chip requires a dummy read in high speed
|
||||
|
||||
int i;
|
||||
for(i = 0; i < Size; i++)
|
||||
{
|
||||
*Buf++ = SPITransaction(0xDE,mSPIFlashBaudrate);
|
||||
}
|
||||
|
||||
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),mSPIFlashBaudrate);
|
||||
SPITransaction(((SectorAddress & 0x00FF00) >> 8),mSPIFlashBaudrate);
|
||||
SPITransaction((SectorAddress & 0x0000FF),mSPIFlashBaudrate);
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
SectorAddress++;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
char *DataPtr = &mFlashSectorBuffer[0];
|
||||
int j;
|
||||
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(*DataPtr++,mSPIFlashBaudrate);
|
||||
FLASH_SS_PIN = 1;
|
||||
|
||||
SectorAddress++;
|
||||
|
||||
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;
|
||||
}
|
||||
44
ChaletLora.X/Source/SPI_Flash.h
Normal file
44
ChaletLora.X/Source/SPI_Flash.h
Normal file
@ -0,0 +1,44 @@
|
||||
#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_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 SPIFlashWriteSectorWorkingBuffer(int SectorAddress, int Erase);
|
||||
|
||||
|
||||
#endif /* SPI_FLASH_H */
|
||||
|
||||
7
ChaletLora.X/Source/Schedule.c
Normal file
7
ChaletLora.X/Source/Schedule.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "define.h"
|
||||
#include "Schedule.h"
|
||||
|
||||
void InitSchedule()
|
||||
{
|
||||
|
||||
}
|
||||
14
ChaletLora.X/Source/Schedule.h
Normal file
14
ChaletLora.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
ChaletLora.X/Source/Scheduler.c
Normal file
39
ChaletLora.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
ChaletLora.X/Source/Scheduler.h
Normal file
48
ChaletLora.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
|
||||
|
||||
59
ChaletLora.X/Source/TCPServer.c
Normal file
59
ChaletLora.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
ChaletLora.X/Source/TCPServer.h
Normal file
11
ChaletLora.X/Source/TCPServer.h
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
#ifndef TCPSERVER_H
|
||||
#define TCPSERVER_H
|
||||
|
||||
|
||||
int OpenTCPServer();
|
||||
void TickTCPServer();
|
||||
|
||||
|
||||
#endif
|
||||
484
ChaletLora.X/Source/Terminal.c
Normal file
484
ChaletLora.X/Source/Terminal.c
Normal file
@ -0,0 +1,484 @@
|
||||
|
||||
/*
|
||||
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 "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"
|
||||
"\nstatus : get general system status\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,"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
ChaletLora.X/Source/Terminal.h
Normal file
67
ChaletLora.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
|
||||
|
||||
696
ChaletLora.X/Source/Uart.c
Normal file
696
ChaletLora.X/Source/Uart.c
Normal file
@ -0,0 +1,696 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* 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);
|
||||
|
||||
#ifdef USE_PRINTF
|
||||
//UartOpenComPort(CONSOLE_UART_PORT,115200,UART_ONE_STOP_BIT,UART_NO_PARITY); //Open console port
|
||||
UartOpenComPort(NETWORK_UART_PORT,9600,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;
|
||||
|
||||
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();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i == NETWORK_UART_PORT)
|
||||
{
|
||||
#ifndef NO_EXTERNAL_UART
|
||||
SC16IS740DriverTick();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// 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++)
|
||||
// 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
ChaletLora.X/Source/Uart.h
Normal file
106
ChaletLora.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
ChaletLora.X/Source/Util.c
Normal file
367
ChaletLora.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
ChaletLora.X/Source/Util.h
Normal file
63
ChaletLora.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
ChaletLora.X/Source/Watchdog.c
Normal file
64
ChaletLora.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"
|
||||
//#include "pastatus.h"
|
||||
|
||||
void InitWatchdog(void)
|
||||
{
|
||||
if(RCONbits.WDTO == 1)
|
||||
{
|
||||
// estPAStatus.WatchdogFlag = 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
|
||||
|
||||
|
||||
572
ChaletLora.X/Source/WiFiCtrl.c
Normal file
572
ChaletLora.X/Source/WiFiCtrl.c
Normal file
@ -0,0 +1,572 @@
|
||||
#include "WiFiCtrl.h"
|
||||
#include "string.h"
|
||||
#include "driver/source/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"
|
||||
|
||||
|
||||
|
||||
/** 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];
|
||||
|
||||
SOCKET PrintfSocket = -1, PrintfServerSocket = -1;
|
||||
uint8 PrintfRxBuf[1024];
|
||||
|
||||
SOCKET NetworkSocket = -1, NetworkServerSocket = -1;
|
||||
uint8 NetworkRxBuf[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;
|
||||
|
||||
tstrM2MIPConfig mModuleIPConfig;
|
||||
|
||||
bool mWiFiInitOK = false;
|
||||
char mWiFiState = WIFI_UNKNOWN_STATE;
|
||||
|
||||
|
||||
/**
|
||||
* \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 == PrintfServerSocket)
|
||||
{
|
||||
listen(PrintfServerSocket,0);
|
||||
}
|
||||
else if(sock == NetworkServerSocket)
|
||||
{
|
||||
listen(NetworkServerSocket,0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Bind Failed\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SOCKET_MSG_LISTEN:
|
||||
{
|
||||
|
||||
tstrSocketListenMsg *pstrListen = (tstrSocketListenMsg*)pvMsg;
|
||||
if(pstrListen->status != 0)
|
||||
{
|
||||
printf("socket %d listen Failed\n",socket);;
|
||||
break;
|
||||
}
|
||||
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"));
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,1);
|
||||
}
|
||||
else if(sock == PrintfServerSocket)
|
||||
{
|
||||
memset(PrintfRxBuf,0,sizeof(PrintfRxBuf));
|
||||
// Get the accepted socket.
|
||||
PrintfSocket = pstrAccept->sock;
|
||||
recv(PrintfSocket, PrintfRxBuf, sizeof(PrintfRxBuf), 0);
|
||||
}
|
||||
else if(sock == NetworkServerSocket)
|
||||
{
|
||||
memset(NetworkRxBuf,0,sizeof(NetworkRxBuf));
|
||||
// Get the accepted socket.
|
||||
NetworkSocket = pstrAccept->sock;
|
||||
recv(NetworkSocket, NetworkRxBuf, sizeof(NetworkRxBuf), 0);
|
||||
}
|
||||
|
||||
}
|
||||
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...
|
||||
RxTerminalBuf(pstrRecvMsg->pu8Buffer, pstrRecvMsg->s16BufferSize);
|
||||
recv(TerminalSocket, TerminalRxBuf, sizeof(TerminalRxBuf), 0);
|
||||
}
|
||||
else if(sock == PrintfSocket)
|
||||
{
|
||||
//Fwd data to stdin...
|
||||
recv(PrintfSocket, PrintfRxBuf, sizeof(PrintfRxBuf), 0);
|
||||
}
|
||||
else if(sock == NetworkSocket)
|
||||
{
|
||||
//Fwd data to Network...
|
||||
recv(NetworkSocket, NetworkRxBuf, sizeof(NetworkRxBuf), 0);
|
||||
}
|
||||
}
|
||||
else //Socket must be closed.
|
||||
{
|
||||
if(sock == TerminalSocket)
|
||||
{
|
||||
close(TerminalSocket);
|
||||
TerminalSocket = -1;
|
||||
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,0);
|
||||
}
|
||||
else if(sock == PrintfSocket)
|
||||
{
|
||||
close(PrintfSocket);
|
||||
PrintfSocket = -1;
|
||||
}
|
||||
else if(sock == NetworkSocket)
|
||||
{
|
||||
close(NetworkSocket);
|
||||
NetworkSocket = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
#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);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case M2M_WIFI_REQ_DHCP_CONF:
|
||||
{
|
||||
uint8 *pu8IPAddress = (uint8 *)pvMsg;
|
||||
/* 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);
|
||||
|
||||
|
||||
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.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.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 = wifi_cb;
|
||||
ret = m2m_wifi_init(¶m);
|
||||
if (M2M_SUCCESS != ret)
|
||||
{
|
||||
mWiFiInitOK = false;
|
||||
mWiFiState = WIFI_INIT_ERROR_STATE;
|
||||
return RET_ERROR;
|
||||
}
|
||||
mWiFiInitOK = true;
|
||||
HEARTBEAT_LED_2_PIN = LED_ON;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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(NULL);
|
||||
// TimerStart(WIFI_TICK_TIMER,1);
|
||||
// }
|
||||
|
||||
if (gbConnectedWifi && !gbTcpConnection)
|
||||
{
|
||||
|
||||
|
||||
OpenTerminalServer();
|
||||
OpenNetworkServer();
|
||||
#ifdef USE_WIFI_PRINTF
|
||||
OpenPrintfServer();
|
||||
#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 TerminalPort = NETWORK_SERVER_PORT;
|
||||
if(NetworkServerSocket >= 0)
|
||||
{
|
||||
strAddr.sin_family = AF_INET;
|
||||
strAddr.sin_port = _htons(TerminalPort);
|
||||
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_WIFI_PRINTF
|
||||
int OpenPrintfServer()
|
||||
{
|
||||
struct sockaddr_in strAddr;
|
||||
|
||||
PrintfServerSocket = socket(AF_INET, SOCK_STREAM,0);
|
||||
uint16 TerminalPort = 5589;
|
||||
if(PrintfServerSocket >= 0)
|
||||
{
|
||||
strAddr.sin_family = AF_INET;
|
||||
strAddr.sin_port = _htons(TerminalPort);
|
||||
strAddr.sin_addr.s_addr = 0;
|
||||
|
||||
bind(PrintfServerSocket, (struct sockaddr*)&strAddr, sizeof(struct sockaddr_in));
|
||||
return RET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
void SendPrintfData(uint8 *data, int size)
|
||||
{
|
||||
if(PrintfSocket != -1);
|
||||
{
|
||||
send(PrintfSocket,data,size,0);
|
||||
recv(PrintfSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
|
||||
}
|
||||
}
|
||||
void SendPrintfByte(uint8 data)
|
||||
{
|
||||
if(PrintfSocket != -1)
|
||||
{
|
||||
send(PrintfSocket,&data,1,0);
|
||||
recv(PrintfSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
192
ChaletLora.X/Source/WiFiCtrl.h
Normal file
192
ChaletLora.X/Source/WiFiCtrl.h
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
|
||||
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 OpenPrintfServer();
|
||||
void SendPrintfData(uint8 *data, int size);
|
||||
void SendPrintfByte(uint8 data);
|
||||
|
||||
#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 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 >>>
|
||||
|
||||
//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 "LeChalet"
|
||||
//#define HOME_AP_PWD "Evinrude30"
|
||||
|
||||
#define TERMINAL_SERVER_PORT 85
|
||||
#define NETWORK_SERVER_PORT 86
|
||||
|
||||
#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 50
|
||||
#define STATIC_IP_ADDRESS_4 126
|
||||
|
||||
#define GATEWAY_ADDRESS_1 192
|
||||
#define GATEWAY_ADDRESS_2 168
|
||||
#define GATEWAY_ADDRESS_3 50
|
||||
#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 */
|
||||
|
||||
231
ChaletLora.X/Source/define.h
Normal file
231
ChaletLora.X/Source/define.h
Normal file
@ -0,0 +1,231 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* 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 5000 //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 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
|
||||
|
||||
// Uncomment next #define for testing with ICCA board
|
||||
// #define USE_ICCA_CU_PA_UART_SNOOPING
|
||||
|
||||
//#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
|
||||
|
||||
//
|
||||
//----------------------------
|
||||
//#define USE_BLOCKING_PRINTF
|
||||
#define USE_PRINTF
|
||||
|
||||
|
||||
#ifdef USE_PRINTF
|
||||
#define PRINTF(n, a...) printf(n, ## a)
|
||||
|
||||
#ifndef NO_WIFI
|
||||
// #define USE_WIFI_PRINTF
|
||||
#endif
|
||||
|
||||
//#define USE_UART_PRINTF
|
||||
#else
|
||||
#define PRINTF(n, a...)
|
||||
#define NO_EXTERNAL_UART
|
||||
#endif
|
||||
|
||||
//#define CONNECT_DEVICE_TO_NETWORK
|
||||
//#define TERMINAL_USE_TELNET
|
||||
//#define TERMINAL_USE_TCP_SERVER
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
typedef bool;
|
||||
|
||||
//----- 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
ChaletLora.X/Source/define_WITT.h
Normal file
168
ChaletLora.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
ChaletLora.X/Source/exceptions.c
Normal file
129
ChaletLora.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();
|
||||
}
|
||||
}
|
||||
677
ChaletLora.X/Source/ina219.c
Normal file
677
ChaletLora.X/Source/ina219.c
Normal file
@ -0,0 +1,677 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@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"
|
||||
|
||||
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
ChaletLora.X/Source/ina219.h
Normal file
141
ChaletLora.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
ChaletLora.X/Source/interrupts.c
Normal file
75
ChaletLora.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. */
|
||||
|
||||
197
ChaletLora.X/Source/main.c
Normal file
197
ChaletLora.X/Source/main.c
Normal file
@ -0,0 +1,197 @@
|
||||
|
||||
/*
|
||||
Description:
|
||||
This is a template file for standard C header file.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
### 20120515 JFM
|
||||
Original version.
|
||||
|
||||
### YYYYMMDD Initial, Bug Identification
|
||||
Change description.
|
||||
*/
|
||||
|
||||
#include "define.h"
|
||||
|
||||
|
||||
#include "Uart.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "timer.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"
|
||||
|
||||
//#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
|
||||
#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 = PS128
|
||||
#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
|
||||
|
||||
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
|
||||
|
||||
#ifndef __32MX330F064H__
|
||||
AD1PCFG = 0xFFFF; //Sart with I/O pins configured as digital I/O
|
||||
#endif
|
||||
|
||||
InitBoard();
|
||||
INTEnableInterrupts();
|
||||
|
||||
TimerInit();
|
||||
// I2CInit();
|
||||
InitChaletPowerRelay();
|
||||
InitBatteryMonitor();
|
||||
|
||||
InitUart();
|
||||
ProtocolInit();
|
||||
|
||||
InitSPIFlash();
|
||||
|
||||
printf("ChaletDuino V2 Initialized\n");
|
||||
|
||||
SPIFlashCheckAndConfigure();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#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");
|
||||
|
||||
// EnableWatchdog();
|
||||
mRetCode = 1;
|
||||
// unsigned int LoraData = 0;
|
||||
// float raw,conv;
|
||||
|
||||
// AD1CON1bits.SAMP = 1;
|
||||
while(mRetCode == 1)
|
||||
{
|
||||
// mRetCode = RunPA();
|
||||
// UartTick();
|
||||
#ifndef NO_WIFI
|
||||
TickWiFi();
|
||||
#endif
|
||||
TickTerminal();
|
||||
UartTick();
|
||||
ChaletPowerRelayTick();
|
||||
BatteryMonitorTick();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(IsTimerExpired(HEARTBEAT_LED_TMR))
|
||||
{
|
||||
HEARTBEAT_LED_1_PIN = ~HEARTBEAT_LED_1_PIN;
|
||||
TimerStart(HEARTBEAT_LED_TMR,HEARTBEAT_LED_TIMEOUT);
|
||||
|
||||
|
||||
|
||||
// AD1CON1bits.SAMP = 0;
|
||||
// while(AD1CON1bits.DONE == 0);
|
||||
// adc = ADC1BUF0;
|
||||
// AD1CON1bits.SAMP = 1;
|
||||
// adc &= 0xFFFE;
|
||||
// conv = (float)adc / 1023;
|
||||
// conv *= 3.3;
|
||||
// raw = conv;
|
||||
// conv *= 11;
|
||||
// conv += 0.2;
|
||||
|
||||
|
||||
// printf("Value: 0x%x - %f - %f\n",adc,raw,conv);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return mRetCode;
|
||||
}
|
||||
|
||||
|
||||
void InitializeBoard()
|
||||
{
|
||||
InitBoard();
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_PRINTF
|
||||
void _mon_putc(char c)
|
||||
{
|
||||
U2TXREG = c;
|
||||
while (U2STAbits.TRMT==0);
|
||||
}
|
||||
#endif
|
||||
|
||||
//EOF
|
||||
|
||||
165
ChaletLora.X/Source/main.h
Normal file
165
ChaletLora.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
ChaletLora.X/Source/system.c
Normal file
20
ChaletLora.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
ChaletLora.X/Source/system.h
Normal file
19
ChaletLora.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. */
|
||||
|
||||
|
||||
38
ChaletLora.X/Source/template.c
Normal file
38
ChaletLora.X/Source/template.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
|
||||
/* Global variables */
|
||||
|
||||
/* Implementation */
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//EOF
|
||||
|
||||
47
ChaletLora.X/Source/template.h
Normal file
47
ChaletLora.X/Source/template.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef TEMPLATE_H
|
||||
#define TEMPLATE_H
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
|
||||
|
||||
#endif
|
||||
//EOF
|
||||
|
||||
300
ChaletLora.X/Source/timer.c
Normal file
300
ChaletLora.X/Source/timer.c
Normal file
@ -0,0 +1,300 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
#include "timer.h"
|
||||
#include "define.h"
|
||||
#include <string.h>
|
||||
//#include <plib.h>
|
||||
//#include "./FatFS/diskio.h"
|
||||
|
||||
//unsigned int MillisecCounter[TIMER_MAX_ID];
|
||||
//unsigned int SecondCounter;
|
||||
//int CalcPeriod;
|
||||
stTimer astTimer[TIMER_MAX_ID];
|
||||
|
||||
//-------------------------------------------------------
|
||||
void TimerInit(void)
|
||||
{
|
||||
#ifdef GP_TIMER_USE_TIMER_1
|
||||
|
||||
T1CON = 0;
|
||||
|
||||
T1CONbits.TCKPS = 0b01; //1:8 prescaler
|
||||
TMR1 = 0;
|
||||
PR1 = 10000; //77.824MHz clock with 1:8 prescaler = timer period of 102.8ns. 1ms period --> 9728 * 102.8ns = 1ms
|
||||
|
||||
IPC1bits.T1IP = 2; //timer interrupt priority = 2;
|
||||
IPC1bits.T1IS = 3; //timer interrupt sub-priority = 2;
|
||||
IFS0bits.T1IF = 0;
|
||||
IEC0bits.T1IE = 1; //start timer
|
||||
|
||||
T1CONbits.ON = 1;
|
||||
|
||||
#endif
|
||||
#ifdef GP_TIMER_USE_TIMER_2
|
||||
T2CON = 0;
|
||||
|
||||
T2CONbits.TCKPS = 0b011; //1:8 prescaler
|
||||
TMR2 = 0;
|
||||
PR2 = 10000; //77.824MHz clock with 1:8 prescaler = timer period of 102.8ns. 1ms period --> 9728 * 102.8ns = 1ms
|
||||
|
||||
IPC2bits.T2IP = 2; //timer interrupt priority = 2;
|
||||
IPC2bits.T2IS = 3; //timer interrupt sub-priority = 2;
|
||||
IFS0bits.T2IF = 0;
|
||||
IEC0bits.T2IE = 1; //start timer
|
||||
|
||||
T2CONbits.ON = 1;
|
||||
#endif
|
||||
|
||||
memset(&astTimer[0], 0, sizeof(astTimer));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
/*unsigned int GetActualTimerMilliSec(void)
|
||||
{
|
||||
return MillisecCounter;
|
||||
}*/
|
||||
|
||||
//-------------------------------------------------------
|
||||
/*unsigned int GetActualTimerSec(void)
|
||||
{
|
||||
return SecondCounter;
|
||||
}*/
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
int IsMilliSecTimerExpired(eTimerID p_eTimerID)
|
||||
{
|
||||
int CalcPeriod = 0;
|
||||
|
||||
if ((astTimer+p_eTimerID)->bRunning)
|
||||
{
|
||||
CalcPeriod = (astTimer+p_eTimerID)->uiMillisecCounter - (astTimer+p_eTimerID)->uiStart;
|
||||
//if(CalcPeriod > 0 && CalcPeriod >= (astTimer+p_eTimerID)->uiPeriodMillisec)
|
||||
if(CalcPeriod >= (astTimer+p_eTimerID)->uiPeriodMillisec)
|
||||
{
|
||||
//TimerReset(p_eTimerID);
|
||||
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
|
||||
return 1;
|
||||
}
|
||||
else if(CalcPeriod < 0)
|
||||
{
|
||||
if((1000 + CalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodMillisec)
|
||||
{
|
||||
//TimerReset(p_eTimerID);
|
||||
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
int IsSecTimerExpired(eTimerID p_eTimerID)
|
||||
{
|
||||
int iCalcPeriod = 0;
|
||||
|
||||
if ((astTimer+p_eTimerID)->bRunning)
|
||||
{
|
||||
iCalcPeriod = (astTimer+p_eTimerID)->uiSecondCounter - (astTimer+p_eTimerID)->uiStart;
|
||||
//if(iCalcPeriod > 0 && iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodSecond)
|
||||
if(iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodSecond)
|
||||
{
|
||||
//TimerReset(p_eTimerID);
|
||||
(astTimer+p_eTimerID)->uiSecondCounter = 0;
|
||||
return 1;
|
||||
}
|
||||
else if(iCalcPeriod < 0)
|
||||
{
|
||||
if(((unsigned)0xFFFFFFFF + iCalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodSecond)
|
||||
{
|
||||
//TimerReset(p_eTimerID);
|
||||
(astTimer+p_eTimerID)->uiSecondCounter = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
int IsTimerExpired(eTimerID p_eTimerID)
|
||||
{
|
||||
int iCalcPeriod = 0;
|
||||
|
||||
if ((astTimer+p_eTimerID)->bRunning)
|
||||
{
|
||||
/*if (IsSecTimerExpired(p_eTimerID) && IsMilliSecTimerExpired(p_eTimerID))
|
||||
return 1;*/
|
||||
|
||||
iCalcPeriod = (astTimer+p_eTimerID)->uiSecondCounter - (astTimer+p_eTimerID)->uiStart;
|
||||
|
||||
if(iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodSecond)
|
||||
{
|
||||
iCalcPeriod = (astTimer+p_eTimerID)->uiMillisecCounter - (astTimer+p_eTimerID)->uiStart;
|
||||
if(iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodMillisec)
|
||||
{
|
||||
(astTimer+p_eTimerID)->uiSecondCounter = 0;
|
||||
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
|
||||
return 1;
|
||||
}
|
||||
else if(iCalcPeriod < 0)
|
||||
{
|
||||
if((1000 + iCalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodMillisec)
|
||||
{
|
||||
(astTimer+p_eTimerID)->uiSecondCounter = 0;
|
||||
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(iCalcPeriod < 0)
|
||||
{
|
||||
if(((unsigned)0xFFFFFFFF + iCalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodSecond)
|
||||
{
|
||||
iCalcPeriod = (astTimer+p_eTimerID)->uiMillisecCounter - (astTimer+p_eTimerID)->uiStart;
|
||||
if(iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodMillisec)
|
||||
{
|
||||
(astTimer+p_eTimerID)->uiSecondCounter = 0;
|
||||
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
|
||||
return 1;
|
||||
}
|
||||
else if(iCalcPeriod < 0)
|
||||
{
|
||||
if((1000 + iCalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodMillisec)
|
||||
{
|
||||
(astTimer+p_eTimerID)->uiSecondCounter = 0;
|
||||
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
void TimerStart(eTimerID p_eTimerID, unsigned int p_uiPeriod)
|
||||
{
|
||||
(astTimer+p_eTimerID)->bRunning = true;
|
||||
if (p_uiPeriod >= 1000)
|
||||
{
|
||||
(astTimer+p_eTimerID)->uiPeriodSecond = p_uiPeriod / 1000;
|
||||
(astTimer+p_eTimerID)->uiPeriodMillisec = p_uiPeriod % 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
(astTimer+p_eTimerID)->uiPeriodSecond = 0;
|
||||
(astTimer+p_eTimerID)->uiPeriodMillisec = p_uiPeriod;
|
||||
}
|
||||
TimerReset(p_eTimerID);
|
||||
}
|
||||
void TimerStartSeconds(eTimerID p_eTimerID, unsigned int p_uiPeriod)
|
||||
{
|
||||
(astTimer+p_eTimerID)->bRunning = true;
|
||||
(astTimer+p_eTimerID)->uiPeriodSecond = p_uiPeriod;
|
||||
(astTimer+p_eTimerID)->uiPeriodMillisec = 0;
|
||||
TimerReset(p_eTimerID);
|
||||
}
|
||||
//-------------------------------------------------------
|
||||
void TimerReset(eTimerID p_eTimerID)
|
||||
{
|
||||
(astTimer+p_eTimerID)->uiStart = 0;
|
||||
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
|
||||
(astTimer+p_eTimerID)->uiSecondCounter = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
bool IsTimerRunning(eTimerID p_eTimerID)
|
||||
{
|
||||
return (astTimer+p_eTimerID)->bRunning;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
void TimerStop(eTimerID p_eTimerID)
|
||||
{
|
||||
(astTimer+p_eTimerID)->bRunning = false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
void Sleep(unsigned int timeout)
|
||||
{
|
||||
TimerStart(SLEEP_FCN_TIMER,timeout);
|
||||
|
||||
while(!IsTimerExpired(SLEEP_FCN_TIMER))
|
||||
{
|
||||
Nop();
|
||||
}
|
||||
TimerStop(SLEEP_FCN_TIMER);
|
||||
}
|
||||
|
||||
|
||||
#ifdef GP_TIMER_USE_TIMER_1
|
||||
|
||||
void __ISR(_TIMER_1_VECTOR, ipl2) Timer1MilliSecInterrupt(void)
|
||||
{
|
||||
unsigned int i;
|
||||
stTimer* pstPtr = &astTimer[0];
|
||||
|
||||
// disk_timerproc();
|
||||
|
||||
// Update all timers
|
||||
for (i=0; i<TIMER_MAX_ID; i++)
|
||||
{
|
||||
// update timer only if timer is running
|
||||
if (pstPtr->bRunning)
|
||||
{
|
||||
if(pstPtr->uiMillisecCounter++ == 1000)
|
||||
{
|
||||
pstPtr->uiMillisecCounter = 0;
|
||||
pstPtr->uiSecondCounter++;
|
||||
}
|
||||
}
|
||||
pstPtr++;
|
||||
}
|
||||
|
||||
IFS0bits.T1IF = 0; //Clear interrupt flag
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GP_TIMER_USE_TIMER_2
|
||||
|
||||
void __ISR(_TIMER_2_VECTOR, ipl2) Timer2MilliSecInterrupt(void) {
|
||||
unsigned int i;
|
||||
stTimer* pstPtr = &astTimer[0];
|
||||
|
||||
//disk_timerproc();
|
||||
|
||||
// Update all timers
|
||||
for (i = 0; i < TIMER_MAX_ID; i++) {
|
||||
// update timer only if timer is running
|
||||
if (pstPtr->bRunning) {
|
||||
if (pstPtr->uiMillisecCounter++ == 1000) {
|
||||
pstPtr->uiMillisecCounter = 0;
|
||||
pstPtr->uiSecondCounter++;
|
||||
}
|
||||
}
|
||||
pstPtr++;
|
||||
}
|
||||
|
||||
IFS0bits.T2IF = 0; //Clear interrupt flag
|
||||
}
|
||||
#endif
|
||||
|
||||
//EOF
|
||||
|
||||
|
||||
78
ChaletLora.X/Source/timer.h
Normal file
78
ChaletLora.X/Source/timer.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* 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 TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Includes */
|
||||
#include "define.h"
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Defines */
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definitions */
|
||||
typedef enum
|
||||
{
|
||||
HEARTBEAT_LED_TMR = 0,
|
||||
CHALET_POWER_RELAY_COIL_TIMER,
|
||||
SLEEP_FCN_TIMER,
|
||||
BATTERY_MONITOR_TIMER,
|
||||
CHALET_POWER_RELAY_AUTOTURNOFF_TIMER,
|
||||
WIFI_RECONNECT_TIMER,
|
||||
WIFI_TICK_TIMER,
|
||||
TIMER_MAX_ID
|
||||
}eTimerID;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int uiStart;
|
||||
unsigned int uiMillisecCounter;
|
||||
unsigned int uiSecondCounter;
|
||||
unsigned int uiPeriodMillisec;
|
||||
unsigned int uiPeriodSecond;
|
||||
bool bRunning;
|
||||
} stTimer;
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Prototypes */
|
||||
void TimerInit(void);
|
||||
int IsMilliSecTimerExpired(eTimerID p_eTimerID);
|
||||
int IsSecTimerExpired(eTimerID p_eTimerID);
|
||||
int IsTimerExpired(eTimerID p_eTimerID);
|
||||
void TimerStart(eTimerID p_eTimerID, unsigned int p_uiPeriod);
|
||||
void TimerStartSeconds(eTimerID p_eTimerID, unsigned int p_uiPeriod);
|
||||
void TimerStop(eTimerID p_eTimerID);
|
||||
void TimerReset(eTimerID p_eTimerID);
|
||||
bool IsTimerRunning(eTimerID p_eTimerID);
|
||||
|
||||
void Sleep(unsigned int millisecs);
|
||||
|
||||
#endif
|
||||
//EOF
|
||||
|
||||
2
ChaletLora.X/Source/versionbuild.h
Normal file
2
ChaletLora.X/Source/versionbuild.h
Normal file
@ -0,0 +1,2 @@
|
||||
#define VERSIONNUMBER "ENG00.01"
|
||||
#define BUILDNUMBER "1"
|
||||
317
ChaletLora.X/Source/winc1500/bsp/include/nm_bsp.h
Normal file
317
ChaletLora.X/Source/winc1500/bsp/include/nm_bsp.h
Normal file
@ -0,0 +1,317 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief WINC BSP API Declarations.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/** \defgroup nm_bsp BSP
|
||||
*/
|
||||
/**@defgroup BSPDefine Defines
|
||||
* @ingroup nm_bsp
|
||||
* @{
|
||||
*/
|
||||
#ifndef _NM_BSP_H_
|
||||
#define _NM_BSP_H_
|
||||
|
||||
#define NMI_API
|
||||
|
||||
#include "winc1500_config.h"
|
||||
#include "math.h"
|
||||
|
||||
#define NM_EDGE_INTERRUPT (1)
|
||||
|
||||
#define NM_DEBUG CONF_WINC_DEBUG
|
||||
#define NM_BSP_PRINTF CONF_WINC_PRINTF
|
||||
/*!<
|
||||
* Attribute used to define memory section to map Functions in host memory.
|
||||
*/
|
||||
#define CONST const
|
||||
|
||||
/*!<
|
||||
* Used for code portability.
|
||||
*/
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
/*!<
|
||||
* Void Pointer to '0' in case of NULL is not defined.
|
||||
*/
|
||||
|
||||
#define BSP_MIN(x, y) ((x) > (y) ? (y) : (x))
|
||||
/*!<
|
||||
* Computes the minimum of \b x and \b y.
|
||||
*/
|
||||
|
||||
//@}
|
||||
|
||||
/**@defgroup DataT DataTypes
|
||||
* @ingroup nm_bsp
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @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;
|
||||
//@}
|
||||
|
||||
#ifndef CORTUS_APP
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup BSPAPI Function
|
||||
* @ingroup nm_bsp
|
||||
*/
|
||||
|
||||
/** @defgroup NmBspInitFn nm_bsp_init
|
||||
* @ingroup BSPAPI
|
||||
*
|
||||
* Initialization for BSP (<strong>B</strong>oard <strong>S</strong>upport <strong>P</strong>ackage) such as Reset and Chip Enable Pins for WINC, delays,
|
||||
* register ISR, enable/disable IRQ for WINC, ...etc. You must use this function in the head of your application to
|
||||
* enable WINC and Host Driver to communicate with each other.
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn sint8 nm_bsp_init(void);
|
||||
* @brief This function is used to initialize the <strong>B</strong>oard <strong>S</strong>upport <strong>P</strong>ackage <strong>(BSP)</strong> in order to prepare the WINC
|
||||
* before it start working.
|
||||
*
|
||||
* The nm_bsp_init function is the first function that should be called at the beginning of
|
||||
* every application to initialize the BSP and the WINC board. Otherwise, the rest of the BSP function
|
||||
* calls will return with failure. This function should also be called after the WINC has been switched off
|
||||
with
|
||||
* a successful call to "nm_bsp_deinit" in order to reinitialize the BSP before the user can use any of the
|
||||
WINC API
|
||||
* functions again. After the function initialize the WINC. Hard reset must be applied to start the WINC
|
||||
board.
|
||||
* @note Implementation of this function is host dependent.
|
||||
* @warning inappropriate use of this function will lead to unavailability of host-chip communication.\n
|
||||
*
|
||||
* @see nm_bsp_deinit, nm_bsp_reset
|
||||
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
|
||||
|
||||
*/
|
||||
sint8 nm_bsp_init(void);
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup NmBspDeinitFn nm_bsp_deinit
|
||||
* @ingroup BSPAPI
|
||||
* De-initialization for BSP ((<strong>B</strong>oard <strong>S</strong>upport <strong>P</strong>ackage)). This function should be called only after
|
||||
* a successful call to nm_bsp_init.
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn sint8 nm_bsp_deinit(void);
|
||||
* @pre The BSP should be initialized through \ref nm_bsp_init first.
|
||||
* @brief This function is used to de-initialize the BSP and turn off the WINC board.
|
||||
*
|
||||
* The nm_bsp_deinit is the last function that should be called after the application has finished and
|
||||
before the WINC is switched * off. The function call turns off the WINC board by setting CHIP_EN and
|
||||
RESET_N signals low.Every function call of "nm_bsp_init" should
|
||||
* be matched with a call to nm_bsp_deinit. Failure to do so may result in the WINC consuming higher power
|
||||
than expected.
|
||||
* @note Implementation of this function is host dependent.
|
||||
* @warning misuse may lead to unknown behavior in case of soft reset.\n
|
||||
* @see nm_bsp_init
|
||||
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
|
||||
|
||||
*/
|
||||
sint8 nm_bsp_deinit(void);
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup NmBspResetFn nm_bsp_reset
|
||||
* @ingroup BSPAPI
|
||||
* Resetting WINC1500 SoC by setting CHIP_EN and RESET_N signals low, then after specific delay the function will
|
||||
* put CHIP_EN high then RESET_N high, for the timing between signals please review the WINC data-sheet
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn void nm_bsp_reset(void);
|
||||
* @param [in] None
|
||||
* @brief Applies a hardware reset to the WINC board.
|
||||
* The "nm_bsp_reset" is used to apply a hard reset to the WINC board by setting CHIP_EN and RESET_N
|
||||
signals low, then after specific delay
|
||||
* the function will put CHIP_EN high then RESET_N high, for the detailed timing between signals please
|
||||
review the WINC data-sheet. After a * successful call, the WINC board firmware will kick off to load and
|
||||
kick off the WINC firmware. This function should be called to reset the * WINC firmware after the BSP is
|
||||
initialized and before the start of any communication with WINC board. Calling this function at any other time *
|
||||
will result in losing the state and connections saved in the WINC board and starting again from the initial state. The
|
||||
host driver will need
|
||||
* to be de-initialized before calling nm_bsp_reset and initialized again after it using the "
|
||||
m2m_wifi_(de)init".
|
||||
* @pre Initialize \ref nm_bsp_init first
|
||||
* @note Implementation of this function is host dependent and called by HIF layer.
|
||||
* @warning Calling this function will drop any connection and internal state saved on the WINC firmware.
|
||||
* @see nm_bsp_init, m2m_wifi_init, m2m_wifi_deinit
|
||||
* @return None
|
||||
|
||||
*/
|
||||
void nm_bsp_reset(void);
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup NmBspSleepFn nm_bsp_sleep
|
||||
* @ingroup BSPAPI
|
||||
* Sleep in units of milliseconds.\n
|
||||
* This function used by HIF Layer according to different situations.
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn void nm_bsp_sleep(uint32);
|
||||
* @brief Used to put the host to sleep for the specified duration.
|
||||
* Forcing the host to sleep for extended period may lead to host not being able to respond to WINC board
|
||||
*events.It's important to be considerate while choosing the sleep period.
|
||||
* @param [in] u32TimeMsec
|
||||
* Time unit in milliseconds
|
||||
* @pre Initialize \ref nm_bsp_init first
|
||||
* @warning Maximum value must nor exceed 4294967295 milliseconds which is equal to 4294967.295 seconds.\n
|
||||
* @note Implementation of this function is host dependent.
|
||||
* @see nm_bsp_init
|
||||
* @return None
|
||||
*/
|
||||
void nm_bsp_sleep(uint32 u32TimeMsec);
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup NmBspRegisterFn nm_bsp_register_isr
|
||||
* @ingroup BSPAPI
|
||||
* Register ISR (Interrupt Service Routine) in the initialization of HIF (Host Interface) Layer.
|
||||
* When the interrupt trigger the BSP layer should call the pfisr function once inside the interrupt.
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn void nm_bsp_register_isr(tpfNmBspIsr);
|
||||
* @param [in] tpfNmBspIsr pfIsr
|
||||
* Pointer to ISR handler in HIF
|
||||
* @brief Register the host interface interrupt service routine.
|
||||
* WINC board utilize SPI interface to communicate with the host. This function register the SPI interrupt
|
||||
the notify * the host whenever there is an outstanding message from the WINC board. The function should
|
||||
be called during the initialization * of the host interface. It an internal driver function and shouldn't
|
||||
be called by the application.
|
||||
* @warning Make sure that ISR for IRQ pin for WINC is disabled by default in your implementation.
|
||||
* @note Implementation of this function is host dependent and called by HIF layer.
|
||||
* @see tpfNmBspIsr
|
||||
* @return None
|
||||
|
||||
*/
|
||||
void nm_bsp_register_isr(tpfNmBspIsr pfIsr);
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup NmBspInterruptCtrl nm_bsp_interrupt_ctrl
|
||||
* @ingroup BSPAPI
|
||||
* Synchronous enable/disable interrupts function
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn void nm_bsp_interrupt_ctrl(uint8);
|
||||
* @pre The interrupt must be registered using nm_bsp_register_isr first.
|
||||
* @brief Enable/Disable interrupts
|
||||
* This function can be used to enable/disable the WINC to host interrupt as the depending on how the driver
|
||||
is implemented.
|
||||
* It an internal driver function and shouldn't be called by the application.
|
||||
* @param [in] u8Enable
|
||||
* '0' disable interrupts. '1' enable interrupts
|
||||
* @see tpfNmBspIsr, nm_bsp_register_isr
|
||||
* @note Implementation of this function is host dependent and called by HIF layer.
|
||||
* @return None
|
||||
|
||||
*/
|
||||
void nm_bsp_interrupt_ctrl(uint8 u8Enable);
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _NM_BSP_BIG_END
|
||||
#define NM_BSP_B_L_32(x) \
|
||||
((((x)&0x000000FF) << 24) + (((x)&0x0000FF00) << 8) + (((x)&0x00FF0000) >> 8) + (((x)&0xFF000000) >> 24))
|
||||
#define NM_BSP_B_L_16(x) ((((x)&0x00FF) << 8) + (((x)&0xFF00) >> 8))
|
||||
#else
|
||||
#define NM_BSP_B_L_32(x) (x)
|
||||
#define NM_BSP_B_L_16(x) (x)
|
||||
#endif
|
||||
|
||||
#endif /*_NM_BSP_H_*/
|
||||
104
ChaletLora.X/Source/winc1500/bsp/include/nm_bsp_internal.h
Normal file
104
ChaletLora.X/Source/winc1500/bsp/include/nm_bsp_internal.h
Normal file
@ -0,0 +1,104 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief This module contains NMC1500 BSP APIs declarations.
|
||||
*
|
||||
* Copyright (c) 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
|
||||
*
|
||||
*/
|
||||
/**@defgroup BSPDefine Defines
|
||||
* @ingroup nm_bsp
|
||||
* @{
|
||||
*/
|
||||
#ifndef _NM_BSP_INTERNAL_H_
|
||||
#define _NM_BSP_INTERNAL_H_
|
||||
|
||||
#ifdef WIN32
|
||||
#include "nm_bsp_win32.h"
|
||||
#endif
|
||||
|
||||
#ifdef __K20D50M__
|
||||
#include "nm_bsp_k20d50m.h"
|
||||
#endif
|
||||
|
||||
#ifdef __MSP430FR5739__
|
||||
#include "bsp_msp430fr5739.h"
|
||||
#endif
|
||||
|
||||
#ifdef _FREESCALE_MCF51CN128_
|
||||
#include "bsp/include/nm_bsp_mcf51cn128.h"
|
||||
#endif
|
||||
|
||||
#ifdef __MCF964548__
|
||||
#include "bsp/include/nm_bsp_mc96f4548.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APP_APS3_CORTUS__
|
||||
#include "nm_bsp_aps3_cortus.h"
|
||||
#endif
|
||||
|
||||
#if (defined __SAMR21G18A__)
|
||||
#include "bsp/include/nm_bsp_samr21.h"
|
||||
#endif
|
||||
|
||||
#if (defined __SAML21J18A__) || (defined __SAML21J18B__)
|
||||
#include "bsp/include/nm_bsp_saml21.h"
|
||||
#endif
|
||||
|
||||
#if (defined __SAML22N18A__)
|
||||
#include "bsp/include/nm_bsp_saml22.h"
|
||||
#endif
|
||||
|
||||
#if (defined __SAM4S16C__) || (defined __SAM4SD32C__)
|
||||
#include "bsp/include/nm_bsp_sam4s.h"
|
||||
#endif
|
||||
|
||||
#if (defined __SAME70Q21__) || (defined __SAMV71Q21__)
|
||||
#include "bsp/include/nm_bsp_same70.h"
|
||||
#endif
|
||||
|
||||
#ifdef CORTUS_APP
|
||||
#include "crt_iface.h"
|
||||
#endif
|
||||
|
||||
#ifdef NRF51
|
||||
#include "nm_bsp_nrf51822.h"
|
||||
#endif
|
||||
|
||||
#ifdef _ARDUINO_UNO_
|
||||
#include "bsp/include/nm_bsp_arduino_uno.h"
|
||||
#endif
|
||||
|
||||
#endif //_NM_BSP_INTERNAL_H_
|
||||
181
ChaletLora.X/Source/winc1500/bsp/source/nm_bsp.c
Normal file
181
ChaletLora.X/Source/winc1500/bsp/source/nm_bsp.c
Normal file
@ -0,0 +1,181 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief This module contains SAMD21 BSP APIs implementation.
|
||||
*
|
||||
* Copyright (c) 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bsp/include/nm_bsp.h"
|
||||
#include "common/include/nm_common.h"
|
||||
#include "timer.h"
|
||||
#include "define.h"
|
||||
#include "BoardCfg.h"
|
||||
//#include <plib.h>
|
||||
|
||||
//#include "atmel_start.h"
|
||||
//#include "winc_init.h"
|
||||
|
||||
#ifndef CONF_WINC_EXT_INT_PIN
|
||||
#define CONF_WINC_EXT_INT_PIN 0
|
||||
#endif
|
||||
|
||||
static tpfNmBspIsr gpfIsr = NULL;
|
||||
|
||||
void __ISR(_EXTERNAL_0_VECTOR , ipl3) chip_isr(void)
|
||||
//static void chip_isr(void)
|
||||
{
|
||||
if (gpfIsr)
|
||||
{
|
||||
gpfIsr();
|
||||
}
|
||||
|
||||
IFS0bits.INT0IF = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @fn nm_bsp_init
|
||||
* @brief Initialize BSP
|
||||
* @return 0 in case of success and -1 in case of failure
|
||||
*/
|
||||
sint8 nm_bsp_init(void)
|
||||
{
|
||||
gpfIsr = NULL;
|
||||
//
|
||||
//JFM Not necessary, we know our timer base is 1ms...
|
||||
|
||||
// /* Make sure a 1ms Systick is configured. */
|
||||
// if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk && SysTick->CTRL & SysTick_CTRL_TICKINT_Msk)) {
|
||||
// delay_init(SysTick);
|
||||
// }
|
||||
return M2M_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn nm_bsp_deinit
|
||||
* @brief De-iInitialize BSP
|
||||
* @return 0 in case of success and -1 in case of failure
|
||||
*/
|
||||
sint8 nm_bsp_deinit(void)
|
||||
{
|
||||
return M2M_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn nm_bsp_reset
|
||||
* @brief Reset NMC1500 SoC by setting CHIP_EN and RESET_N signals low,
|
||||
* CHIP_EN high then RESET_N high
|
||||
*/
|
||||
void nm_bsp_reset(void)
|
||||
{
|
||||
// GP_DEBUG_1_PIN = 1;
|
||||
|
||||
WIFI_CHP_EN_PIN = 0;
|
||||
WIFI_CHP_RST_PIN = 0;
|
||||
// Sleep(1); //JFM
|
||||
Sleep(10);
|
||||
WIFI_CHP_EN_PIN = 1;
|
||||
// Sleep(5); JFM
|
||||
Sleep(15);
|
||||
WIFI_CHP_RST_PIN = 1;
|
||||
|
||||
// GP_DEBUG_1_PIN = 0;
|
||||
|
||||
|
||||
// gpio_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, false);
|
||||
// gpio_set_pin_level(CONF_WINC_PIN_RESET, false);
|
||||
// nm_bsp_sleep(1);
|
||||
// gpio_set_pin_level(CONF_WINC_PIN_CHIP_ENABLE, true);
|
||||
// nm_bsp_sleep(5);
|
||||
// gpio_set_pin_level(CONF_WINC_PIN_RESET, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* @fn nm_bsp_sleep
|
||||
* @brief Sleep in units of mSec
|
||||
* @param[IN] u32TimeMsec
|
||||
* Time in milliseconds
|
||||
*/
|
||||
void nm_bsp_sleep(uint32 u32TimeMsec)
|
||||
{
|
||||
Sleep(u32TimeMsec);
|
||||
|
||||
|
||||
|
||||
// while (u32TimeMsec--) {
|
||||
// delay_ms(1);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal Get the PIO hardware instance
|
||||
*
|
||||
* \param[in] pin The PIO pin
|
||||
*
|
||||
* \return The instance of PIO hardware
|
||||
*/
|
||||
|
||||
/*
|
||||
* @fn nm_bsp_register_isr
|
||||
* @brief Register interrupt service routine
|
||||
* @param[IN] pfIsr
|
||||
* Pointer to ISR handler
|
||||
*/
|
||||
void nm_bsp_register_isr(tpfNmBspIsr pfIsr)
|
||||
{
|
||||
gpfIsr = pfIsr;
|
||||
//
|
||||
// ext_irq_register(CONF_WINC_EXT_INT_PIN, chip_isr);
|
||||
}
|
||||
|
||||
/*
|
||||
* @fn nm_bsp_interrupt_ctrl
|
||||
* @brief Enable/Disable interrupts
|
||||
* @param[IN] u8Enable
|
||||
* '0' disable interrupts. '1' enable interrupts
|
||||
*/
|
||||
void nm_bsp_interrupt_ctrl(uint8 u8Enable)
|
||||
{
|
||||
if(u8Enable == 0)
|
||||
{
|
||||
IEC0bits.INT0IE = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
IEC0bits.INT0IE = 1;
|
||||
}
|
||||
// _ext_irq_enable(CONF_WINC_EXT_INT_PIN, u8Enable);
|
||||
}
|
||||
@ -0,0 +1,173 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief This module contains NMC1000 bus wrapper APIs declarations.
|
||||
*
|
||||
* Copyright (c) 2015 - 2017 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 _NM_BUS_WRAPPER_H_
|
||||
#define _NM_BUS_WRAPPER_H_
|
||||
|
||||
#include "common/include/nm_common.h"
|
||||
|
||||
/**
|
||||
BUS Type
|
||||
**/
|
||||
#define NM_BUS_TYPE_I2C ((uint8)0)
|
||||
#define NM_BUS_TYPE_SPI ((uint8)1)
|
||||
#define NM_BUS_TYPE_UART ((uint8)2)
|
||||
/**
|
||||
IOCTL commands
|
||||
**/
|
||||
#define NM_BUS_IOCTL_R ((uint8)0) /*!< Read only ==> I2C/UART. Parameter:tstrNmI2cDefault/tstrNmUartDefault */
|
||||
#define NM_BUS_IOCTL_W ((uint8)1) /*!< Write only ==> I2C/UART. Parameter type tstrNmI2cDefault/tstrNmUartDefault*/
|
||||
#define NM_BUS_IOCTL_W_SPECIAL \
|
||||
((uint8)2) /*!< Write two buffers within the same transaction \
|
||||
(same start/stop conditions) ==> I2C only. Parameter:tstrNmI2cSpecial */
|
||||
#define NM_BUS_IOCTL_RW ((uint8)3) /*!< Read/Write at the same time ==> SPI only. Parameter:tstrNmSpiRw */
|
||||
|
||||
#define NM_BUS_IOCTL_WR_RESTART \
|
||||
((uint8)4) /*!< Write buffer then made restart condition then read ==> I2C only. parameter:tstrNmI2cSpecial */
|
||||
/**
|
||||
* @struct tstrNmBusCapabilities
|
||||
* @brief Structure holding bus capabilities information
|
||||
* @sa NM_BUS_TYPE_I2C, NM_BUS_TYPE_SPI
|
||||
*/
|
||||
typedef struct {
|
||||
uint16 u16MaxTrxSz; /*!< Maximum transfer size. Must be >= 16 bytes*/
|
||||
} tstrNmBusCapabilities;
|
||||
|
||||
/**
|
||||
* @struct tstrNmI2cDefault
|
||||
* @brief Structure holding I2C default operation parameters
|
||||
* @sa NM_BUS_IOCTL_R, NM_BUS_IOCTL_W
|
||||
*/
|
||||
typedef struct {
|
||||
uint8 u8SlaveAdr;
|
||||
uint8 *pu8Buf; /*!< Operation buffer */
|
||||
uint16 u16Sz; /*!< Operation size */
|
||||
} tstrNmI2cDefault;
|
||||
|
||||
/**
|
||||
* @struct tstrNmI2cSpecial
|
||||
* @brief Structure holding I2C special operation parameters
|
||||
* @sa NM_BUS_IOCTL_W_SPECIAL
|
||||
*/
|
||||
typedef struct {
|
||||
uint8 u8SlaveAdr;
|
||||
uint8 *pu8Buf1; /*!< pointer to the 1st buffer */
|
||||
uint8 *pu8Buf2; /*!< pointer to the 2nd buffer */
|
||||
uint16 u16Sz1; /*!< 1st buffer size */
|
||||
uint16 u16Sz2; /*!< 2nd buffer size */
|
||||
} tstrNmI2cSpecial;
|
||||
|
||||
/**
|
||||
* @struct tstrNmSpiRw
|
||||
* @brief Structure holding SPI R/W parameters
|
||||
* @sa NM_BUS_IOCTL_RW
|
||||
*/
|
||||
typedef struct {
|
||||
uint8 *pu8InBuf; /*!< pointer to input buffer.
|
||||
Can be set to null and in this case zeros should be sent at MOSI */
|
||||
uint8 *pu8OutBuf; /*!< pointer to output buffer.
|
||||
Can be set to null and in this case data from MISO can be ignored */
|
||||
uint16 u16Sz; /*!< Transfere size */
|
||||
} tstrNmSpiRw;
|
||||
|
||||
/**
|
||||
* @struct tstrNmUartDefault
|
||||
* @brief Structure holding UART default operation parameters
|
||||
* @sa NM_BUS_IOCTL_R, NM_BUS_IOCTL_W
|
||||
*/
|
||||
typedef struct {
|
||||
uint8 *pu8Buf; /*!< Operation buffer */
|
||||
uint16 u16Sz; /*!< Operation size */
|
||||
} tstrNmUartDefault;
|
||||
/*!< Bus capabilities. This structure must be declared at platform specific bus wrapper */
|
||||
extern tstrNmBusCapabilities egstrNmBusCapabilities;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/**
|
||||
* @fn nm_bus_init
|
||||
* @brief Initialize the bus wrapper
|
||||
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
|
||||
*/
|
||||
sint8 nm_bus_init(void *);
|
||||
|
||||
/**
|
||||
* @fn nm_bus_ioctl
|
||||
* @brief send/receive from the bus
|
||||
* @param [in] u8Cmd
|
||||
* IOCTL command for the operation
|
||||
* @param [in] pvParameter
|
||||
* Arbitrary parameter depending on IOCTL
|
||||
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
|
||||
* @note For SPI only, it's important to be able to send/receive at the same time
|
||||
*/
|
||||
sint8 nm_bus_ioctl(uint8 u8Cmd, void *pvParameter);
|
||||
|
||||
/**
|
||||
* @fn nm_bus_deinit
|
||||
* @brief De-initialize the bus wrapper
|
||||
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
|
||||
*/
|
||||
sint8 nm_bus_deinit(void);
|
||||
|
||||
/*
|
||||
* @fn nm_bus_reinit
|
||||
* @brief re-initialize the bus wrapper
|
||||
* @param [in] void *config
|
||||
* re-init configuration data
|
||||
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
|
||||
*/
|
||||
sint8 nm_bus_reinit(void *);
|
||||
/*
|
||||
* @fn nm_bus_get_chip_type
|
||||
* @brief get chip type
|
||||
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
|
||||
*/
|
||||
#ifdef CONF_WINC_USE_UART
|
||||
uint8 nm_bus_get_chip_type(void);
|
||||
sint8 nm_bus_break(void);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_NM_BUS_WRAPPER_H_*/
|
||||
206
ChaletLora.X/Source/winc1500/bus_wrapper/source/nm_bus_wrapper.c
Normal file
206
ChaletLora.X/Source/winc1500/bus_wrapper/source/nm_bus_wrapper.c
Normal file
@ -0,0 +1,206 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief This module contains NMC1000 bus wrapper APIs implementation.
|
||||
*
|
||||
* Copyright (c) 2015 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bsp/include/nm_bsp.h"
|
||||
#include "common/include/nm_common.h"
|
||||
#include "bus_wrapper/include/nm_bus_wrapper.h"
|
||||
#include "define.h"
|
||||
#include "BoardCfg.h"
|
||||
#include "SPI.h"
|
||||
//#include "atmel_start.h"
|
||||
//#include "winc_init.h"
|
||||
|
||||
#define NM_BUS_MAX_TRX_SZ 256
|
||||
|
||||
tstrNmBusCapabilities egstrNmBusCapabilities = {NM_BUS_MAX_TRX_SZ};
|
||||
|
||||
|
||||
static sint8 spi_rw(uint8 *pu8Mosi, uint8 *pu8Miso, uint16 u16Sz)
|
||||
{
|
||||
uint8 u8Dummy = 0;
|
||||
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
|
||||
|
||||
if (!pu8Mosi)
|
||||
{
|
||||
pu8Mosi = &u8Dummy;
|
||||
u8SkipMosi = 1;
|
||||
}
|
||||
else if (!pu8Miso)
|
||||
{
|
||||
pu8Miso = &u8Dummy;
|
||||
u8SkipMiso = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return M2M_ERR_BUS_FAIL;
|
||||
}
|
||||
|
||||
|
||||
if (!u8SkipMiso)
|
||||
{
|
||||
while(u16Sz-- != 0)
|
||||
{
|
||||
uint8 tmp;
|
||||
tmp = SPITransaction(0xDE);
|
||||
*pu8Miso++ = tmp;
|
||||
}
|
||||
}
|
||||
if (!u8SkipMosi)
|
||||
{
|
||||
while(u16Sz-- != 0)
|
||||
{
|
||||
uint8 tmp;
|
||||
tmp = SPITransaction(*pu8Mosi++); //assign to tmp for debug purposes only.
|
||||
}
|
||||
}
|
||||
WIFI_SPI_SS_PIN = 1;
|
||||
|
||||
|
||||
/*uint8 u8Dummy = 0;
|
||||
uint8 u8SkipMosi = 0, u8SkipMiso = 0;
|
||||
|
||||
if (!pu8Mosi)
|
||||
{
|
||||
pu8Mosi = &u8Dummy;
|
||||
u8SkipMosi = 1;
|
||||
}
|
||||
else if (!pu8Miso)
|
||||
{
|
||||
pu8Miso = &u8Dummy;
|
||||
u8SkipMiso = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return M2M_ERR_BUS_FAIL;
|
||||
}
|
||||
|
||||
gpio_set_pin_level(CONF_WINC_PIN_CHIP_SELECT, false);
|
||||
if (!u8SkipMiso) {
|
||||
io_read(io, pu8Miso, u16Sz);
|
||||
}
|
||||
if (!u8SkipMosi) {
|
||||
io_write(io, pu8Mosi, u16Sz);
|
||||
}
|
||||
gpio_set_pin_level(CONF_WINC_PIN_CHIP_SELECT, true);*/
|
||||
|
||||
return M2M_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @fn nm_bus_init
|
||||
* @brief Initialize the bus wrapper
|
||||
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
|
||||
*/
|
||||
sint8 nm_bus_init(void *pvinit)
|
||||
{
|
||||
sint8 result = M2M_SUCCESS;
|
||||
nm_bsp_reset();
|
||||
nm_bsp_sleep(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//JFM The SPI module has been initialized in InitBoard()
|
||||
//so the two following lines are not needed.
|
||||
/* spi_m_sync_get_io_descriptor(spi_instance, &io);
|
||||
spi_m_sync_enable(spi_instance);/*
|
||||
|
||||
nm_bsp_reset();
|
||||
nm_bsp_sleep(1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* @fn nm_bus_ioctl
|
||||
* @brief send/receive from the bus
|
||||
* @param[IN] u8Cmd
|
||||
* IOCTL command for the operation
|
||||
* @param[IN] pvParameter
|
||||
* Arbitrary parameter depenging on IOCTL
|
||||
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
|
||||
* @note For SPI only, it's important to be able to send/receive at the same time
|
||||
*/
|
||||
sint8 nm_bus_ioctl(uint8 u8Cmd, void *pvParameter)
|
||||
{
|
||||
sint8 s8Ret = 0;
|
||||
switch (u8Cmd)
|
||||
{
|
||||
case NM_BUS_IOCTL_RW:
|
||||
{
|
||||
tstrNmSpiRw *pstrParam = (tstrNmSpiRw *)pvParameter;
|
||||
s8Ret = spi_rw(pstrParam->pu8InBuf, pstrParam->pu8OutBuf, pstrParam->u16Sz);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
s8Ret = -1;
|
||||
M2M_ERR("invalide ioclt cmd\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return s8Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @fn nm_bus_deinit
|
||||
* @brief De-initialize the bus wrapper
|
||||
*/
|
||||
sint8 nm_bus_deinit(void)
|
||||
{
|
||||
sint8 result = 0;
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
* @fn nm_bus_reinit
|
||||
* @brief re-initialize the bus wrapper
|
||||
* @param [in] void *config
|
||||
* re-init configuration data
|
||||
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
|
||||
*/
|
||||
sint8 nm_bus_reinit(void *config)
|
||||
{
|
||||
return M2M_SUCCESS;
|
||||
}
|
||||
150
ChaletLora.X/Source/winc1500/common/include/nm_common.h
Normal file
150
ChaletLora.X/Source/winc1500/common/include/nm_common.h
Normal file
@ -0,0 +1,150 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief WINC Driver Common API Declarations.
|
||||
*
|
||||
* Copyright (c) 2015 - 2017 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 _NM_COMMON_H_
|
||||
#define _NM_COMMON_H_
|
||||
|
||||
#include "bsp/include/nm_bsp.h"
|
||||
#include "common/include/nm_debug.h"
|
||||
|
||||
/**@defgroup CommonDefines CommonDefines
|
||||
* @ingroup WlanDefines
|
||||
*/
|
||||
/**@{*/
|
||||
#define M2M_TIME_OUT_DELAY 10000
|
||||
|
||||
/*states*/
|
||||
#define M2M_SUCCESS ((sint8)0)
|
||||
#define M2M_ERR_SEND ((sint8)-1)
|
||||
#define M2M_ERR_RCV ((sint8)-2)
|
||||
#define M2M_ERR_MEM_ALLOC ((sint8)-3)
|
||||
#define M2M_ERR_TIME_OUT ((sint8)-4)
|
||||
#define M2M_ERR_INIT ((sint8)-5)
|
||||
#define M2M_ERR_BUS_FAIL ((sint8)-6)
|
||||
#define M2M_NOT_YET ((sint8)-7)
|
||||
#define M2M_ERR_FIRMWARE ((sint8)-8)
|
||||
#define M2M_SPI_FAIL ((sint8)-9)
|
||||
#define M2M_ERR_FIRMWARE_bURN ((sint8)-10)
|
||||
#define M2M_ACK ((sint8)-11)
|
||||
#define M2M_ERR_FAIL ((sint8)-12)
|
||||
#define M2M_ERR_FW_VER_MISMATCH ((sint8)-13)
|
||||
#define M2M_ERR_SCAN_IN_PROGRESS ((sint8)-14)
|
||||
#define M2M_ERR_INVALID_ARG ((sint8)-15)
|
||||
#define M2M_ERR_INVALID ((sint8)-16)
|
||||
|
||||
/*i2c MAASTER ERR*/
|
||||
#define I2C_ERR_LARGE_ADDRESS 0xE1UL /*the address exceed the max addressing mode in i2c flash*/
|
||||
#define I2C_ERR_TX_ABRT 0xE2UL /*NO ACK from slave*/
|
||||
#define I2C_ERR_OVER_SIZE 0xE3UL /**/
|
||||
#define ERR_PREFIX_NMIS 0xE4UL /*wrong first four byte in flash NMIS*/
|
||||
#define ERR_FIRMEWARE_EXCEED_SIZE 0xE5UL /*Total size of firmware exceed the max size 256k*/
|
||||
/**/
|
||||
#define PROGRAM_START 0x26961735UL
|
||||
#define BOOT_SUCCESS 0x10add09eUL
|
||||
#define BOOT_START 0x12345678UL
|
||||
|
||||
#define NBIT31 (0x80000000)
|
||||
#define NBIT30 (0x40000000)
|
||||
#define NBIT29 (0x20000000)
|
||||
#define NBIT28 (0x10000000)
|
||||
#define NBIT27 (0x08000000)
|
||||
#define NBIT26 (0x04000000)
|
||||
#define NBIT25 (0x02000000)
|
||||
#define NBIT24 (0x01000000)
|
||||
#define NBIT23 (0x00800000)
|
||||
#define NBIT22 (0x00400000)
|
||||
#define NBIT21 (0x00200000)
|
||||
#define NBIT20 (0x00100000)
|
||||
#define NBIT19 (0x00080000)
|
||||
#define NBIT18 (0x00040000)
|
||||
#define NBIT17 (0x00020000)
|
||||
#define NBIT16 (0x00010000)
|
||||
#define NBIT15 (0x00008000)
|
||||
#define NBIT14 (0x00004000)
|
||||
#define NBIT13 (0x00002000)
|
||||
#define NBIT12 (0x00001000)
|
||||
#define NBIT11 (0x00000800)
|
||||
#define NBIT10 (0x00000400)
|
||||
#define NBIT9 (0x00000200)
|
||||
#define NBIT8 (0x00000100)
|
||||
#define NBIT7 (0x00000080)
|
||||
#define NBIT6 (0x00000040)
|
||||
#define NBIT5 (0x00000020)
|
||||
#define NBIT4 (0x00000010)
|
||||
#define NBIT3 (0x00000008)
|
||||
#define NBIT2 (0x00000004)
|
||||
#define NBIT1 (0x00000002)
|
||||
#define NBIT0 (0x00000001)
|
||||
|
||||
#define M2M_MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
#define M2M_SEL(x, m1, m2, m3) ((x > 1) ? ((x > 2) ? (m3) : (m2)) : (m1))
|
||||
#define WORD_ALIGN(val) (((val)&0x03) ? ((val) + 4 - ((val)&0x03)) : (val))
|
||||
|
||||
#define DATA_PKT_OFFSET 4
|
||||
|
||||
#ifndef BIG_ENDIAN
|
||||
#define BYTE_0(word) ((uint8)(((word) >> 0) & 0x000000FFUL))
|
||||
#define BYTE_1(word) ((uint8)(((word) >> 8) & 0x000000FFUL))
|
||||
#define BYTE_2(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
|
||||
#define BYTE_3(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
|
||||
#else
|
||||
#define BYTE_0(word) ((uint8)(((word) >> 24) & 0x000000FFUL))
|
||||
#define BYTE_1(word) ((uint8)(((word) >> 16) & 0x000000FFUL))
|
||||
#define BYTE_2(word) ((uint8)(((word) >> 8) & 0x000000FFUL))
|
||||
#define BYTE_3(word) ((uint8)(((word) >> 0) & 0x000000FFUL))
|
||||
#endif
|
||||
|
||||
/**@}*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
NMI_API void m2m_memcpy(uint8 *pDst, uint8 *pSrc, uint32 sz);
|
||||
NMI_API void m2m_memset(uint8 *pBuf, uint8 val, uint32 sz);
|
||||
NMI_API uint16 m2m_strlen(uint8 *pcStr);
|
||||
NMI_API sint8 m2m_memcmp(uint8 *pu8Buff1, uint8 *pu8Buff2, uint32 u32Size);
|
||||
NMI_API uint8 m2m_strncmp(uint8 *pcS1, uint8 *pcS2, uint16 u16Len);
|
||||
NMI_API uint8 *m2m_strstr(uint8 *pcIn, uint8 *pcStr);
|
||||
NMI_API uint8 m2m_checksum(uint8 *buf, int sz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*_NM_COMMON_H_*/
|
||||
117
ChaletLora.X/Source/winc1500/common/include/nm_debug.h
Normal file
117
ChaletLora.X/Source/winc1500/common/include/nm_debug.h
Normal file
@ -0,0 +1,117 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief This module contains debug APIs declarations.
|
||||
*
|
||||
* 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 _NM_DEBUG_H_
|
||||
#define _NM_DEBUG_H_
|
||||
|
||||
#include "bsp/include/nm_bsp.h"
|
||||
/* #include "bsp/include/nm_bsp_internal.h" */
|
||||
|
||||
/**@defgroup DebugDefines DebugDefines
|
||||
* @ingroup WlanDefines
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
#define M2M_LOG_NONE 0
|
||||
#define M2M_LOG_ERROR 1
|
||||
#define M2M_LOG_INFO 2
|
||||
#define M2M_LOG_REQ 3
|
||||
#define M2M_LOG_DBG 4
|
||||
|
||||
#if (defined __APS3_CORTUS__)
|
||||
#define M2M_LOG_LEVEL M2M_LOG_INFO
|
||||
#else
|
||||
#define M2M_LOG_LEVEL M2M_LOG_REQ
|
||||
#endif
|
||||
|
||||
#define M2M_ERR(...)
|
||||
#define M2M_INFO(...)
|
||||
#define M2M_REQ(...)
|
||||
#define M2M_DBG(...)
|
||||
#define M2M_PRINT(...)
|
||||
|
||||
#if (CONF_WINC_DEBUG == 1)
|
||||
#undef M2M_PRINT
|
||||
#define M2M_PRINT(...) \
|
||||
do { \
|
||||
CONF_WINC_PRINTF(__VA_ARGS__); \
|
||||
CONF_WINC_PRINTF("\r"); \
|
||||
} while (0)
|
||||
#if (M2M_LOG_LEVEL >= M2M_LOG_ERROR)
|
||||
#undef M2M_ERR
|
||||
#define M2M_ERR(...) \
|
||||
do { \
|
||||
CONF_WINC_PRINTF("(APP)(ERR)[%s][%d]", __FUNCTION__, __LINE__); \
|
||||
CONF_WINC_PRINTF(__VA_ARGS__); \
|
||||
CONF_WINC_PRINTF("\r"); \
|
||||
} while (0)
|
||||
#if (M2M_LOG_LEVEL >= M2M_LOG_INFO)
|
||||
#undef M2M_INFO
|
||||
#define M2M_INFO(...) \
|
||||
do { \
|
||||
CONF_WINC_PRINTF("(APP)(INFO)"); \
|
||||
CONF_WINC_PRINTF(__VA_ARGS__); \
|
||||
CONF_WINC_PRINTF("\r"); \
|
||||
} while (0)
|
||||
#if (M2M_LOG_LEVEL >= M2M_LOG_REQ)
|
||||
#undef M2M_REQ
|
||||
#define M2M_REQ(...) \
|
||||
do { \
|
||||
CONF_WINC_PRINTF("(APP)(R)"); \
|
||||
CONF_WINC_PRINTF(__VA_ARGS__); \
|
||||
CONF_WINC_PRINTF("\r"); \
|
||||
} while (0)
|
||||
#if (M2M_LOG_LEVEL >= M2M_LOG_DBG)
|
||||
#undef M2M_DBG
|
||||
#define M2M_DBG(...) \
|
||||
do { \
|
||||
CONF_WINC_PRINTF("(APP)(DBG)[%s][%d]", __FUNCTION__, __LINE__); \
|
||||
CONF_WINC_PRINTF(__VA_ARGS__); \
|
||||
CONF_WINC_PRINTF("\r"); \
|
||||
} while (0)
|
||||
#endif /*M2M_LOG_DBG*/
|
||||
#endif /*M2M_LOG_REQ*/
|
||||
#endif /*M2M_LOG_INFO*/
|
||||
#endif /*M2M_LOG_ERROR*/
|
||||
#endif /*CONF_WINC_DEBUG */
|
||||
|
||||
/**@}*/
|
||||
#endif /* _NM_DEBUG_H_ */
|
||||
132
ChaletLora.X/Source/winc1500/common/source/nm_common.c
Normal file
132
ChaletLora.X/Source/winc1500/common/source/nm_common.c
Normal file
@ -0,0 +1,132 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief This module contains common APIs declarations.
|
||||
*
|
||||
* Copyright (c) 2015 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
|
||||
*
|
||||
*/
|
||||
#include "common/include/nm_common.h"
|
||||
|
||||
void m2m_memcpy(uint8 *pDst, uint8 *pSrc, uint32 sz)
|
||||
{
|
||||
if (sz == 0)
|
||||
return;
|
||||
do {
|
||||
*pDst = *pSrc;
|
||||
pDst++;
|
||||
pSrc++;
|
||||
} while (--sz);
|
||||
}
|
||||
uint8 m2m_checksum(uint8 *buf, int sz)
|
||||
{
|
||||
uint8 cs = 0;
|
||||
while (--sz) {
|
||||
cs ^= *buf;
|
||||
buf++;
|
||||
}
|
||||
|
||||
return cs;
|
||||
}
|
||||
|
||||
void m2m_memset(uint8 *pBuf, uint8 val, uint32 sz)
|
||||
{
|
||||
if (sz == 0)
|
||||
return;
|
||||
do {
|
||||
*pBuf = val;
|
||||
pBuf++;
|
||||
} while (--sz);
|
||||
}
|
||||
|
||||
uint16 m2m_strlen(uint8 *pcStr)
|
||||
{
|
||||
uint16 u16StrLen = 0;
|
||||
while (*pcStr) {
|
||||
u16StrLen++;
|
||||
pcStr++;
|
||||
}
|
||||
return u16StrLen;
|
||||
}
|
||||
|
||||
uint8 m2m_strncmp(uint8 *pcS1, uint8 *pcS2, uint16 u16Len)
|
||||
{
|
||||
for (; u16Len > 0; pcS1++, pcS2++, --u16Len)
|
||||
if (*pcS1 != *pcS2)
|
||||
return ((*(uint8 *)pcS1 < *(uint8 *)pcS2) ? -1 : +1);
|
||||
else if (*pcS1 == '\0')
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Finds the occurance of pcStr in pcIn.
|
||||
If pcStr is part of pcIn it returns a valid pointer to the start of pcStr within pcIn.
|
||||
Otherwise a NULL Pointer is returned.
|
||||
*/
|
||||
uint8 *m2m_strstr(uint8 *pcIn, uint8 *pcStr)
|
||||
{
|
||||
uint8 u8c;
|
||||
uint16 u16StrLen;
|
||||
|
||||
u8c = *pcStr++;
|
||||
if (!u8c)
|
||||
return (uint8 *)pcIn; // Trivial empty string case
|
||||
|
||||
u16StrLen = m2m_strlen(pcStr);
|
||||
do {
|
||||
uint8 u8Sc;
|
||||
|
||||
do {
|
||||
u8Sc = *pcIn++;
|
||||
if (!u8Sc)
|
||||
return (uint8 *)0;
|
||||
} while (u8Sc != u8c);
|
||||
} while (m2m_strncmp(pcIn, pcStr, u16StrLen) != 0);
|
||||
|
||||
return (uint8 *)(pcIn - 1);
|
||||
}
|
||||
|
||||
sint8 m2m_memcmp(uint8 *pu8Buff1, uint8 *pu8Buff2, uint32 u32Size)
|
||||
{
|
||||
uint32 i;
|
||||
sint8 s8Result = 0;
|
||||
for (i = 0; i < u32Size; i++) {
|
||||
if (pu8Buff1[i] != pu8Buff2[i]) {
|
||||
s8Result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return s8Result;
|
||||
}
|
||||
232
ChaletLora.X/Source/winc1500/driver/include/ecc_types.h
Normal file
232
ChaletLora.X/Source/winc1500/driver/include/ecc_types.h
Normal file
@ -0,0 +1,232 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief WINC Application Interface Internal Types.
|
||||
*
|
||||
* Copyright (c) 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 __ECC_TYPES_H__
|
||||
#define __ECC_TYPES_H__
|
||||
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
INCLUDES
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
|
||||
#ifndef _FIRMWARE_
|
||||
#include "driver/include/m2m_types.h"
|
||||
#else
|
||||
#include "m2m_types.h"
|
||||
#endif
|
||||
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
MACROS
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
|
||||
#define ECC_LARGEST_CURVE_SIZE (32)
|
||||
/*!<
|
||||
The size of the the largest supported EC. For now, assuming
|
||||
the 256-bit EC is the largest supported curve type.
|
||||
*/
|
||||
|
||||
#define ECC_POINT_MAX_SIZE ECC_LARGEST_CURVE_SIZE
|
||||
/*!<
|
||||
Maximum size of one coordinate of an EC point.
|
||||
*/
|
||||
|
||||
#define ECC_POINT_MAX_SIZE_WORDS (ECC_POINT_MAX_SIZE / 4)
|
||||
/*!<
|
||||
SIZE in 32-bit words.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#define ECC_NUM_SUPP_CURVES ((sizeof(gastrECCSuppList)) / (sizeof(tstrEllipticCurve)))
|
||||
#endif
|
||||
/*!<
|
||||
*/
|
||||
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
DATA TYPES
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
|
||||
/*!
|
||||
@enum \
|
||||
tenuEcNamedCurve
|
||||
|
||||
@brief EC Named Curves
|
||||
|
||||
Defines a list of supported ECC named curves.
|
||||
*/
|
||||
typedef enum EcNamedCurve {
|
||||
EC_SECP192R1 = 19,
|
||||
/*!<
|
||||
It is defined by NIST as P192 and by the SEC Group as secp192r1.
|
||||
*/
|
||||
EC_SECP256R1 = 23,
|
||||
/*!<
|
||||
It is defined by NIST as P256 and by the SEC Group as secp256r1.
|
||||
*/
|
||||
EC_SECP384R1 = 24,
|
||||
/*!<
|
||||
It is defined by NIST as P384 and by the SEC Group as secp384r1.
|
||||
*/
|
||||
EC_SECP521R1 = 25,
|
||||
/*!<
|
||||
It is defined by NIST as P521 and by the SEC Group as secp521r1.
|
||||
*/
|
||||
EC_UNKNOWN = 255
|
||||
} tenuEcNamedCurve;
|
||||
|
||||
/*!
|
||||
@struct \
|
||||
tstrECPoint
|
||||
|
||||
@brief Elliptic Curve point representation
|
||||
*/
|
||||
typedef struct EcPoint {
|
||||
uint8 X[ECC_POINT_MAX_SIZE];
|
||||
/*!<
|
||||
The X-coordinate of the ec point.
|
||||
*/
|
||||
uint8 Y[ECC_POINT_MAX_SIZE];
|
||||
/*!<
|
||||
The Y-coordinate of the ec point.
|
||||
*/
|
||||
uint16 u16Size;
|
||||
/*!<
|
||||
Point size in bytes (for each of the coordinates).
|
||||
*/
|
||||
uint16 u16PrivKeyID;
|
||||
/*!<
|
||||
ID for the corresponding private key.
|
||||
*/
|
||||
} tstrECPoint;
|
||||
|
||||
/*!
|
||||
@struct \
|
||||
tstrECDomainParam
|
||||
|
||||
@brief ECC Curve Domain Parameters
|
||||
|
||||
The structure defines the ECC domain parameters for curves defined over prime finite fields.
|
||||
*/
|
||||
typedef struct EcDomainParam {
|
||||
uint32 p[ECC_POINT_MAX_SIZE_WORDS];
|
||||
uint32 a[ECC_POINT_MAX_SIZE_WORDS];
|
||||
uint32 b[ECC_POINT_MAX_SIZE_WORDS];
|
||||
tstrECPoint G;
|
||||
} tstrECDomainParam;
|
||||
|
||||
/*!
|
||||
@struct \
|
||||
tstrEllipticCurve
|
||||
|
||||
@brief
|
||||
Definition of an elliptic curve
|
||||
*/
|
||||
typedef struct {
|
||||
tenuEcNamedCurve enuType;
|
||||
tstrECDomainParam strParam;
|
||||
} tstrEllipticCurve;
|
||||
|
||||
typedef enum {
|
||||
ECC_REQ_NONE,
|
||||
ECC_REQ_CLIENT_ECDH,
|
||||
ECC_REQ_SERVER_ECDH,
|
||||
ECC_REQ_GEN_KEY,
|
||||
ECC_REQ_SIGN_GEN,
|
||||
ECC_REQ_SIGN_VERIFY
|
||||
} tenuEccREQ;
|
||||
|
||||
typedef struct {
|
||||
tstrECPoint strPubKey;
|
||||
uint8 au8Key[ECC_POINT_MAX_SIZE];
|
||||
} tstrEcdhReqInfo;
|
||||
|
||||
typedef struct {
|
||||
uint32 u32nSig;
|
||||
} tstrEcdsaVerifyReqInfo;
|
||||
|
||||
typedef struct {
|
||||
uint16 u16CurveType;
|
||||
uint16 u16HashSz;
|
||||
} tstrEcdsaSignReqInfo;
|
||||
|
||||
typedef struct {
|
||||
uint16 u16REQ;
|
||||
uint16 u16Status;
|
||||
uint32 u32UserData;
|
||||
uint32 u32SeqNo;
|
||||
union {
|
||||
tstrEcdhReqInfo strEcdhREQ;
|
||||
tstrEcdsaSignReqInfo strEcdsaSignREQ;
|
||||
tstrEcdsaVerifyReqInfo strEcdsaVerifyREQ;
|
||||
};
|
||||
} tstrEccReqInfo;
|
||||
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
GLOBALS
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
|
||||
#if 0
|
||||
static tstrEllipticCurve gastrECCSuppList[] = {
|
||||
{
|
||||
EC_SECP256R1,
|
||||
{
|
||||
{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
|
||||
{0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
|
||||
{0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0, 0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8},
|
||||
{
|
||||
{
|
||||
0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2,
|
||||
0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96
|
||||
},
|
||||
{
|
||||
0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16,
|
||||
0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5
|
||||
},
|
||||
32
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!<
|
||||
List of supported Elliptic Curves ordered by security level (most secure curve is at index ZERO).
|
||||
*/
|
||||
|
||||
#endif /* __ECC_TYPES_H__ */
|
||||
750
ChaletLora.X/Source/winc1500/driver/include/m2m_ate_mode.h
Normal file
750
ChaletLora.X/Source/winc1500/driver/include/m2m_ate_mode.h
Normal file
@ -0,0 +1,750 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief WINC ATE Test Driver Interface.
|
||||
*
|
||||
* Copyright (c) 2015 - 2017 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef _M2M_ATE_FW_
|
||||
|
||||
#ifndef _M2M_ATE_MODE_H_
|
||||
#define _M2M_ATE_MODE_H_
|
||||
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
INCLUDES
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
#include "common/include/nm_common.h"
|
||||
#include "driver/include/m2m_types.h"
|
||||
|
||||
/** \defgroup m2m_ate ATE
|
||||
*/
|
||||
/**@defgroup ATEDefine Defines
|
||||
* @ingroup m2m_ate
|
||||
* @{
|
||||
*/
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
MACROS
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
#define M2M_ATE_MAX_NUM_OF_RATES (20)
|
||||
/*!<
|
||||
Maximum number of all rates (b,g and n)
|
||||
*/
|
||||
#define M2M_ATE_MAX_FRAME_LENGTH (1024)
|
||||
/*!< Maximum number of length for each frame
|
||||
*/
|
||||
#define M2M_ATE_MIN_FRAME_LENGTH (1)
|
||||
/*!< Minimum number of length for each frame
|
||||
*/
|
||||
#define M2M_ATE_SUCCESS (M2M_SUCCESS)
|
||||
/*!< No Error and operation completed successfully.
|
||||
*/
|
||||
#define M2M_ATE_ERR_VALIDATE (M2M_ERR_FAIL)
|
||||
/*!< Error in parameters passed to functions.
|
||||
*/
|
||||
#define M2M_ATE_ERR_TX_ALREADY_RUNNING (-1)
|
||||
/*!< Error in starting a transmission test. Another test is already running and its not allowed to start another ATE
|
||||
* test.
|
||||
*/
|
||||
#define M2M_ATE_ERR_RX_ALREADY_RUNNING (-2)
|
||||
/*!< Error in starting a reception test. Another test is already running and its not allowed to start another ATE test.
|
||||
*/
|
||||
#define M2M_ATE_ERR_UNHANDLED_CASE (-3)
|
||||
/*!< Invalid case.
|
||||
*/
|
||||
#define M2M_ATE_RX_DISABLE_DA 0x0
|
||||
/*!< Filter selection for received frames: Disable filtering received frames by the destination address.
|
||||
*/
|
||||
#define M2M_ATE_RX_ENABLE_DA 0x1
|
||||
/*!< Filter selection for received frames: Enable filtering received frames by the destination address.
|
||||
*/
|
||||
#define M2M_ATE_RX_DISABLE_SA 0x0
|
||||
/*!< Filter selection for received frames: Disable filtering received frames by the source address.
|
||||
*/
|
||||
#define M2M_ATE_RX_ENABLE_SA 0x1
|
||||
/*!< Filter selection for received frames: Enable filtering received frames by the source address.
|
||||
*/
|
||||
#define M2M_ATE_DISABLE_SELF_MACADDR 0x0
|
||||
/*!<Disable setting a new mac address through the ATE test application and use the pre-set mac address in the firmware.
|
||||
*/
|
||||
#define M2M_ATE_SET_SELF_MACADDR 0x1
|
||||
/*!<Enable setting a new mac address through the ATE test application and use the pre-set mac address.
|
||||
*/
|
||||
#define M2M_ATE_TX_DUTY_MAX_VALUE M2M_ATE_TX_DUTY_1
|
||||
/*!< The maximum value of duty cycle
|
||||
*/
|
||||
#define M2M_ATE_TX_DUTY_MIN_VALUE M2M_ATE_TX_DUTY_10
|
||||
/*!< The minimum value of duty cycle
|
||||
*/
|
||||
//@}
|
||||
/**@defgroup ATEDataTypes DataTypes
|
||||
* @ingroup m2m_ate
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
DATA TYPES
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
/*!
|
||||
*@enum tenuM2mAteFwState
|
||||
*@brief Enumeration used to change ATE firmware states
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_FW_STATE_STOP = 0x00,
|
||||
/*!< State to stop ATE firmware
|
||||
*/
|
||||
M2M_ATE_FW_STATE_RUN = 0x01,
|
||||
/*!< State to run ATE firmware
|
||||
*/
|
||||
} tenuM2mAteFwState;
|
||||
|
||||
/*!
|
||||
*@enum tenuM2mAteTxRates
|
||||
*@brief Enumeration used to index the TX rates that can be used during the transmission test.
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_TX_RATE_1_Mbps_INDEX = 0x00,
|
||||
M2M_ATE_TX_RATE_2_Mbps_INDEX = 0x01,
|
||||
M2M_ATE_TX_RATE_55_Mbps_INDEX = 0x02,
|
||||
M2M_ATE_TX_RATE_11_Mbps_INDEX = 0x03,
|
||||
/*!< B-Rates
|
||||
*/
|
||||
M2M_ATE_TX_RATE_6_Mbps_INDEX = 0x04,
|
||||
M2M_ATE_TX_RATE_9_Mbps_INDEX = 0x05,
|
||||
M2M_ATE_TX_RATE_12_Mbps_INDEX = 0x06,
|
||||
M2M_ATE_TX_RATE_18_Mbps_INDEX = 0x07,
|
||||
M2M_ATE_TX_RATE_24_Mbps_INDEX = 0x08,
|
||||
M2M_ATE_TX_RATE_36_Mbps_INDEX = 0x09,
|
||||
M2M_ATE_TX_RATE_48_Mbps_INDEX = 0x0A,
|
||||
M2M_ATE_TX_RATE_54_Mbps_INDEX = 0x0B,
|
||||
/*!< G-Rates
|
||||
*/
|
||||
M2M_ATE_TX_RATE_MCS_0_INDEX = 0x0C,
|
||||
M2M_ATE_TX_RATE_MCS_1_INDEX = 0x0D,
|
||||
M2M_ATE_TX_RATE_MCS_2_INDEX = 0x0E,
|
||||
M2M_ATE_TX_RATE_MCS_3_INDEX = 0x0F,
|
||||
M2M_ATE_TX_RATE_MCS_4_INDEX = 0x10,
|
||||
M2M_ATE_TX_RATE_MCS_5_INDEX = 0x11,
|
||||
M2M_ATE_TX_RATE_MCS_6_INDEX = 0x12,
|
||||
M2M_ATE_TX_RATE_MCS_7_INDEX = 0x13,
|
||||
/*!< N-Rates
|
||||
*/
|
||||
} tenuM2mAteTxIndexOfRates;
|
||||
|
||||
/*!
|
||||
*@enum tenuM2mAteTxDutyCycle
|
||||
*@brief Enumeration used to index the TX duty cycle that can be used during the transmission test.
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_TX_DUTY_1 = 0x01,
|
||||
M2M_ATE_TX_DUTY_2 = 0x02,
|
||||
M2M_ATE_TX_DUTY_3 = 0x03,
|
||||
M2M_ATE_TX_DUTY_4 = 0x04,
|
||||
M2M_ATE_TX_DUTY_5 = 0x05,
|
||||
M2M_ATE_TX_DUTY_6 = 0x06,
|
||||
M2M_ATE_TX_DUTY_7 = 0x07,
|
||||
M2M_ATE_TX_DUTY_8 = 0x08,
|
||||
M2M_ATE_TX_DUTY_9 = 0x09,
|
||||
M2M_ATE_TX_DUTY_10 = 0xA0,
|
||||
} tenuM2mAteTxDutyCycle;
|
||||
|
||||
/*!
|
||||
*@enum tenuM2mAteTxDpdControl
|
||||
*@brief Enumeration for the allowed Digital-pre distortion(DPD) control values.
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_TX_DPD_DYNAMIC = 0x00,
|
||||
/*!< Dynamic mode indicates that DPD values will be set dynamically from a lookup table pre-set with the DPD
|
||||
* coefficents.
|
||||
*/
|
||||
M2M_ATE_TX_DPD_BYPASS = 0x01,
|
||||
/*!< Bypass mode indicates that the DPD control will be bypassed.
|
||||
*/
|
||||
M2M_ATE_TX_DPD_ENABLED = 0x02,
|
||||
/*!< Enabled mode allows the tester to manually set the DPD coefficients.
|
||||
*/
|
||||
} tenuM2mAteTxDpdControl;
|
||||
|
||||
/*!
|
||||
*@enum tenuM2mAteTxGainSetting
|
||||
*@brief Enumeration for the allowed TX gain selection modes.
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_TX_GAIN_DYNAMIC = 0x00,
|
||||
/*!< Dynamic mode indicates that Tx gain values for the digital gain,pa and ppa, will be set dynamically from a
|
||||
* lookup table based on the Tx_rate configured.
|
||||
*/
|
||||
M2M_ATE_TX_GAIN_BYPASS = 0x01,
|
||||
/*!< Bypass mode indicates that Tx gain configurations will be bypassed.
|
||||
*/
|
||||
M2M_ATE_TX_GAIN_FCC = 0x02,
|
||||
/*!< Using the FCC tx gain configuration indicates that the tx gain values will be used from the FCC flashed
|
||||
* table(pre-configured values from a customer).
|
||||
*/
|
||||
M2M_ATE_TX_GAIN_TELEC = 0x03,
|
||||
/*!< Using the TELEC tx gain configuration indicates that the tx gain values will be used from the TELEC flashed
|
||||
* table(pre-configured values from a customer).
|
||||
*/
|
||||
} tenuM2mAteTxGainSetting;
|
||||
|
||||
/*!
|
||||
*@enum tenuM2mAtePMUSetting
|
||||
*@brief Used to Enable PMU or disable it
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_PMU_DISBLE = 0x00,
|
||||
/*!< Disable using PMU mode
|
||||
*/
|
||||
M2M_ATE_PMU_ENABLE = 0x01,
|
||||
/*!< Enable using PMU mode
|
||||
*/
|
||||
} tenuM2mAtePMUSetting;
|
||||
|
||||
/*!
|
||||
*@enum tenuM2mAteTxSource
|
||||
*@brief Used to define the Tx source, either PHY mode or MAC mode.
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_TX_SRC_MAC = 0x00,
|
||||
/*!< When the TX Source is set to MAC, it indicates that the TX frames are manually framed and sent from the MAC
|
||||
* layer
|
||||
*/
|
||||
M2M_ATE_TX_SRC_PHY = 0x01,
|
||||
/*!< When the TX source is set to PHY, it indicates that transmission sequence occurs from PHY layer in the form of
|
||||
* pulses
|
||||
*/
|
||||
} tenuM2mAteTxSource;
|
||||
|
||||
/*!
|
||||
*@enum tenuM2mAteTxMode
|
||||
*@brief Used to define the mode of PHY TX transmission source: Continuous Wave(CW) or Normal(i.e CW is disabled) TX
|
||||
*sequence
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_TX_MODE_NORM = 0x00,
|
||||
/*!< When the TX source is set to PHY,normal mode indicates that continous transmission is disabled.
|
||||
*/
|
||||
M2M_ATE_TX_MODE_CW = 0x01,
|
||||
/*!< When the TX source is set to PHY, continous mode indicates that transmission sequences occur back to back in a
|
||||
* continous wave from the PHY layer.
|
||||
*/
|
||||
} tenuM2mAteTxMode;
|
||||
|
||||
/*!
|
||||
*@enum tenuM2mAteRxPwrMode
|
||||
*@brief Used to define type of RX mode either high power or low power
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_RX_PWR_HIGH = 0x00,
|
||||
/*!< Indicates that receive mode is operating at high power
|
||||
*/
|
||||
M2M_ATE_RX_PWR_LOW = 0x01,
|
||||
/*!< Indicates that receive mode is operating at low power
|
||||
*/
|
||||
} tenuM2mAteRxPwrMode;
|
||||
|
||||
/*!
|
||||
*@enum tenuM2mAteChannels
|
||||
*@brief Available channels for TX and RX in the 2.4GHz spectrum starting at 2412MHz with a 5MHz bandwidth.
|
||||
*/
|
||||
typedef enum {
|
||||
M2M_ATE_CHANNEL_1 = 0x01,
|
||||
/*!< Channel 1: 2412MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_2 = 0x02,
|
||||
/*!< Channel 2: 2417MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_3 = 0x03,
|
||||
/*!< Channel 3: 2422MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_4 = 0x04,
|
||||
/*!< Channel 4: 2427MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_5 = 0x05,
|
||||
/*!< Channel 5: 2432MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_6 = 0x06,
|
||||
/*!< Channel 6: 2437MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_7 = 0x07,
|
||||
/*!< Channel 7: 2442MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_8 = 0x08,
|
||||
/*!< Channel 8: 2447MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_9 = 0x09,
|
||||
/*!< Channel 9: 2452MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_10 = 0x0A,
|
||||
/*!< Channel 10: 2462MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_11 = 0x0B,
|
||||
/*!< Channel 11: 2467MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_12 = 0x0C,
|
||||
/*!< Channel 12: 2472MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_13 = 0x0D,
|
||||
/*!< Channel 13: 2472MHz
|
||||
*/
|
||||
M2M_ATE_CHANNEL_14 = 0x0E,
|
||||
/*!< Channel 14: 2484MHz
|
||||
*/
|
||||
} tenuM2mAteChannels;
|
||||
|
||||
/*!
|
||||
*@struct tstrM2mAteRxStatus
|
||||
*@brief Used to save statistics for receive(RX) test case
|
||||
*/
|
||||
typedef struct {
|
||||
uint32 num_rx_pkts;
|
||||
/*!< Number of total RX packets
|
||||
*/
|
||||
uint32 num_err_pkts;
|
||||
/*!< Number of RX failed packets
|
||||
*/
|
||||
uint32 num_good_pkts;
|
||||
/*!< Number of RX packets actually received
|
||||
*/
|
||||
} tstrM2mAteRxStatus;
|
||||
|
||||
/*!
|
||||
*@struct tstrM2mAteRxStatus
|
||||
*@brief Used to save recieve test case configuration
|
||||
*@see tenuM2mAteRxPwrMode
|
||||
*/
|
||||
typedef struct {
|
||||
uint8 u8RxPwrMode;
|
||||
/*!< RX power mode review \ref tenuM2mAteRxPwrMode
|
||||
*/
|
||||
} tstrM2mAteInit;
|
||||
|
||||
/*!
|
||||
*@struct tstrM2mAteTx
|
||||
*@brief Used for the transmission(Tx) test configuration.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32 num_frames;
|
||||
/*!< Number of frames to be sent where maximum number allowed is 4294967295 ul, and ZERO means infinite number of
|
||||
* frames
|
||||
*/
|
||||
uint32 data_rate;
|
||||
/*!< Rate to send packets, to select a rate use values from the enumeration \ref tenuM2mAteTxIndexOfRates and pass
|
||||
* it to \ref m2m_ate_get_tx_rate
|
||||
*/
|
||||
uint8 channel_num;
|
||||
/*!< Channel number as enumerated at \ref tenuM2mAteChannels
|
||||
*/
|
||||
uint8 duty_cycle;
|
||||
/*!< Duty cycle value between from 1 to 10, where maximum = 1, minimum = 10. As enumerated \ref
|
||||
* tenuM2mAteTxDutyCycle
|
||||
*/
|
||||
uint16 frame_len;
|
||||
/*!< Use @ref M2M_ATE_MAX_FRAME_LENGTH (1024) as the maximum value while @ref M2M_ATE_MIN_FRAME_LENGTH (1) is the
|
||||
* minimum value
|
||||
*/
|
||||
uint8 tx_gain_sel;
|
||||
/*!< TX gain mode selection value \ref tenuM2mAteTxGainSetting
|
||||
*/
|
||||
uint8 dpd_ctrl;
|
||||
/*!< DPD mode value\ref tenuM2mAteTxDpdControl
|
||||
*/
|
||||
uint8 use_pmu;
|
||||
/*!< This is 0 if PMU is not used otherwise it must be be 1 \ref tenuM2mAtePMUSetting
|
||||
*/
|
||||
uint8 phy_burst_tx;
|
||||
/*!< Source of Burst TX either PHY or MAC \ref tenuM2mAteTxSource
|
||||
*/
|
||||
uint8 cw_tx;
|
||||
/*!< Mode of Phy TX transmission either normal TX sequence or CW(Continuous Wave) TX sequence \ref tenuM2mAteTxMode
|
||||
*/
|
||||
uint32 xo_offset_x1000;
|
||||
/*!< Signed XO offset value in Part Per Million(PPM) multiplied by 1000.
|
||||
*/
|
||||
uint8 use_efuse_xo_offset;
|
||||
/*!< Set to 0 to use the XO offset provided in xo_offset_x1000. Set to 1 to use XO offset programmed on WINC efuse.
|
||||
*/
|
||||
uint8 peer_mac_addr[6];
|
||||
/*!< Set peer address to send directed frames to a certain address.
|
||||
*/
|
||||
} tstrM2mAteTx;
|
||||
|
||||
/*!
|
||||
*@struct tstrM2mAteRx
|
||||
*@brief Used for the reception(Rx) test configuration.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8 channel_num;
|
||||
/*!< Channel number \ref tenuM2mAteChannels
|
||||
*/
|
||||
uint8 use_pmu;
|
||||
/*!< This is 0 if PMU is not used otherwise it must be be 1 \ref tenuM2mAtePMUSetting
|
||||
*/
|
||||
uint32 xo_offset_x1000;
|
||||
/*!< Signed XO offset value in PPM (Part Per Million) multiplied by 1000.
|
||||
*/
|
||||
uint8 use_efuse_xo_offset;
|
||||
/*!< Set to 0 to use the XO offset provided in xo_offset_x1000. Set to 1 to use XO offset programmed on WINC efuse.
|
||||
*/
|
||||
uint8 self_mac_addr[6];
|
||||
/*!< Set to the self mac address required to be overriden.
|
||||
*/
|
||||
uint8 peer_mac_addr[6];
|
||||
/*!< Set to the source mac address expected to filter frames from.
|
||||
*/
|
||||
uint8 mac_filter_en_da;
|
||||
/*!< Flag set to enable or disable reception with destination address as a filter. Using the following flags \ref
|
||||
M2M_ATE_RX_ENABLE_DA \ref M2M_ATE_RX_DISABLE_DA
|
||||
*/
|
||||
uint8 mac_filter_en_sa;
|
||||
/*!< Flag set to enable or disable reception with source address as a filter.Using the following flags \ref
|
||||
M2M_ATE_RX_ENABLE_SA \ref M2M_ATE_RX_DISABLE_SA
|
||||
*/
|
||||
uint8 override_self_mac_addr;
|
||||
/*!< Flag set to enable or disable self mac address feature. Using the following flags \ref
|
||||
M2M_ATE_DISABLE_SELF_MACADDR \ref M2M_ATE_SET_SELF_MACADDR
|
||||
*/
|
||||
} tstrM2mAteRx;
|
||||
//@}
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
FUNCTION PROTOTYPES
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/**@defgroup ATEFunction Function
|
||||
* @ingroup m2m_ate
|
||||
* @{
|
||||
*/
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_init(void);
|
||||
|
||||
@brief
|
||||
This function used to download the ATE firmware from flash and start it.
|
||||
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_init_param
|
||||
*/
|
||||
sint8 m2m_ate_init(void);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_init(tstrM2mAteInit *pstrInit);
|
||||
|
||||
@brief
|
||||
This function is used to download and start the ATE firmware with an initialization value
|
||||
stating the rx mode power \ref tstrM2mAteInit.
|
||||
@param [in] tstrM2mAteInit *
|
||||
Pointer to a structure \ref tstrM2mAteInit, defining the initial RX mode value.
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_init
|
||||
*/
|
||||
sint8 m2m_ate_init_param(tstrM2mAteInit *pstrInit);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_deinit(void);
|
||||
|
||||
@brief
|
||||
De-Initialization of ATE firmware mode
|
||||
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
*/
|
||||
sint8 m2m_ate_deinit(void);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_set_fw_state(uint8);
|
||||
|
||||
@brief
|
||||
This function is used to change the ATE firmware status from running to stopped or vice versa.
|
||||
|
||||
@param [in] u8State
|
||||
Required state of the ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_init
|
||||
*/
|
||||
sint8 m2m_ate_set_fw_state(uint8);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_get_fw_state(uint8);
|
||||
|
||||
@brief
|
||||
This function is used to return the status of ATE firmware.
|
||||
|
||||
@return
|
||||
The function SHALL return the status of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
|
||||
@see
|
||||
m2m_ate_init, m2m_ate_set_fw_state
|
||||
*/
|
||||
sint8 m2m_ate_get_fw_state(void);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
uint32 m2m_ate_get_tx_rate(uint8);
|
||||
|
||||
@brief
|
||||
This function is used to return value of TX rate required by application developer.
|
||||
|
||||
@param [in] u8Index
|
||||
Index of the required rate , one of \ref tenuM2mAteTxIndexOfRates enumeration values.
|
||||
@return
|
||||
The function SHALL return 0 in case of receiving invalid index, otherwise the selected rate value is returned.
|
||||
@see
|
||||
tenuM2mAteTxIndexOfRates
|
||||
*/
|
||||
uint32 m2m_ate_get_tx_rate(uint8);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_get_tx_status(void);
|
||||
|
||||
@brief
|
||||
This function is used to return the status of TX test case either running or stopped.
|
||||
|
||||
@return
|
||||
The function SHALL return the status of ATE firmware, 1 if TX test case is running or 0 if TX test case has been
|
||||
stopped.
|
||||
@see
|
||||
m2m_ate_start_tx, m2m_ate_stop_tx
|
||||
*/
|
||||
sint8 m2m_ate_get_tx_status(void);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_start_tx(tstrM2mAteTx *)
|
||||
|
||||
@brief
|
||||
This function is used to start the TX test case.
|
||||
|
||||
@param [in] strM2mAteTx
|
||||
Type of \ref tstrM2mAteTx, with the values required to enable TX test case. Application must use \ref
|
||||
m2m_ate_init first.
|
||||
@return
|
||||
The function SHALL return 0 for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_init, m2m_ate_stop_tx, m2m_ate_get_tx_status
|
||||
*/
|
||||
sint8 m2m_ate_start_tx(tstrM2mAteTx *);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_stop_tx(void)
|
||||
|
||||
@brief
|
||||
This function is used to stop the TX test case.
|
||||
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_init, m2m_ate_start_tx, m2m_ate_get_tx_status
|
||||
*/
|
||||
sint8 m2m_ate_stop_tx(void);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_get_rx_status(uint8);
|
||||
|
||||
@brief
|
||||
This function is used to return the status of RX test case either running or stopped.
|
||||
|
||||
@return
|
||||
The function SHALL return status of ATE firmware, 1 if RX test case is running or 0 when the test case has been
|
||||
stopped.
|
||||
@see
|
||||
m2m_ate_start_rx, m2m_ate_stop_rx
|
||||
*/
|
||||
sint8 m2m_ate_get_rx_status(void);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_start_rx(tstrM2mAteRx *)
|
||||
|
||||
@brief
|
||||
This function is used to start RX test case.
|
||||
|
||||
@param [in] strM2mAteRx
|
||||
Type of \ref tstrM2mAteRx, with the values required to enable RX test case. Application must use \ref
|
||||
m2m_ate_init first.
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_init, m2m_ate_stop_rx, m2m_ate_get_rx_status
|
||||
*/
|
||||
sint8 m2m_ate_start_rx(tstrM2mAteRx *);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_stop_rx(void)
|
||||
|
||||
@brief
|
||||
This function is used to stop RX test case.
|
||||
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_init, m2m_ate_start_rx, m2m_ate_get_rx_status
|
||||
*/
|
||||
sint8 m2m_ate_stop_rx(void);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *)
|
||||
|
||||
@brief
|
||||
This function is used to read RX statistics from the ATE firmware.
|
||||
|
||||
@param [out] strM2mAteRxStatus
|
||||
Type of \ref tstrM2mAteRxStatus used to save statistics of RX test case. Application must use \ref
|
||||
m2m_ate_start_rx first.
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_init, m2m_ate_start_rx
|
||||
*/
|
||||
sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_set_dig_gain(double dGaindB)
|
||||
|
||||
@brief
|
||||
This function is used to set the digital gain value to the HW registers in dB.
|
||||
|
||||
@param [in] double dGaindB
|
||||
The digital gain value required to be set.
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_get_dig_gain, m2m_ate_get_pa_gain,m2m_ate_get_ppa_gain,m2m_ate_get_tot_gain
|
||||
*/
|
||||
sint8 m2m_ate_set_dig_gain(double dGaindB);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_get_dig_gain(double * dGaindB)
|
||||
|
||||
@brief
|
||||
This function is used to retrieve the digital gain value from the HW registers in dB.
|
||||
Digital gain is one of the values that are set to calculate the total tx gain value.
|
||||
|
||||
@param [out] double * dGaindB
|
||||
The retrieved digital gain value obtained from HW registers in dB.
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_set_dig_gain, m2m_ate_get_pa_gain,m2m_ate_get_ppa_gain,m2m_ate_get_tot_gain
|
||||
*/
|
||||
sint8 m2m_ate_get_dig_gain(double *dGaindB);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
void m2m_ate_set_pa_gain(uint8 gain_db)
|
||||
|
||||
@brief
|
||||
This function is used to set the PA gain (18/15/12/9/6/3/0 only)
|
||||
|
||||
@param [in] uint8 gain_db
|
||||
PA gain level allowed (18/15/12/9/6/3/0 only)
|
||||
|
||||
*/
|
||||
void m2m_ate_set_pa_gain(uint8 gain_db);
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_get_pa_gain(double *paGaindB)
|
||||
|
||||
@brief
|
||||
This function is used to get the Power Amplifier(PA) gain
|
||||
|
||||
@param [out] double *paGaindB
|
||||
The retrieved PA gain value obtained from HW registers in dB.
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_set_dig_gain, m2m_ate_get_dig_gain,m2m_ate_get_ppa_gain,m2m_ate_get_tot_gain
|
||||
*/
|
||||
sint8 m2m_ate_get_pa_gain(double *paGaindB);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_get_ppa_gain(double * ppaGaindB)
|
||||
|
||||
@brief
|
||||
This function is used to get the Pre-Power Amplifier(PPA) gain
|
||||
|
||||
@param [out] uint32 * ppaGaindB
|
||||
The retrieved PPA gain value obtained from HW registers in dB.
|
||||
@return
|
||||
The function SHALL return 0 for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_set_dig_gain, m2m_ate_get_dig_gain,m2m_ate_get_pa_gain,m2m_ate_get_tot_gain
|
||||
*/
|
||||
sint8 m2m_ate_get_ppa_gain(double *ppaGaindB);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_ate_get_tot_gain(double * totGaindB)
|
||||
|
||||
@brief
|
||||
This function is used to calculate the total tx gain value
|
||||
|
||||
@param [out] double * totGaindB
|
||||
The retrieved total gain value obtained from calculations made based on the digital gain, PA and PPA gain
|
||||
values.
|
||||
@return
|
||||
The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
|
||||
@see
|
||||
m2m_ate_set_dig_gain, m2m_ate_get_dig_gain,m2m_ate_get_pa_gain,m2m_ate_get_ppa_gain
|
||||
*/
|
||||
sint8 m2m_ate_get_tot_gain(double *totGaindB);
|
||||
//@}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _M2M_CONFIG_MODE_H_ */
|
||||
|
||||
#endif //_M2M_ATE_FW_
|
||||
259
ChaletLora.X/Source/winc1500/driver/include/m2m_crypto.h
Normal file
259
ChaletLora.X/Source/winc1500/driver/include/m2m_crypto.h
Normal file
@ -0,0 +1,259 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief WINC Crypto Application Interface.
|
||||
*
|
||||
* Copyright (c) 2015 - 2017 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 __M2M_CRYPTO_H__
|
||||
#define __M2M_CRYPTO_H__
|
||||
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
INCLUDES
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
|
||||
#include "common/include/nm_common.h"
|
||||
#include "driver/include/m2m_types.h"
|
||||
#include "driver/source/m2m_hif.h"
|
||||
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
MACROS
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
#define M2M_MAX_RSA_LEN (256)
|
||||
#define M2M_SHA256_DIGEST_LEN 32
|
||||
#define M2M_SHA256_MAX_DATA (M2M_BUFFER_MAX_SIZE - M2M_SHA256_CONTEXT_BUFF_LEN - M2M_HIF_HDR_OFFSET)
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
DATA TYPES
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
|
||||
/*!
|
||||
@struct \
|
||||
tstrM2mSha256Ctxt
|
||||
|
||||
@brief
|
||||
SHA256 context data
|
||||
*/
|
||||
typedef struct sha256ctxt {
|
||||
uint32 au32Sha256CtxtBuff[M2M_SHA256_CONTEXT_BUFF_LEN / sizeof(uint32)];
|
||||
} tstrM2mSha256Ctxt;
|
||||
|
||||
/*!
|
||||
@enum \
|
||||
tenuRsaSignStatus
|
||||
|
||||
@brief
|
||||
RSA Signature status: pass or fail.
|
||||
|
||||
@see
|
||||
m2m_crypto_rsa_sign_gen
|
||||
*/
|
||||
typedef enum { M2M_RSA_SIGN_OK, M2M_RSA_SIGN_FAIL } tenuRsaSignStatus;
|
||||
|
||||
/*!
|
||||
@typedef \
|
||||
tpfAppCryproCb
|
||||
|
||||
@brief Crypto Calback function receiving the crypto related messages
|
||||
@param [in] u8MsgType
|
||||
Crypto command about which the notification is received.
|
||||
@param [in] pvResp
|
||||
A pointer to the result associated with the notification.
|
||||
@param [in] pvMsg
|
||||
A pointer to a buffer containing the notification parameters (if any). It should be
|
||||
Casted to the correct data type corresponding to the notification type.
|
||||
@see
|
||||
m2m_crypto_init
|
||||
tenuM2mCryptoCmd
|
||||
*/
|
||||
typedef void (*tpfAppCryproCb)(uint8 u8MsgType, void *pvResp, void *pvMsg);
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
||||
FUNCTION PROTOTYPES
|
||||
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_crypto_init();
|
||||
|
||||
@brief crypto initialization.
|
||||
|
||||
@param[in] pfAppCryproCb
|
||||
Pointer to the Crypto Calback function receiving the crypto related messages.
|
||||
@see
|
||||
tpfAppCryproCb
|
||||
|
||||
@return
|
||||
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
|
||||
*/
|
||||
sint8 m2m_crypto_init(tpfAppCryproCb pfAppCryproCb);
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt);
|
||||
|
||||
@brief SHA256 hash initialization
|
||||
|
||||
@param[in] psha256Ctxt
|
||||
Pointer to a sha256 context allocated by the caller.
|
||||
@return
|
||||
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
|
||||
*/
|
||||
sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength);
|
||||
|
||||
@brief SHA256 hash update
|
||||
|
||||
@param [in] psha256Ctxt
|
||||
Pointer to the sha256 context.
|
||||
|
||||
@param [in] pu8Data
|
||||
Buffer holding the data submitted to the hash.
|
||||
|
||||
@param [in] u16DataLength
|
||||
Size of the data bufefr in bytes.
|
||||
@pre SHA256 module should be initialized first through m2m_crypto_sha256_hash_init function.
|
||||
|
||||
@see m2m_crypto_sha256_hash_init
|
||||
|
||||
@return
|
||||
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
|
||||
|
||||
*/
|
||||
sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest);
|
||||
|
||||
@brief SHA256 hash finalization
|
||||
|
||||
@param[in] psha256Ctxt
|
||||
Pointer to a sha256 context allocated by the caller.
|
||||
|
||||
@param [in] pu8Sha256Digest
|
||||
Buffer allocated by the caller which will hold the resultant SHA256 Digest. It must be allocated no less
|
||||
than M2M_SHA256_DIGEST_LEN.
|
||||
|
||||
@return
|
||||
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
|
||||
*/
|
||||
sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash, \
|
||||
uint16 u16HashLength, uint8 *pu8RsaSignature);
|
||||
|
||||
@brief RSA Signature Verification
|
||||
|
||||
The function shall request the RSA Signature verification from the WINC Firmware for the given message. The signed
|
||||
message shall be compressed to the corresponding hash algorithm before calling this function. The hash type is
|
||||
identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
|
||||
|
||||
@param[in] pu8N
|
||||
RSA Key modulus n.
|
||||
|
||||
@param[in] u16NSize
|
||||
Size of the RSA modulus n in bytes.
|
||||
|
||||
@param[in] pu8E
|
||||
RSA public exponent.
|
||||
|
||||
@param[in] u16ESize
|
||||
Size of the RSA public exponent in bytes.
|
||||
|
||||
@param[in] pu8SignedMsgHash
|
||||
The hash digest of the signed message.
|
||||
|
||||
@param[in] u16HashLength
|
||||
The length of the hash digest.
|
||||
|
||||
@param[out] pu8RsaSignature
|
||||
Signature value to be verified.
|
||||
|
||||
@return
|
||||
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
|
||||
*/
|
||||
sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
|
||||
uint16 u16HashLength, uint8 *pu8RsaSignature);
|
||||
|
||||
/*!
|
||||
@fn \
|
||||
sint8 m2m_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash, \
|
||||
uint16 u16HashLength, uint8 *pu8RsaSignature);
|
||||
|
||||
@brief RSA Signature Generation
|
||||
|
||||
The function shall request the RSA Signature generation from the WINC Firmware for the given message. The signed
|
||||
message shall be compressed to the corresponding hash algorithm before calling this function. The hash type is
|
||||
identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
|
||||
|
||||
@param[in] pu8N
|
||||
RSA Key modulus n.
|
||||
|
||||
@param[in] u16NSize
|
||||
Size of the RSA modulus n in bytes.
|
||||
|
||||
@param[in] pu8d
|
||||
RSA private exponent.
|
||||
|
||||
@param[in] u16dSize
|
||||
Size of the RSA private exponent in bytes.
|
||||
|
||||
@param[in] pu8SignedMsgHash
|
||||
The hash digest of the signed message.
|
||||
|
||||
@param[in] u16HashLength
|
||||
The length of the hash digest.
|
||||
|
||||
@param[out] pu8RsaSignature
|
||||
Pointer to a user buffer allocated by teh caller shall hold the generated signature.
|
||||
|
||||
@return
|
||||
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
|
||||
*/
|
||||
sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
|
||||
uint16 u16HashLength, uint8 *pu8RsaSignature);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __M2M_CRYPTO_H__ */
|
||||
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