Création GIT

This commit is contained in:
jfmartel 2020-11-16 05:47:46 -05:00
commit 06e51cffb5
146 changed files with 75351 additions and 0 deletions

113
Bootloader_PIC32.X/Makefile Normal file
View 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

View File

@ -0,0 +1,364 @@
/*******************************************************************************
* *
* 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. *
* *
*******************************************************************************/
/*---- example include file ---------------------------------------------------*/
#include "define.h"
#include "BootloaderProtocol.h"
#include "BootloaderStateMachine.h"
#include "internaluart.h"
//#include <string.h>
enum eBootloaderProtocolStates ProtocolState;
unsigned int RxCounter;
unsigned int WordBuf;
unsigned short DataSize;
unsigned int CurCmd;
char *DataBufPtr;
char Checksum;
int ByteCount;
int *RecordDataPtr;
Bool e_CommandPending;
Bool e_FlashUpdateMode;
//#pragma DATA_ALIGN ( RxDataBuffer,16);
//#pragma DATA_SECTION(RxDataBuffer,"bootloaderbuffer");
unsigned char RxDataBuffer[MAX_RX_BUFF_SIZE]; //Rx buffer
//#pragma DATA_SECTION(TxBuffer,"bootloaderbuffer");
char TxBuffer[MAX_TX_BUFF_SIZE]; //Tx buffer
stDataSector_t CurrentDataSector;
void ProtocolInit(void)
{
ProtocolResetSM();
e_CommandPending = false;
e_FlashUpdateMode = false;
ByteCount = 0;
}
void ProtocolRxData( char mData )
{
if(e_CommandPending == true)
{
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_COMMAND_PENDING);
return;
}
if(e_FlashUpdateMode == true)
{
// DownloadFlash(0x328000, 0x32FFFF);
e_FlashUpdateMode = false;
return;
}
switch(ProtocolState)
{
case PROTOCOL_RX_HEADER:
{
if((unsigned char)mData == PROTOCOL_HEADER)
ProtocolState = PROTOCOL_RX_CMD;
break;
}
case PROTOCOL_RX_CMD:
{
CurCmd = ((unsigned int)mData & 0x00FF);
ProtocolState = PROTOCOL_RX_DATA_SIZE_1;
break;
}
case PROTOCOL_RX_DATA_SIZE_1:
{
DataSize = ((unsigned int)mData & 0x00FF); //((mData << 8) & 0xFF00);
ProtocolState = PROTOCOL_RX_DATA_SIZE_2;
break;
}
case PROTOCOL_RX_DATA_SIZE_2:
{
DataSize |= ((mData << 8) & 0xFF00); //(mData & 0x00FF);
if(DataSize > MAX_SECTOR_SIZE*4) //4 bytes per word...
{
ProtocolResetSM();
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_DATA_OVERSIZE);
}
else
{
if(DataSize == 0)
ProtocolState = PROTOCOL_RX_CHECKSUM;
else
{
if(CurCmd == SEND_RECORD_REQUEST_CMD && ((DataSize-6) % 4 != 0))// data must be 32 bits word) aligned when receiving a data record.
{
ProtocolResetSM();
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_DATA_BYTES_MISALIGNED);
break;
}
else
ProtocolState = PROTOCOL_RX_DATA_BYTE4;
//ProtocolState = PROTOCOL_RX_DATA_BYTE1;
}
}
break;
}
/* case PROTOCOL_RX_DATA_BYTE1: //This compiler does not support 8 bits alignment
{
RxCounter++;
Checksum ^= mData;
if(CurCmd == SEND_RECORD_REQUEST_CMD) //for this command, we must concatenate 4 bytes in 1 word
{
WordBuf = (((unsigned int)mData << 24) & 0xFF000000);
if(RxCounter >= DataSize)
{
ProtocolResetSM();
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_DATA_BYTES_MISALIGNED);
}
else
ProtocolState = PROTOCOL_RX_DATA_BYTE2;
}
else
{
*DataBufPtr++ = mData; //Store new byte in buffer.
if(RxCounter >= DataSize) //all bytes received
{
ProtocolState = PROTOCOL_RX_CHECKSUM;
}
}
break;
}
case PROTOCOL_RX_DATA_BYTE2:
{
WordBuf |= (((unsigned int)mData << 16) & 0x00FF0000);
RxCounter++;
*DataBufPtr++ = WordBuf; //Store new word in buffer.
Checksum ^= mData;
if(RxCounter >= DataSize)
{
ProtocolResetSM();
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_DATA_BYTES_MISALIGNED);
}
else
ProtocolState = PROTOCOL_RX_DATA_BYTE3;
}
case PROTOCOL_RX_DATA_BYTE3:
{
WordBuf |= (((unsigned int)mData << 8) & 0x0000FF00);
RxCounter++;
*DataBufPtr++ = WordBuf; //Store new word in buffer.
Checksum ^= mData;
if(RxCounter >= DataSize)
{
ProtocolResetSM();
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_DATA_BYTES_MISALIGNED);
}
else
ProtocolState = PROTOCOL_RX_DATA_BYTE4;
}
case PROTOCOL_RX_DATA_BYTE4:
{
WordBuf |= ((unsigned int)mData & 0x000000FF);
RxCounter++;
*DataBufPtr++ = WordBuf; //Store new word in buffer.
Checksum ^= mData;
if(RxCounter >= DataSize)
{
ProtocolState = PROTOCOL_RX_CHECKSUM; //all data received
}
else
{
ProtocolState = PROTOCOL_RX_DATA_BYTE1; //get next word
}
break;
}*/
case PROTOCOL_RX_DATA_BYTE4:
{
Checksum ^= mData;
*DataBufPtr++ = mData;
if(CurCmd == SEND_RECORD_REQUEST_CMD) //for this command, we must concatenate 4 bytes in 1 word
{
if(RxCounter == 3) //Start address..
{
CurrentDataSector.SectorStartAddress = *(unsigned int*)(&RxDataBuffer[0]);
DataBufPtr = &RxDataBuffer[0];
}
if(RxCounter == 5) //Record Size..
{
CurrentDataSector.SectorSize = *(unsigned short*)(&RxDataBuffer[0]);
DataBufPtr = &RxDataBuffer[0];
}
if(RxCounter > 5)
{
if(ByteCount == 3)
{
ByteCount = 0;
*RecordDataPtr++ = *(unsigned int*)(&RxDataBuffer[0]);
DataBufPtr = &RxDataBuffer[0];
}
else
{
ByteCount++;
}
}
}
RxCounter++;
if(RxCounter >= DataSize)
{
ProtocolState = PROTOCOL_RX_CHECKSUM; //all data received
}
else
{
ProtocolState = PROTOCOL_RX_DATA_BYTE4; //get next word
}
break;
}
case PROTOCOL_RX_CHECKSUM:
{
if(mData == Checksum)
{
//execute command...
e_CommandPending = true;
// ProtocolExecCmd((enum eBootloaderProtocolCmds) CurCmd);
}
else
{
//Error, bad checksum...
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_BAD_CHECKSUM);
ProtocolResetSM();
}
break;
}
default:
{
ProtocolResetSM();
break;
}
}
}
void ProtocolExecCmd()
{
switch(CurCmd)
{
case CONNECT_REQUEST_CMD: //Sent by the PTE in answer to BOOTLOADER_READY_CMD to enter boot mode
case BOOTLOADER_UNLOCK_REQUEST_CMD:
case HEARTBEAT_REQUEST_CMD:
case START_UPDATE_REQUEST_CMD:
case SEND_RECORD_REQUEST_CMD:
case END_UPDATE_REQUEST_CMD:
case FLASH_API_VER_REQUEST_CMD:
case SCRUB_FLASH_REQUEST_CMD:
{
BootloaderSM(SM_RX_CMD_EVENT,CurCmd);
break;
}
case FIRMWARE_RESET_REQUEST:
{
SoftReset();
break;
}
case DOWNLOAD_FLASH_REQUEST_CMD:
{
e_FlashUpdateMode = true;
break;
}
default:
{
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_UNKNOWN_COMMAND);
break;
}
}
ProtocolResetSM();
}
void ProtocolResetSM()
{
ProtocolState = PROTOCOL_RX_HEADER;
WordBuf = 0;
RxCounter = 0;
DataSize = 0;
CurCmd = 0;
DataBufPtr = &RxDataBuffer[0];
Checksum = 0;
RecordDataPtr = &CurrentDataSector.SectorData[0];
}
unsigned int ProtocolSendCmd(enum eBootloaderProtocolCmds mCmd, char *mData, unsigned mDataSize)
{
int i;
char mChecksum = 0;
if(mDataSize + 5 > MAX_TX_BUFF_SIZE)
return 0;
TxBuffer[0] = PROTOCOL_HEADER;
TxBuffer[1] = (char)mCmd;
TxBuffer[2] = LSB8(mDataSize);
TxBuffer[3] = MSB8(mDataSize);
for(i = 0; i < mDataSize; i++)
{
mChecksum ^= *mData;
TxBuffer[i+4] = *mData++;
}
TxBuffer[mDataSize + 4] = mChecksum;
SendInternalUartData(TxBuffer,mDataSize+5);
return mDataSize + 5;
}
void ProtocolSendAck(enum eBootloaderAcknowledgement mAck, enum eBootloaderProtocolRet mErr)
{
char mAckBufferData[2];
mAckBufferData[0] = (char) mAck;
mAckBufferData[1] = (char) mErr;
ProtocolSendCmd(ACKNOWLEDGE_CMD, mAckBufferData, 2);
}

View File

@ -0,0 +1,96 @@
#ifndef BOOTLOADER_PROTOCOL_H
#define BOOTLOADER_PROTOCOL_H
#define PROTOCOL_HEADER 0xBA
#define MAX_SECTOR_SIZE 0x01000
#define MAX_RX_BUFF_SIZE 0x100
#define MAX_TX_BUFF_SIZE 0x100
typedef struct
{
unsigned int SectorStartAddress;
unsigned short SectorSize;
unsigned int SectorData[MAX_SECTOR_SIZE];
}stDataSector_t;
enum eBootloaderProtocolStates
{
PROTOCOL_RX_HEADER,
PROTOCOL_RX_CMD,
PROTOCOL_RX_DATA_SIZE_1,
PROTOCOL_RX_DATA_SIZE_2,
PROTOCOL_RX_DATA_BYTE1,
PROTOCOL_RX_DATA_BYTE2,
PROTOCOL_RX_DATA_BYTE3,
PROTOCOL_RX_DATA_BYTE4,
PROTOCOL_RX_CHECKSUM
};
enum eBootloaderProtocolCmds
{
ACKNOWLEDGE_CMD,
BOOTLOADER_READY_CMD, //Sent by the bootoloader at boot. If no answer... jump in app, else stay in update mode
CONNECT_REQUEST_CMD, //Sent by the PTE in answer to BOOTLOADER_READY_CMD to enter boot mode
BOOTLOADER_UNLOCK_REQUEST_CMD,
HEARTBEAT_CMD,
HEARTBEAT_REQUEST_CMD,
START_UPDATE_REQUEST_CMD,
SEND_RECORD_REQUEST_CMD,
END_UPDATE_REQUEST_CMD,
FLASH_API_VER_CMD,
FLASH_API_VER_REQUEST_CMD,
SCRUB_FLASH_REQUEST_CMD,
DOWNLOAD_FLASH_REQUEST_CMD,
FLASH_DATA_CMD,
FIRMWARE_RESET_REQUEST = 0xFA
};
enum eBootloaderProtocolRet
{
RET_PROTOCOL_OK,
RET_PROTOCOL_READY,
RET_PROTOCOL_FLASH_ERASE,
RET_PROTOCOL_FLASH_WRITE,
RET_PROTOCOL_ERR_BAD_CHECKSUM,
RET_PROTOCOL_ERR_DATA_OVERSIZE,
RET_PROTOCOL_ERR_DATA_BYTES_MISALIGNED,
RET_PROTOCOL_ERR_UNKNOWN_COMMAND,
RET_PROTOCOL_ERR_COMMAND_PENDING,
RET_PROTOCOL_ERR_ILLEGAL_ADDRESS,
RET_PROTOCOL_ERR_INVALID_UNLOCK_CODE,
RET_PROTOCOL_ERR_UNLOCK_EXPECTED,
RET_PROTOCOL_ERR_ERASE_FLASH_FAILED,
RET_PROTOCOL_ERR_WRITE_FLASH_FAILED,
RET_PROTOCOL_ERR_INVALID_ADDRESS
};
enum eBootloaderAcknowledgement
{
PROTOCOL_NACK,
PROTOCOL_ACK
};
extern Bool e_CommandPending;
extern Bool e_FlashUpdateMode;
extern unsigned char RxDataBuffer[MAX_RX_BUFF_SIZE];
extern stDataSector_t CurrentDataSector;
void ProtocolInit(void);
void ProtocolRxData( char data );
void ProtocolResetSM(void);
void ProtocolExecCmd();
unsigned int ProtocolSendCmd(enum eBootloaderProtocolCmds Cmd, char *Data, unsigned int DataSize);
void ProtocolSendAck(enum eBootloaderAcknowledgement Ack, enum eBootloaderProtocolRet err);
#endif
//===========================================================================
// End of file.
//===========================================================================

View File

@ -0,0 +1,327 @@
/*******************************************************************************
* *
* 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. *
* *
*******************************************************************************/
/*---- example include file ---------------------------------------------------*/
#include "define.h"
#include "BootloaderStateMachine.h"
#include "FlashInterface.h"
#include "BootloaderProtocol.h"
#include "InternalUart.h"
#include <plib.h>
//#include <string.h>
//#include <stdio.h>
unsigned int mSMState;
unsigned int mPseudoTimer;
extern unsigned long _app_start;
void BootloaderSMInit(void)
{
mSMState = SM_UPDATE_WAIT_STATE;
mPseudoTimer = 0;
}
#pragma CODE_SECTION(BootloaderSM,"ramfuncs");
void BootloaderSM(unsigned int event, unsigned int Data)
{
switch(mSMState)
{
case SM_UPDATE_WAIT_STATE:
{
switch(event)
{
case SM_TICK_EVENT:
{
if(mPseudoTimer++ >= PSEUDO_TIMER_VALUE)
{
char mbuf[30];
mbuf[0] = 'R';
mbuf[1] = 'e';
mbuf[2] = 'b';
mbuf[3] = 'o';
mbuf[4] = 'o';
mbuf[5] = 't';
mbuf[6] = 'i';
mbuf[7] = 'n';
mbuf[8] = 'g';
mbuf[9] = ' ';
mbuf[10] = 'i';
mbuf[11] = 'n';
mbuf[12] = ' ';
mbuf[13] = 'a';
mbuf[14] = 'p';
mbuf[15] = 'p';
mbuf[16] = '\r';
SendInternalUartData(&mbuf[0],17);
mPseudoTimer = 0;
// #ifndef _DEBUG
JumpToApp();
// #endif
}
break;
}
case SM_RX_CMD_EVENT:
{
if(Data == CONNECT_REQUEST_CMD)
{
mSMState = SM_IDLE_STATE;
ProtocolSendAck(PROTOCOL_ACK,RET_PROTOCOL_OK); //Bootloader ack
}
//Ignore any other command received...
break;
}
case SM_ABORT_UPDATE:
{
break;
}
}
break; //case SM_UPDATE_WAIT_STATE:
}
case SM_IDLE_STATE:
{
switch(event)
{
case SM_TICK_EVENT:
{
break;
}
case SM_RX_CMD_EVENT:
{
switch(Data)
{
case START_UPDATE_REQUEST_CMD:
{
mSMState = SM_WAIT_FOR_UNLOCK_STATE;
ProtocolSendAck(PROTOCOL_ACK,RET_PROTOCOL_OK); //Bootloader ack
break;
}
case HEARTBEAT_REQUEST_CMD:
{
ProtocolSendCmd(HEARTBEAT_CMD,0,0);
break;
}
case END_UPDATE_REQUEST_CMD:
{
ProtocolSendAck(PROTOCOL_ACK,RET_PROTOCOL_OK); //Bootloader ack
SoftReset(); //simply reset cpu.
break;
}
case FLASH_API_VER_REQUEST_CMD:
{
char Version;
Version = 0x01;
ProtocolSendCmd(FLASH_API_VER_CMD,&Version,1);
break;
}
case SCRUB_FLASH_REQUEST_CMD:
{
//TODO
break;
}
}
break;
}
case SM_ABORT_UPDATE:
{
ProtocolSendAck(PROTOCOL_ACK,RET_PROTOCOL_OK); //Bootloader ack
SoftReset();
break;
}
}
break; //case SM_IDLE_STATE:
}
case SM_WAIT_FOR_UNLOCK_STATE:
{
switch(event)
{
case SM_TICK_EVENT:
{
break;
}
case SM_RX_CMD_EVENT:
{
if(Data == BOOTLOADER_UNLOCK_REQUEST_CMD)
{
if(RxDataBuffer[0] == BOOTLOADER_UNLOCK_CODE)
{
ProtocolSendAck(PROTOCOL_ACK,RET_PROTOCOL_FLASH_ERASE); //Inform PTE that flash is being erased
// #ifndef _DEBUG //don't touch FLASH in debug mode...
//Erase FLASH
if(FlashErase() != FLASH_STATUS_OK)
{
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_ERASE_FLASH_FAILED); //Acknowledge...
mSMState = SM_IDLE_STATE;
break;
}
// #endif
mSMState = SM_WAIT_FOR_NEXT_RECORD;
ProtocolSendAck(PROTOCOL_ACK,RET_PROTOCOL_OK);
}
else//Invalid unlock code... return to IDLE...
{
mSMState = SM_IDLE_STATE;
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_INVALID_UNLOCK_CODE);
}
}
else//If another command than UNLOCK is received... return to IDLE
{
mSMState = SM_IDLE_STATE;
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_UNLOCK_EXPECTED);
}
break; //case SM_RX_CMD_EVENT
}
case SM_ABORT_UPDATE:
{
break;
}
}
break; //case SM_WAIT_FOR_UNLOCK_STATE:
}
case SM_WAIT_FOR_NEXT_RECORD:
{
switch(event)
{
case SM_TICK_EVENT:
{
break;
}
case SM_RX_CMD_EVENT:
{
switch(Data)
{
case SEND_RECORD_REQUEST_CMD:
{
//TODO: Address check...
ProtocolSendAck(PROTOCOL_ACK,RET_PROTOCOL_FLASH_WRITE);
// unsigned int SectorStartAddress;
// unsigned short SectorSize;
// unsigned int *RecordDataPtr;
// unsigned int data;
//
// SectorStartAddress = *(unsigned int*)(&RxDataBuffer[0]);
// SectorSize = *(unsigned short*)(&RxDataBuffer[4]);
// RecordDataPtr = (unsigned int*)&RxDataBuffer[8];
// data = *RecordDataPtr;
// unsigned int test = KVA_TO_PA(APPLICATION_START_ADDRESS);
if(CurrentDataSector.SectorStartAddress < KVA_TO_PA(APPLICATION_FLASH_START_ADDRESS))
{
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_INVALID_ADDRESS);
break;
}
else if(FlashProgramData((void*)(CurrentDataSector.SectorStartAddress), CurrentDataSector.SectorData , CurrentDataSector.SectorSize) != FLASH_STATUS_OK)
{
ProtocolSendAck(PROTOCOL_NACK,RET_PROTOCOL_ERR_WRITE_FLASH_FAILED);
break;
}
ProtocolSendAck(PROTOCOL_ACK,RET_PROTOCOL_OK);
break;
}
case END_UPDATE_REQUEST_CMD:
{
ProtocolSendAck(PROTOCOL_ACK,RET_PROTOCOL_OK);
#ifndef _DEBUG
JumpToApp();
#else
mSMState = SM_IDLE_STATE;
#endif
break;
}
}
break; //case SM_RX_CMD_EVENT:
}
case SM_ABORT_UPDATE:
{
break;
}
}
break; //case SM_WAIT_FOR_NEXT_RECORD:
}
}
}
void JumpToApp()
{
// CloseInternalUart();
void (*fptr)(void);
fptr = (void (*)(void))APPLICATION_START_ADDRESS;
fptr();
}
void DownloadFlash(unsigned int StartAddress, unsigned int EndAddress)
{
/*
unsigned int CurAddress = StartAddress;
unsigned int Data;
unsigned int delay = 0;
char Buf[100];
int i = 0;
while(CurAddress < EndAddress)
{
Data = (CurAddress >> 16);
sprintf(Buf, "0x%.4X",Data);
SendInternalUartData(Buf,strlen(Buf));
// ProtocolSendCmd(FLASH_DATA_CMD,Buf,strlen(Buf));
Data = CurAddress;
sprintf(Buf, "%.4X ",Data);
SendInternalUartData(Buf,strlen(Buf));
// ProtocolSendCmd(FLASH_DATA_CMD,Buf,strlen(Buf));
for(i = 0; i < 16; i++)
{
Data = *(unsigned int*)CurAddress;
if(i != 15)
sprintf(Buf, "%.4X ",Data);
else
sprintf(Buf, "%.4X \r",Data);
SendInternalUartData(Buf,strlen(Buf));
// ProtocolSendCmd(FLASH_DATA_CMD,Buf,strlen(Buf));
CurAddress++;
// while(delay++ < 5000);
delay = 0;
}
}
e_FlashUpdateMode = false;
*/
}
//EOf

View File

@ -0,0 +1,36 @@
#ifndef BOOTLOADER_STATE_MACHINE_H
#define BOOTLOADER_STATE_MACHINE_H
#define SM_NULL_DATA 0
#define PSEUDO_TIMER_VALUE 1500000
#define BOOTLOADER_UNLOCK_CODE 0xA5
enum eBootloaderSMStates
{
SM_UPDATE_WAIT_STATE,
SM_IDLE_STATE,
SM_WAIT_FOR_UNLOCK_STATE,
SM_WAIT_FOR_NEXT_RECORD
};
enum eBootloaderEvents
{
SM_TICK_EVENT,
SM_RX_CMD_EVENT,
SM_ABORT_UPDATE
};
void BootloaderSMInit(void);
void BootloaderSM( unsigned int event, unsigned int Data );
void JumpToApp(void);
void DownloadFlash(unsigned int StartAddress, unsigned int EndAddress);
#endif
//===========================================================================
// End of file.
//===========================================================================

View File

@ -0,0 +1,69 @@
/*******************************************************************************
* *
* 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)
{
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_OFF;
// 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; //Rising 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, 10000000);
// SPI2CONbits.ON = 1;
}
//EOF

View File

@ -0,0 +1,68 @@
/*******************************************************************************
* *
* 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
/* ************************************************************************** */
/* Includes */
/* ************************************************************************** */
/* Defines */
//Output pins hardware definitions
//
#define HEARTBEAT_LED_1_PIN_DIR TRISEbits.TRISE5
#define HEARTBEAT_LED_1_PIN LATEbits.LATE5
#define HEARTBEAT_LED_2_PIN_DIR TRISEbits.TRISE6
#define HEARTBEAT_LED_2_PIN LATEbits.LATE6
#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
#define LED_ON 0
#define LED_OFF 1
#define PIN_INPUT 1
#define PIN_OUTPUT 0
#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);
#endif
//EOF

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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 */

View 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 ---*/

View 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

File diff suppressed because it is too large Load Diff

View 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

View File

@ -0,0 +1,661 @@
/*------------------------------------------------------------------------/
/ 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 "define.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 (1) /* Card detected (yes:true, no:false, default:true) */
#define MMC_WP (0) /* 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;
}

View File

@ -0,0 +1,43 @@
/******************************************************************************
*
* File I/O SD Card Demo System Header File
*
******************************************************************************
* FileName: system_config.h
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* The software supplied herewith by Microchip Technology Incorporated
* (the "Company") for its PICmicro(R) Microcontroller is intended and
* supplied to you, the Company's customer, for use solely and
* exclusively on Microchip PICmicro Microcontroller products. The
* software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
********************************************************************/
#include "fileio_config.h"
#include "sd_spi_config.h"
// Definition for system clock
#define SYS_CLK_FrequencySystemGet() 80000000
// Definition for peripheral clock
#define SYS_CLK_FrequencyPeripheralGet() SYS_CLK_FrequencySystemGet()
// Definition for instruction clock
#define SYS_CLK_FrequencyInstructionGet() (SYS_CLK_FrequencySystemGet() / 2)
#define DRV_SPI_CONFIG_CHANNEL_2_ENABLE
//#include "drv_spi_config.h"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,461 @@
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*******************************************************************************/
// DOM-IGNORE-END
#ifndef _DRV_SPI_H
#define _DRV_SPI_H
#include <stdint.h>
#ifdef __cplusplus // Provide C++ Compatability
extern "C" {
#endif
// *****************************************************************************
/* SPI Modes Enumeration
Summary:
Specifies the SPI modes which can be used in the initialization structure
to initialize the SPI for operation.
Description:
Specifies the SPI bus modes enumeration for which an SPI channel
can operate on. The SPI channel bus mode can be set in the
SPI channel initialization routine parameter.
*/
typedef enum
{
SPI_BUS_MODE_0 = 0x0050, //smp = 0, ckp = 0
SPI_BUS_MODE_1, //smp = 1, ckp = 0
SPI_BUS_MODE_2, //smp = 0, ckp = 1
SPI_BUS_MODE_3, //smp = 1, ckp = 1
}SPI_BUS_MODES;
// *****************************************************************************
/* SPI Transfer Mode Enumeration
Summary:
Defines the Transfer Mode enumeration for SPI.
Description:
This defines the Transfer Mode enumeration for SPI.
*/
typedef enum {
SPI_TRANSFER_MODE_32BIT = 2,
SPI_TRANSFER_MODE_16BIT = 1,
SPI_TRANSFER_MODE_8BIT = 0
}SPI_TRANSFER_MODE;
// *****************************************************************************
/* SPI Initialization structure
Summary:
The structure that defines the SPI channel's operation.
Description:
Specifies the members which can be adjusted to allow the
SPI to be initialized for each instance of SPI.
*/
typedef struct
{
/*Channel for the SPI communication */
uint16_t channel;
#if defined (__PIC32MX)
/*Baud rate for the SPI communication */
uint16_t baudRate;
uint16_t dummy;
/* Clock Edge Selection Bits */
uint8_t cke;
/* One of SPI Bus mode as specified SPI_BUS_MODES */
SPI_BUS_MODES spibus_mode;
/* Select between 8 and 16 bit communication */
SPI_TRANSFER_MODE mode;
#endif
} DRV_SPI_INIT_DATA;
/* macros that defines the SPI signal polarities */
#define SPI_CKE_IDLE_ACT 0 // data change is on active clock to idle clock state
#define SPI_CKE_ACT_IDLE 1 // data change is on idle clock to active clock state
#define SPI_CKP_ACT_HIGH 0 // clock active state is high level
#define SPI_CKP_ACT_LOW 1 // clock active state is low level
#define SPI_SMP_PHASE_MID 0 // master mode data sampled at middle of data output time
#define SPI_SMP_PHASE_END 1 // master mode data sampled at end of data output time
#define SPI_MST_MODE_ENABLE 1 // SPI master mode enabled
#define SPI_MST_MODE_DISABLE 0 // SPI master mode disabled, use SPI in slave mode
#define SPI_MODULE_ENABLE 1 // Enable SPI
#define SPI_MODULE_DISABLE 0 // Disable SPI
// *****************************************************************************
/* Function:
void DRV_SPI_Initialize(DRV_SPI_INIT_DATA *pData)
Summary:
Initializes the SPI instance specified by the channel of the initialization
structure.
Description:
This routine initializes the spi driver instance specified by the channel
of the initialization structure making it ready for clients to lock and
use it.
Precondition:
None.
Returns:
None.
Parameters:
pData - SPI initialization structure.
Example:
<code>
uint16_t myBuffer[MY_BUFFER_SIZE];
unsigned int total;
uint8_t myChannel = 2;
DRV_SPI_INIT_DATA spiInitData = {2, 3, 7, 0, SPI_BUS_MODE_3, 0};
DRV_SPI_Initialize(&spiInitData);
DRV_SPI_Lock(myChannel);
total = 0;
do
{
total += DRV_SPI_PutBuffer( myChannel, &myBuffer[total], MY_BUFFER_SIZE - total );
// Do something else...
} while( total < MY_BUFFER_SIZE );
</code>
Remarks:
This routine must be called before any other SPI routine is called.
This routine should only be called once during system initialization.
Current implementation supports 8-bit transfer mode only.
*/
void DRV_SPI_Initialize(DRV_SPI_INIT_DATA *pData);
// *****************************************************************************
/* Function:
void DRV_SPI_Deinitialize (uint8_t channel)
Summary:
Deinitializes the SPI instance specified by the channel parameter
Description:
This routine deinitializes the spi driver instance specified by the channel
parameter.
Precondition:
None.
Returns:
None.
Parameters:
channel - SPI instance which needs to be deinitialized.
Example:
<code>
uint8_t myChannel = 2;
DRV_SPI_Deinitialize(myChannel);
</code>
Remarks:
None.
*/
void DRV_SPI_Deinitialize (uint8_t channel);
// *****************************************************************************
/* Function:
void DRV_SPI_Put(uint8_t channel, uint8_t data)
Summary:
Writes a byte of data to the SPI to the specified channel
Description:
This routine writes a byte of data to the SPI to the specified channel
Precondition:
The DRV_SPI_Initialize routine must have been called for the specified
SPI driver instance.
Returns:
None.
Parameters:
channel - SPI instance through which the communication needs to happen
data - Data byte to write to the SPI
Example:
<code>
uint16_t myBuffer[MY_BUFFER_SIZE];
unsigned int numBytes;
uint8_t myChannel = 2;
// Pre-initialize myBuffer with MY_BUFFER_SIZE bytes of valid data.
numBytes = 0;
while( numBytes < MY_BUFFER_SIZE )
{
// DRV_SPI_Put API returns data in any case, upto the user to use it
DRV_SPI_Put( myChannel, myBuffer[numBytes++] );
// Do something else...
}
</code>
Remarks:
This is a blocking routine.
*/
void DRV_SPI_Put(uint8_t channel, uint8_t data);
// *****************************************************************************
/* Function:
uint8_t DRV_SPI_Get(uint8_t channel)
Summary:
Reads a byte of data from SPI from the specified channel
Description:
This routine reads a byte of data from SPI from the specified channel
Precondition:
The DRV_SPI_Initialize routine must have been called for the specified
SPI driver instance.
Returns:
A data byte received by the driver.
Parameters:
channel - SPI instance through which the communication needs to happen
Example:
<code>
char myBuffer[MY_BUFFER_SIZE];
unsigned int numBytes;
uint8_t myChannel = 2;
numBytes = 0;
do
{
myBuffer[numBytes++] = DRV_SPI_Get(myChannel);
// Do something else...
} while( numBytes < MY_BUFFER_SIZE);
</code>
Remarks:
This is blocking routine.
*/
uint8_t DRV_SPI_Get(uint8_t channel);
// *****************************************************************************
/* Function:
int DRV_SPI_Lock(uint8_t channel)
Summary:
Locks the SPI instance specified using the channel parameter
Description:
This routine locks the SPI driver instance specified using the channel
parameter
Precondition:
None.
Returns:
Returns the status of the driver usage.
Parameters:
channel - SPI instance through which the communication needs to happen
Example:
Refer to DRV_SPI_Initialize() for an example
Remarks:
None.
*/
int DRV_SPI_Lock(uint8_t channel);
// *****************************************************************************
/* Function:
void DRV_SPI_Unlock(uint8_t channel)
Summary:
Unlocks the SPI instance specified by channel parameter
Description:
This routine unlocks the SPI driver instance specified by channel parameter
making it ready for other clients to lock and use it.
Precondition:
None.
Returns:
None.
Parameters:
channel - SPI instance through which the communication needs to happen
Example:
<code>
uint8_t myChannel = 2;
DRV_SPI_Unlock(myChannel);
</code>
Remarks:
None.
*/
void DRV_SPI_Unlock(uint8_t channel);
// *****************************************************************************
/* Function:
void DRV_SPI_PutBuffer (uint8_t channel, uint8_t * data, uint16_t count)
Summary:
Writes a data buffer to SPI
Description:
This routine writes a buffered data to SPI.
Precondition:
The DRV_SPI_Initialize routine must have been called for the specified
SPI driver instance.
Returns:
None.
Parameters:
channel - SPI instance through which the communication needs to happen
data - Pointer to buffer containing the data write to the SPI instance
count - Total number of bytes that to write to the SPI instance
(must be equal to or less than the size of the buffer)
Example:
Refer to DRV_SPI_Initialize() for an example
Remarks:
This is a blocking routine.
*/
void DRV_SPI_PutBuffer (uint8_t channel, uint8_t * data, uint16_t count);
// *****************************************************************************
/* Function:
void DRV_SPI_GetBuffer (uint8_t channel, uint8_t * data, uint16_t count)
Summary:
Reads a buffered data from SPI
Description:
This routine reads a buffered data from the SPI.
Precondition:
The DRV_SPI_Initialize routine must have been called.
Returns:
None.
Parameters:
channel - SPI instance through which the communication needs to happen
data - Pointer to buffer into which the data read from the SPI instance
will be placed.
count - Total number of bytes that need to be read from the module
instance (must be equal to or less than the size of the
buffer)
Remarks:
This is a blocking routine.
*/
void DRV_SPI_GetBuffer (uint8_t channel, uint8_t * data, uint16_t count);
// *****************************************************************************
/* Function:
void SPI_DummyDataSet(
uint8_t channel,
uint8_t dummyData)
Summary:
Sets the dummy data when calling exchange functions
Description:
This function sets the dummy data used when performing a an SPI
get call. When get is used, the exchange functions will still need
to send data for proper SPI operation.
Precondition:
The DRV_SPI_Initialize routine must have been called.
Returns:
None.
Parameters:
channel - SPI instance through which the communication needs to happen
dummyData - Dummy data to be used.
Remarks:
This is a blocking routine.
*/
void SPI_DummyDataSet(
uint8_t channel,
uint8_t dummyData);
#ifdef __cplusplus // Provide C++ Compatibility
}
#endif
#endif // #ifndef _DRV_SPI_H
/*******************************************************************************
End of File
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,87 @@
/*******************************************************************************
FILEIO Configuration File Template
Company:
Microchip Technology Inc.
File Name:
fileio_config_template.h
Summary:
The header file is a template example for FILEIO configuration.
Description:
The header file is a template example for FIEIO configuration.
Info in this file should be included via system_config.h
*******************************************************************************/
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright (c) 2014 released Microchip Technology Inc. All rights reserved.
Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).
You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.
SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*******************************************************************************/
// DOM-IGNORE-END
#ifndef _FILEIO_CONFIG_H
#define _FILEIO_CONFIG_H
// Macro indicating how many drives can be mounted simultaneously.
#define FILEIO_CONFIG_MAX_DRIVES 1
// Defines a character to use as a delimiter for directories. Forward slash ('/') or backslash ('\\') is recommended.
#define FILEIO_CONFIG_DELIMITER '/'
// Macro defining the maximum supported sector size for the FILEIO module. This value should always be 512 , 1024, 2048, or 4096 bytes.
// Most media uses 512-byte sector sizes.
#define FILEIO_CONFIG_MEDIA_SECTOR_SIZE 512
/* *******************************************************************************************************/
/************** Compiler options to enable/Disable Features based on user's application ******************/
/* *******************************************************************************************************/
/**********************************************************************
Define FILEIO_CONFIG_FUNCTION_SEARCH to disable the functions used to
search for files.
**********************************************************************/
#define FILEIO_CONFIG_SEARCH_DISABLE
// Define FILEIO_CONFIG_FUNCTION_WRITE to disable the functions that write to a drive. Disabling this feature will
// force the file system into read-only mode.
#define FILEIO_CONFIG_WRITE_DISABLE
// Define FILEIO_CONFIG_FUNCTION_FORMAT to disable the function used to format drives.
#define FILEIO_CONFIG_FORMAT_DISABLE
// Define FILEIO_CONFIG_FUNCTION_DIRECTORY to disable use of directories on your drive. Disabling this feature will
// limit you to performing all file operations in the root directory.
#define FILEIO_CONFIG_DIRECTORY_DISABLE
// Define FILEIO_CONFIG_FUNCTION_DRIVE_PROPERTIES to disable the FILEIO_DrivePropertiesGet function. This function
// will determine the properties of your device, including unused memory.
#define FILEIO_CONFIG_DRIVE_PROPERTIES_DISABLE
// Define FILEIO_CONFIG_MULTIPLE_BUFFER_MODE_DISABLE to disable multiple buffer mode. This will force the library to
// use a single instance of the FAT and Data buffer. Otherwise, it will use one FAT buffer and one data buffer per drive
// (defined by FILEIO_CONFIG_MAX_DRIVES). If you are only using one drive in your application, this option has no effect.
//#define FILEIO_CONFIG_MULTIPLE_BUFFER_MODE_DISABLE
#endif

View File

@ -0,0 +1,67 @@
#include "fileio_driver.h"
#include "sd_spi.h"
#include "fileio_lfn.h"
void FILEIO_DRIVER_IOInitialize(int VolumeID)
{
//if(VolumeID == 1)
{
FILEIO_SD_IOInitialize(0);
}
}
bool FILEIO_DRIVER_MediaDetect(int VolumeID)
{
//if(VolumeID == 1)
{
return FILEIO_SD_MediaDetect(0);
}
return false;
}
FILEIO_MEDIA_INFORMATION * FILEIO_DRIVER_MediaInitialize(int VolumeID)
{
//if(VolumeID == 1)
{
return FILEIO_SD_MediaInitialize(0);
}
return 0;
}
bool FILEIO_DRIVER_MediaDeinitialize(int VolumeID)
{
// if(VolumeID == 1)
{
return FILEIO_SD_MediaDeinitialize(0);
}
return false;
}
bool FILEIO_DRIVER_SectorRead(int VolumeID, uint32_t sector_addr, uint8_t* buffer)
{
// if(VolumeID == 1)
{
return FILEIO_SD_SectorRead(0,sector_addr,buffer);
}
return false;
}
uint8_t FILEIO_DRIVER_SectorWrite(int VolumeID, uint32_t sector_addr, uint8_t* buffer, bool allowWriteToZero)
{
// if(VolumeID == 1)
{
return FILEIO_SD_SectorWrite(0,sector_addr,buffer,allowWriteToZero);
}
return false;
}
bool FILEIO_DRIVER_WriteProtectStateGet(int VolumeID)
{
// if(VolumeID == 1)
{
}
return FILEIO_SD_WriteProtectStateGet(0);
}

View File

@ -0,0 +1,22 @@
/*
* File: fileio_driver.h
* Author: JF
*
* Created on May 19, 2017, 10:43 AM
*/
#ifndef FILEIO_DRIVER_H
#define FILEIO_DRIVER_H
#include <stdbool.h>
#include "fileio_media.h"
void FILEIO_DRIVER_IOInitialize(int VolumeID);
bool FILEIO_DRIVER_MediaDetect(int VolumeID);
FILEIO_MEDIA_INFORMATION * FILEIO_DRIVER_MediaInitialize(int VolumeID);
bool FILEIO_DRIVER_MediaDeinitialize(int VolumeID);
bool FILEIO_DRIVER_SectorRead(int VolumeID, uint32_t sector_addr, uint8_t* buffer);
uint8_t FILEIO_DRIVER_SectorWrite(int VolumeID, uint32_t sector_addr, uint8_t* buffer, bool allowWriteToZero);
bool FILEIO_DRIVER_WriteProtectStateGet(int VolumeID);
#endif /* FILEIO_DRIVER_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright 2015 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
//DOM-IGNORE-END
#ifndef _FILEIO_MEDIA_H
#define _FILEIO_MEDIA_H
#include <stdint.h>
// Enumeration to define media error types
typedef enum
{
MEDIA_NO_ERROR, // No errors
MEDIA_DEVICE_NOT_PRESENT, // The requested device is not present
MEDIA_CANNOT_INITIALIZE // Cannot initialize media
} FILEIO_MEDIA_ERRORS;
// Media information flags. The driver's MediaInitialize function will return a pointer to one of these structures.
typedef struct
{
FILEIO_MEDIA_ERRORS errorCode; // The status of the initialization FILEIO_MEDIA_ERRORS
// Flags
union
{
uint8_t value;
struct
{
uint8_t sectorSize : 1; // The sector size parameter is valid.
uint8_t maxLUN : 1; // The max LUN parameter is valid.
} bits;
} validityFlags;
uint16_t sectorSize; // The sector size of the target device.
uint8_t maxLUN; // The maximum Logical Unit Number of the device.
} FILEIO_MEDIA_INFORMATION;
#endif

View File

@ -0,0 +1,361 @@
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright 2015 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
//DOM-IGNORE-END
#ifndef _FSDEF__H
#define _FSDEF__H
#include <stdint.h>
#include <stdbool.h>
#include "fileio.h"
// Private search parameters
typedef enum
{
FILEIO_SEARCH_ENTRY_EMPTY = 0x01,
FILEIO_SEARCH_ENTRY_MATCH = 0x02,
FILEIO_SEARCH_PARTIAL_STRING_SEARCH = 0x04,
FILEIO_SEARCH_ENTRY_ATTRIBUTES = 0x08
} FILEIO_SEARCH_TYPE;
typedef enum
{
FILEIO_NAME_INVALID,
FILEIO_NAME_SHORT,
FILEIO_NAME_LONG,
FILEIO_NAME_DOT
} FILEIO_NAME_TYPE;
typedef enum
{
FILEIO_BUFFER_DATA,
FILEIO_BUFFER_FAT
} FILEIO_BUFFER_ID;
#define FILEIO_DIRECTORY_ENTRIES_PER_SECTOR 0x0f // Mask for the number of directory entries in a sector
#define FILEIO_DIRECTORY_ENTRY_SIZE 32 // Directory entry size, in bytes
#define FILEIO_DIRECTORY_ENTRY_EMPTY 0 // Value to indicate that a directory entry is empty
#define FILEIO_DIRECTORY_ENTRY_DELETED 0xE5 // Value to indicate that a directory entry has been deleted
#define FILEIO_FIXED_ROOT_DIRECTORY_CLUSTER_NUMBER 0 // Value of the root directory cluster for non-FAT32 file systems
#define FILEIO_CLUSTER_VALUE_EMPTY 0x0000 // FAT entry for an empty cluster
#define FILEIO_CLUSTER_VALUE_FAT12_EOF 0xff8 // End-of-file cluster value for FAT12
#define FILEIO_CLUSTER_VALUE_FAT16_EOF 0xfff8 // End-of-file cluster value for FAT16
#define FILEIO_CLUSTER_VALUE_FAT32_EOF 0x0ffffff8 // End-of-file cluster value for FAT32
#define FILEIO_CLUSTER_VALUE_FAT12_FAIL 0xfff // Return value indicating failure for FAT12
#define FILEIO_CLUSTER_VALUE_FAT16_FAIL 0xffff // Return value indicating failure for FAT16
#define FILEIO_CLUSTER_VALUE_FAT32_FAIL 0x0fffffff // Return value indicating failure for FAT32
#define FILEIO_CLUSTER_VALUE_FAT12_END 0xff7 // Comparison value to determine if the firmware has reached the last allocatable cluster for FAT12
#define FILEIO_CLUSTER_VALUE_FAT16_END 0xfff7 // Comparison value to determine if the firmware has reached the last allocatable cluster for FAT16
#define FILEIO_CLUSTER_VALUE_FAT32_END 0x0ffffff7 // Comparison value to determine if the firmware has reached the last allocatable cluster for FAT32
#define FILEIO_MEDIA_SECTOR_MBR 0ul // Master Boot Record sector number
#define FILEIO_FAT_GOOD_SIGN_0 0x55 // FAT signature byte 0
#define FILEIO_FAT_GOOD_SIGN_1 0xAA // FAT signatury byte 1
typedef struct
{
uint32_t dataBufferCachedSector;
uint32_t fatBufferCachedSector;
struct
{
unsigned dataBufferNeedsWrite : 1;
unsigned fatBufferNeedsWrite : 1;
} flags;
void * driveOwner;
} FILEIO_BUFFER_STATUS;
// Structure containing information about a device
typedef struct
{
uint32_t firstPartitionSector; // Logical block address of the first sector of the FAT partition on the device
uint32_t firstFatSector; // Logical block address of the FAT
uint32_t firstRootSector; // Logical block address of the root directory
uint32_t firstRootCluster; // Cluster number of the root directory
uint32_t firstDataSector; // Logical block address of the data section of the device.
uint32_t partitionClusterCount; // The maximum number of clusters in the partition.
uint32_t sectorSize; // The size of a sector in bytes
uint32_t fatSectorCount; // The number of sectors in the FAT
uint8_t * dataBuffer; // Address of the global data buffer used to read and write file information
uint8_t * fatBuffer; // Address of the fat buffer used to read and write sectors of the FAT
FILEIO_BUFFER_STATUS * bufferStatusPtr; // Pointer to a buffer status structure
const FILEIO_DRIVE_CONFIG * driveConfig; // Configuration information for the drive
void * mediaParameters; // Parameters that describe which instance of the media to use (see [media].h for more information).
uint16_t rootDirectoryEntryCount; // The maximum number of entries in the root directory.
uint8_t fatCopyCount; // The number of copies of the FAT in the partition
uint8_t sectorsPerCluster; // The number of sectors per cluster in the data region
uint8_t type; // The file system type of the partition (FAT12, FAT16 or FAT32)
uint8_t mount; // Device mount flag (true if disk was mounted successfully, false otherwise)
uint8_t error; // Last error that occured for this drive
char driveId;
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_DRIVE;
#else
} FILEIO_DRIVE;
#endif
typedef struct
{
uint32_t cluster;
FILEIO_DRIVE * drive;
} FILEIO_DIRECTORY;
// Directory entry structure
typedef struct
{
char name[FILEIO_FILE_NAME_LENGTH_8P3_NO_RADIX]; // File name and extension
uint8_t attributes; // File attributes
uint8_t reserved0; // Reserved byte
uint8_t createTimeMs; // Create time (millisecond field)
uint16_t createTime; // Create time (second, minute, hour field)
uint16_t createDate; // Create date
uint16_t accessDate; // Last access date
uint16_t firstClusterHigh; // High word of the entry's first cluster number
uint16_t writeTime; // Last update time
uint16_t writeDate; // Last update date
uint16_t firstClusterLow; // Low word of the entry's first cluster number
uint32_t fileSize; // The 32-bit file size
} FILEIO_DIRECTORY_ENTRY;
// Long File Name Entry
typedef struct
{
uint8_t sequenceNumber; // Sequence number,
uint8_t namePart1[10]; // File name part 1
uint8_t attributes; // File attribute
uint8_t type; // LFN Type
uint8_t checksum; // Checksum
uint16_t namePart2[6]; // File name part 2
uint16_t reserved0; // Reserved for future use
uint16_t namePart3[2]; // File name part 3
} FILEIO_DIRECTORY_ENTRY_LFN;
// BIOS Parameter Block for a FAT12 partition
typedef struct {
uint8_t jumpCommand[3]; // Jump Command
uint8_t oemName[8]; // OEM name
uint16_t bytesPerSector; // Number of bytes per sector
uint8_t sectorsPerCluster; // Number of sectors per cluster
uint16_t reservedSectorCount; // Number of reserved sectors at the beginning of the partition
uint8_t fatCount; // Number of FATs on the partition
uint16_t rootDirectoryEntryCount; // Number of root directory entries
uint16_t totalSectors; // Total number of sectors
uint8_t mediaDescriptor; // Media descriptor
uint16_t sectorsPerFat; // Number of sectors per FAT
uint16_t sectorsPerTrack; // Number of sectors per track
uint16_t headCount; // Number of heads
uint32_t hiddenSectorCount; // Number of hidden sectors
uint32_t reserved0; // Reserved space
uint8_t driveNumber; // Drive number
uint8_t reserved1; // Reserved space
uint8_t bootSignature; // Boot signature - equal to 0x29
uint8_t volumeId[4]; // Volume ID
uint8_t volLabel[11]; // Volume Label
uint8_t fileSystemType[8]; // File system type in ASCII. Not used for determination
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_BIOS_PARAMETER_BLOCK_FAT12;
#else
} FILEIO_BIOS_PARAMETER_BLOCK_FAT12;
#endif
// BIOS Parameter Block for a FAT16 partition
typedef struct {
uint8_t jumpCommand[3]; // Jump Command
uint8_t oemName[8]; // OEM name
uint16_t bytesPerSector; // Number of bytes per sector
uint8_t sectorsPerCluster; // Number of sectors per cluster
uint16_t reservedSectorCount; // Number of reserved sectors at the beginning of the partition
uint8_t fatCount; // Number of FATs on the partition
uint16_t rootDirectoryEntryCount; // Number of root directory entries
uint16_t totalSectors16; // Total number of sectors
uint8_t mediaDescriptor; // Media descriptor
uint16_t sectorsPerFat; // Number of sectors per FAT
uint16_t sectorsPerTrack; // Number of sectors per track
uint16_t headCount; // Number of heads
uint32_t hiddenSectorCount; // Number of hidden sectors
uint32_t totalSectors32; // Total sector count (32 bits)
uint8_t driveNumber; // Drive number
uint8_t reserved0; // Reserved space
uint8_t bootSignature; // Boot signature - equal to 0x29
uint8_t volumeId[4]; // Volume ID
uint8_t volumeLabel[11]; // Volume Label
uint8_t fileSystemType[8]; // File system type in ASCII. Not used for determination
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_BIOS_PARAMETER_BLOCK_FAT16;
#else
} FILEIO_BIOS_PARAMETER_BLOCK_FAT16;
#endif
// BIOS Parameter Block for a FAT32 parition
typedef struct {
uint8_t jumpCommand[3]; // Jump Command
uint8_t oemName[8]; // OEM name
uint16_t bytesPerSector; // Number of uint8_ts per sector
uint8_t sectorsPerCluster; // Number of sectors per cluster
uint16_t reservedSectorCount; // Number of reserved sectors at the beginning of the partition
uint8_t fatCount; // Number of FATs on the partition
uint16_t rootDirectoryEntryCount; // Number of root directory entries
uint16_t totalSectors16; // Total number of sectors
uint8_t mediaDescriptor; // Media descriptor
uint16_t sectorsPerFat16; // Number of sectors per FAT (16-bit)
uint16_t sectorsPerTrack; // Number of sectors per track
uint16_t headCount; // Number of heads
uint32_t hiddenSectorCount; // Number of hidden sectors
uint32_t totalSectors32; // Total sector count (32 bits)
uint32_t sectorsPerFat32; // Sectors per FAT (32 bits)
uint16_t mirroringFlags; // Presently active FAT. Defined by bits 0-3 if bit 7 is 1.
uint16_t fileSystemVersion; // FAT32 filesystem version. Should be 0:0
uint32_t firstClusterRootDirectory; // Start cluster of the root directory (should be 2)
uint16_t fileSystemInformation; // File system information
uint16_t backupBootSector; // Backup boot sector address.
uint8_t reserved0[12]; // Reserved space
uint8_t driveNumber; // Drive number
uint8_t reserved1; // Reserved space
uint8_t bootSignature; // Boot signature - 0x29
uint8_t volumeId[4]; // Volume ID
uint8_t volumeLabel[11]; // Volume Label
uint8_t fileSystemType[8]; // File system type in ASCII. Not used for determination
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_BIOS_PARAMETER_BLOCK_FAT32;
#else
} FILEIO_BIOS_PARAMETER_BLOCK_FAT32;
#endif
// A macro for the boot sector uint8_ts per sector value offset
#define BSI_BPS 11
// A macro for the boot sector sector per cluster value offset
#define BSI_SPC 13
// A macro for the boot sector reserved sector count value offset
#define BSI_RESRVSEC 14
// A macro for the boot sector FAT count value offset
#define BSI_FATCOUNT 16
// A macro for the boot sector root directory entry count value offset
#define BSI_ROOTDIRENTS 17
// A macro for the boot sector 16-bit total sector count value offset
#define BSI_TOTSEC16 19
// A macro for the boot sector sectors per FAT value offset
#define BSI_SPF 22
// A macro for the boot sector 32-bit total sector count value offset
#define BSI_TOTSEC32 32
// A macro for the boot sector boot signature offset
#define BSI_BOOTSIG 38
// A macro for the boot sector file system type string offset
#define BSI_FSTYPE 54
// A macro for the boot sector 32-bit sector per FAT value offset
#define BSI_FATSZ32 36
// A macro for the boot sector start cluster of root directory value offset
#define BSI_ROOTCLUS 44
// A macro for the FAT32 boot sector boot signature offset
#define BSI_FAT32_BOOTSIG 66
// A macro for the FAT32 boot sector file system type string offset
#define BSI_FAT32_FSTYPE 82
// Structure of a partition table entry
typedef struct
{
uint8_t bootDescriptor; // The boot descriptor (should be 0x00 in a non-bootable device)
uint8_t chsFirstParitionSector[3]; // The cylinder-head-sector address of the first sector of the partition
uint8_t fileSystemDescriptor; // The file system descriptor
uint8_t chsLastPartitionSector[3]; // The cylinder-head-sector address of the last sector of the partition
uint32_t lbaFirstSector; // The logical block address of the first sector of the partition
uint32_t sectorCount; // The number of sectors in a partition
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_MBR_PARTITION_TABLE_ENTRY;
#else
} FILEIO_MBR_PARTITION_TABLE_ENTRY;
#endif
// Strucure of a device's master boot record
typedef struct
{
uint8_t bootCode[446]; // Boot code
FILEIO_MBR_PARTITION_TABLE_ENTRY partition0; // The first partition table entry
FILEIO_MBR_PARTITION_TABLE_ENTRY partition1; // The second partition table entry
FILEIO_MBR_PARTITION_TABLE_ENTRY partition2; // The third partition table entry
FILEIO_MBR_PARTITION_TABLE_ENTRY partition3; // The fourth partition table entry
uint8_t signature0; // MBR signature code - equal to 0x55
uint8_t signature1; // MBR signature code - equal to 0xAA
#if defined __XC32__ || defined __XC16__
}__attribute__((packed)) FILEIO_MASTER_BOOT_RECORD;
#else
} FILEIO_MASTER_BOOT_RECORD;
#endif
// Structure matching the configuration of a FAT boot sector
typedef struct
{
// A union of different bios parameter blocks
union
{
FILEIO_BIOS_PARAMETER_BLOCK_FAT32 fat32;
FILEIO_BIOS_PARAMETER_BLOCK_FAT16 fat16;
FILEIO_BIOS_PARAMETER_BLOCK_FAT12 fat12;
} biosParameterBlock;
uint8_t reserved[512-sizeof(FILEIO_BIOS_PARAMETER_BLOCK_FAT32)-2]; // Reserved space
uint8_t signature0; // Boot sector signature code - equal to 0x55
uint8_t signature1; // Boot sector signature code - equal to 0xAA
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_BOOT_SECTOR;
#else
} FILEIO_BOOT_SECTOR;
#endif
FILEIO_ERROR_TYPE FILEIO_LoadMBR (FILEIO_DRIVE * drive);
FILEIO_ERROR_TYPE FILEIO_LoadBootSector (FILEIO_DRIVE * drive);
uint32_t FILEIO_FullClusterNumberGet(FILEIO_DIRECTORY_ENTRY * entry);
uint32_t FILEIO_ClusterToSector(FILEIO_DRIVE * disk, uint32_t cluster);
FILEIO_DRIVE * FILEIO_CharToDrive (char c);
const char * FILEIO_CacheDirectory (FILEIO_DIRECTORY * dir, const char * path, bool createDirectories);
uint16_t FILEIO_FindNextDelimiter(const char * path);
FILEIO_RESULT FILEIO_DirectoryMakeSingle (FILEIO_DIRECTORY * dir, const char * path);
FILEIO_RESULT FILEIO_DirectoryChangeSingle (FILEIO_DIRECTORY * dir, const char * path);
int FILEIO_DirectoryRemoveSingle (FILEIO_DIRECTORY * directory, char * path);
void FILEIO_FormatShortFileName (const char * fileName, FILEIO_OBJECT * filePtr);
uint8_t FILEIO_FileNameTypeGet (const char * fileName, bool partialStringSearch);
bool FILEIO_ShortFileNameCompare (uint8_t * fileName1, uint8_t * fileName2, uint8_t mode);
uint32_t FILEIO_FATWrite (FILEIO_DRIVE *disk, uint32_t currentCluster, uint32_t value, uint8_t forceWrite);
uint32_t FILEIO_FATRead (FILEIO_DRIVE * disk, uint32_t currentCluster);
FILEIO_DIRECTORY_ENTRY * FILEIO_DirectoryEntryCache (FILEIO_DIRECTORY * directory, FILEIO_ERROR_TYPE * error, uint32_t * currentCluster, uint16_t * currentClusterOffset, uint16_t entryOffset);
bool FILEIO_FlushBuffer (FILEIO_DRIVE * disk, FILEIO_BUFFER_ID bufferId);
FILEIO_ERROR_TYPE FILEIO_EraseClusterChain (uint32_t cluster, FILEIO_DRIVE * disk);
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryCreate (FILEIO_OBJECT * filePtr, uint16_t * entryHandle, uint8_t attributes, bool allocateDataCluster);
FILEIO_ERROR_TYPE FILEIO_ClusterAllocate (FILEIO_DRIVE * drive, uint32_t * cluster, bool eraseCluster);
FILEIO_ERROR_TYPE FILEIO_EraseCluster (FILEIO_DRIVE * drive, uint32_t cluster);
uint32_t FILEIO_FindEmptyCluster (FILEIO_DRIVE * drive, uint32_t baseCluster);
uint32_t FILEIO_CreateFirstCluster (FILEIO_OBJECT * filePtr);
FILEIO_ERROR_TYPE FILEIO_FindShortFileName (FILEIO_DIRECTORY * directory, FILEIO_OBJECT * filePtr, uint8_t * fileName, uint32_t * currentCluster, uint16_t * currentClusterOffset, uint16_t entryOffset, uint16_t attributes, FILEIO_SEARCH_TYPE mode);
FILEIO_ERROR_TYPE FILEIO_EraseFile (FILEIO_OBJECT * filePtr, uint16_t * entryHandle, bool eraseData);
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryFindEmpty (FILEIO_OBJECT * filePtr, uint16_t * entryOffset);
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryPopulate(FILEIO_OBJECT * filePtr, uint16_t * entryHandle, uint8_t attributes, uint32_t cluster);
FILEIO_ERROR_TYPE FILEIO_NextClusterGet (FILEIO_OBJECT * fo, uint32_t count);
int FILEIO_DotEntryWrite (FILEIO_DRIVE * drive, uint32_t dot, uint32_t dotdot, FILEIO_TIMESTAMP * timeStamp);
void FILEIO_ShortFileNameConvert (char * newFileName, char * oldFileName);
bool FILEIO_IsClusterAllocated(FILEIO_DIRECTORY * directory, FILEIO_OBJECT * filePtr);
int FILEIO_GetSingleBuffer (FILEIO_DRIVE * drive);
FILEIO_ERROR_TYPE FILEIO_ForceRecache (FILEIO_DRIVE * disk);
#endif

View File

@ -0,0 +1,376 @@
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright 2015 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
//DOM-IGNORE-END
#ifndef _FSDEF__H
#define _FSDEF__H
#include <stdint.h>
#include <stdbool.h>
#include "fileio_lfn.h"
// Private search paramters
typedef enum
{
FILEIO_SEARCH_ENTRY_EMPTY = 0x01,
FILEIO_SEARCH_ENTRY_MATCH = 0x02,
FILEIO_SEARCH_PARTIAL_STRING_SEARCH = 0x04,
FILEIO_SEARCH_ENTRY_ATTRIBUTES = 0x08
} FILEIO_SEARCH_TYPE;
typedef enum
{
FILEIO_NAME_INVALID,
FILEIO_NAME_SHORT,
FILEIO_NAME_LONG,
FILEIO_NAME_DOT
} FILEIO_NAME_TYPE;
typedef enum
{
FILEIO_BUFFER_DATA,
FILEIO_BUFFER_FAT
} FILEIO_BUFFER_ID;
#define FILEIO_FILE_NAME_LENGTH_LFN 256 // Maximum file name length for Long File Names
#define FILEIO_FILE_NAME_UTF16_CHARS_IN_LFN_ENTRY 13 // Number of UTF-16 characters in a LFN directory entry
#define FILEIO_DIRECTORY_ENTRIES_PER_SECTOR 0x0f // Mask for the number of directory entries in a sector
#define FILEIO_DIRECTORY_ENTRY_SIZE 32 // Directory entry size, in bytes
#define FILEIO_DIRECTORY_ENTRY_EMPTY 0 // Value to indicate that a directory entry is empty
#define FILEIO_DIRECTORY_ENTRY_DELETED 0xE5 // Value to indicate that a directory entry has been deleted
#define FILEIO_FIXED_ROOT_DIRECTORY_CLUSTER_NUMBER 0 // Value of the root directory cluster for non-FAT32 file systems
#define FILEIO_CLUSTER_VALUE_EMPTY 0x0000 // FAT entry for an empty cluster
#define FILEIO_CLUSTER_VALUE_FAT12_EOF 0xff8 // End-of-file cluster value for FAT12
#define FILEIO_CLUSTER_VALUE_FAT16_EOF 0xfff8 // End-of-file cluster value for FAT16
#define FILEIO_CLUSTER_VALUE_FAT32_EOF 0x0ffffff8 // End-of-file cluster value for FAT32
#define FILEIO_CLUSTER_VALUE_FAT12_FAIL 0xfff // Return value indicating failure for FAT12
#define FILEIO_CLUSTER_VALUE_FAT16_FAIL 0xffff // Return value indicating failure for FAT16
#define FILEIO_CLUSTER_VALUE_FAT32_FAIL 0x0fffffff // Return value indicating failure for FAT32
#define FILEIO_CLUSTER_VALUE_FAT12_END 0xff7 // Comparison value to determine if the firmware has reached the last allocatable cluster for FAT12
#define FILEIO_CLUSTER_VALUE_FAT16_END 0xfff7 // Comparison value to determine if the firmware has reached the last allocatable cluster for FAT16
#define FILEIO_CLUSTER_VALUE_FAT32_END 0x0ffffff7 // Comparison value to determine if the firmware has reached the last allocatable cluster for FAT32
#define FILEIO_MEDIA_SECTOR_MBR 0ul // Master Boot Record sector number
#define FILEIO_FAT_GOOD_SIGN_0 0x55 // FAT signature byte 0
#define FILEIO_FAT_GOOD_SIGN_1 0xAA // FAT signatury byte 1
typedef struct
{
uint32_t dataBufferCachedSector;
uint32_t fatBufferCachedSector;
struct
{
unsigned dataBufferNeedsWrite : 1;
unsigned fatBufferNeedsWrite : 1;
} flags;
void * driveOwner;
} FILEIO_BUFFER_STATUS;
// Structure containing information about a device
typedef struct
{
uint32_t firstPartitionSector; // Logical block address of the first sector of the FAT partition on the device
uint32_t firstFatSector; // Logical block address of the FAT
uint32_t firstRootSector; // Logical block address of the root directory
uint32_t firstRootCluster; // Cluster number of the root directory
uint32_t firstDataSector; // Logical block address of the data section of the device.
uint32_t partitionClusterCount; // The maximum number of clusters in the partition.
uint32_t sectorSize; // The size of a sector in bytes
uint32_t fatSectorCount; // The number of sectors in the FAT
uint8_t * dataBuffer; // Address of the global data buffer used to read and write file information
uint8_t * fatBuffer; // Address of the fat buffer used to read and write sectors of the FAT
FILEIO_BUFFER_STATUS * bufferStatusPtr; // Pointer to a buffer status structure
const FILEIO_DRIVE_CONFIG * driveConfig; // Configuration information for the drive
void * mediaParameters; // Parameters that describe which instance of the media to use (see [media].h for more information).
uint16_t rootDirectoryEntryCount; // The maximum number of entries in the root directory.
uint8_t fatCopyCount; // The number of copies of the FAT in the partition
uint8_t sectorsPerCluster; // The number of sectors per cluster in the data region
uint8_t type; // The file system type of the partition (FAT12, FAT16 or FAT32)
uint8_t mount; // Device mount flag (true if disk was mounted successfully, false otherwise)
uint8_t error; // Last error that occured for this drive
char driveId;
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_DRIVE;
#else
} FILEIO_DRIVE;
#endif
typedef struct
{
uint32_t cluster;
FILEIO_DRIVE * drive;
} FILEIO_DIRECTORY;
// Directory entry structure
typedef struct
{
char name[FILEIO_FILE_NAME_LENGTH_8P3_NO_RADIX]; // File name and extension
uint8_t attributes; // File attributes
uint8_t reserved0; // Reserved byte
uint8_t createTimeMs; // Create time (millisecond field)
uint16_t createTime; // Create time (second, minute, hour field)
uint16_t createDate; // Create date
uint16_t accessDate; // Last access date
uint16_t firstClusterHigh; // High word of the entry's first cluster number
uint16_t writeTime; // Last update time
uint16_t writeDate; // Last update date
uint16_t firstClusterLow; // Low word of the entry's first cluster number
uint32_t fileSize; // The 32-bit file size
} FILEIO_DIRECTORY_ENTRY;
// Long File Name Entry
typedef struct
{
uint8_t sequenceNumber; // Sequence number,
uint8_t namePart1[10]; // File name part 1
uint8_t attributes; // File attribute
uint8_t type; // LFN Type
uint8_t checksum; // Checksum
uint16_t namePart2[6]; // File name part 2
uint16_t reserved0; // Reserved for future use
uint16_t namePart3[2]; // File name part 3
} FILEIO_DIRECTORY_ENTRY_LFN;
// BIOS Parameter Block for a FAT12 partition
typedef struct {
uint8_t jumpCommand[3]; // Jump Command
uint8_t oemName[8]; // OEM name
uint16_t bytesPerSector; // Number of bytes per sector
uint8_t sectorsPerCluster; // Number of sectors per cluster
uint16_t reservedSectorCount; // Number of reserved sectors at the beginning of the partition
uint8_t fatCount; // Number of FATs on the partition
uint16_t rootDirectoryEntryCount; // Number of root directory entries
uint16_t totalSectors; // Total number of sectors
uint8_t mediaDescriptor; // Media descriptor
uint16_t sectorsPerFat; // Number of sectors per FAT
uint16_t sectorsPerTrack; // Number of sectors per track
uint16_t headCount; // Number of heads
uint32_t hiddenSectorCount; // Number of hidden sectors
uint32_t reserved0; // Reserved space
uint8_t driveNumber; // Drive number
uint8_t reserved1; // Reserved space
uint8_t bootSignature; // Boot signature - equal to 0x29
uint8_t volumeId[4]; // Volume ID
uint8_t volLabel[11]; // Volume Label
uint8_t fileSystemType[8]; // File system type in ASCII. Not used for determination
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_BIOS_PARAMETER_BLOCK_FAT12;
#else
} FILEIO_BIOS_PARAMETER_BLOCK_FAT12;
#endif
// BIOS Parameter Block for a FAT16 partition
typedef struct {
uint8_t jumpCommand[3]; // Jump Command
uint8_t oemName[8]; // OEM name
uint16_t bytesPerSector; // Number of bytes per sector
uint8_t sectorsPerCluster; // Number of sectors per cluster
uint16_t reservedSectorCount; // Number of reserved sectors at the beginning of the partition
uint8_t fatCount; // Number of FATs on the partition
uint16_t rootDirectoryEntryCount; // Number of root directory entries
uint16_t totalSectors16; // Total number of sectors
uint8_t mediaDescriptor; // Media descriptor
uint16_t sectorsPerFat; // Number of sectors per FAT
uint16_t sectorsPerTrack; // Number of sectors per track
uint16_t headCount; // Number of heads
uint32_t hiddenSectorCount; // Number of hidden sectors
uint32_t totalSectors32; // Total sector count (32 bits)
uint8_t driveNumber; // Drive number
uint8_t reserved0; // Reserved space
uint8_t bootSignature; // Boot signature - equal to 0x29
uint8_t volumeId[4]; // Volume ID
uint8_t volumeLabel[11]; // Volume Label
uint8_t fileSystemType[8]; // File system type in ASCII. Not used for determination
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_BIOS_PARAMETER_BLOCK_FAT16;
#else
} FILEIO_BIOS_PARAMETER_BLOCK_FAT16;
#endif
// BIOS Parameter Block for a FAT32 parition
typedef struct {
uint8_t jumpCommand[3]; // Jump Command
uint8_t oemName[8]; // OEM name
uint16_t bytesPerSector; // Number of uint8_ts per sector
uint8_t sectorsPerCluster; // Number of sectors per cluster
uint16_t reservedSectorCount; // Number of reserved sectors at the beginning of the partition
uint8_t fatCount; // Number of FATs on the partition
uint16_t rootDirectoryEntryCount; // Number of root directory entries
uint16_t totalSectors16; // Total number of sectors
uint8_t mediaDescriptor; // Media descriptor
uint16_t sectorsPerFat16; // Number of sectors per FAT (16-bit)
uint16_t sectorsPerTrack; // Number of sectors per track
uint16_t headCount; // Number of heads
uint32_t hiddenSectorCount; // Number of hidden sectors
uint32_t totalSectors32; // Total sector count (32 bits)
uint32_t sectorsPerFat32; // Sectors per FAT (32 bits)
uint16_t mirroringFlags; // Presently active FAT. Defined by bits 0-3 if bit 7 is 1.
uint16_t fileSystemVersion; // FAT32 filesystem version. Should be 0:0
uint32_t firstClusterRootDirectory; // Start cluster of the root directory (should be 2)
uint16_t fileSystemInformation; // File system information
uint16_t backupBootSector; // Backup boot sector address.
uint8_t reserved0[12]; // Reserved space
uint8_t driveNumber; // Drive number
uint8_t reserved1; // Reserved space
uint8_t bootSignature; // Boot signature - 0x29
uint8_t volumeId[4]; // Volume ID
uint8_t volumeLabel[11]; // Volume Label
uint8_t fileSystemType[8]; // File system type in ASCII. Not used for determination
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_BIOS_PARAMETER_BLOCK_FAT32;
#else
} FILEIO_BIOS_PARAMETER_BLOCK_FAT32;
#endif
// A macro for the boot sector uint8_ts per sector value offset
#define BSI_BPS 11
// A macro for the boot sector sector per cluster value offset
#define BSI_SPC 13
// A macro for the boot sector reserved sector count value offset
#define BSI_RESRVSEC 14
// A macro for the boot sector FAT count value offset
#define BSI_FATCOUNT 16
// A macro for the boot sector root directory entry count value offset
#define BSI_ROOTDIRENTS 17
// A macro for the boot sector 16-bit total sector count value offset
#define BSI_TOTSEC16 19
// A macro for the boot sector sectors per FAT value offset
#define BSI_SPF 22
// A macro for the boot sector 32-bit total sector count value offset
#define BSI_TOTSEC32 32
// A macro for the boot sector boot signature offset
#define BSI_BOOTSIG 38
// A macro for the boot sector file system type string offset
#define BSI_FSTYPE 54
// A macro for the boot sector 32-bit sector per FAT value offset
#define BSI_FATSZ32 36
// A macro for the boot sector start cluster of root directory value offset
#define BSI_ROOTCLUS 44
// A macro for the FAT32 boot sector boot signature offset
#define BSI_FAT32_BOOTSIG 66
// A macro for the FAT32 boot sector file system type string offset
#define BSI_FAT32_FSTYPE 82
// Structure of a partition table entry
typedef struct
{
uint8_t bootDescriptor; // The boot descriptor (should be 0x00 in a non-bootable device)
uint8_t chsFirstParitionSector[3]; // The cylinder-head-sector address of the first sector of the partition
uint8_t fileSystemDescriptor; // The file system descriptor
uint8_t chsLastPartitionSector[3]; // The cylinder-head-sector address of the last sector of the partition
uint32_t lbaFirstSector; // The logical block address of the first sector of the partition
uint32_t sectorCount; // The number of sectors in a partition
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_MBR_PARTITION_TABLE_ENTRY;
#else
} FILEIO_MBR_PARTITION_TABLE_ENTRY;
#endif
// Strucure of a device's master boot record
typedef struct
{
uint8_t bootCode[446]; // Boot code
FILEIO_MBR_PARTITION_TABLE_ENTRY partition0; // The first partition table entry
FILEIO_MBR_PARTITION_TABLE_ENTRY partition1; // The second partition table entry
FILEIO_MBR_PARTITION_TABLE_ENTRY partition2; // The third partition table entry
FILEIO_MBR_PARTITION_TABLE_ENTRY partition3; // The fourth partition table entry
uint8_t signature0; // MBR signature code - equal to 0x55
uint8_t signature1; // MBR signature code - equal to 0xAA
#if defined __XC32__ || defined __XC16__
}__attribute__((packed)) FILEIO_MASTER_BOOT_RECORD;
#else
} FILEIO_MASTER_BOOT_RECORD;
#endif
// Structure matching the configuration of a FAT boot sector
typedef struct
{
// A union of different bios parameter blocks
union
{
FILEIO_BIOS_PARAMETER_BLOCK_FAT32 fat32;
FILEIO_BIOS_PARAMETER_BLOCK_FAT16 fat16;
FILEIO_BIOS_PARAMETER_BLOCK_FAT12 fat12;
} biosParameterBlock;
uint8_t reserved[512-sizeof(FILEIO_BIOS_PARAMETER_BLOCK_FAT32)-2]; // Reserved space
uint8_t signature0; // Boot sector signature code - equal to 0x55
uint8_t signature1; // Boot sector signature code - equal to 0xAA
#if defined __XC32__ || defined __XC16__
} __attribute__ ((packed)) FILEIO_BOOT_SECTOR;
#else
} FILEIO_BOOT_SECTOR;
#endif
typedef enum
{
FILEIO_LFN_SUCCESS = 0,
FILEIO_LFN_FAILURE,
FILEIO_LFN_NONE
} FILEIO_LFN_ERROR;
FILEIO_ERROR_TYPE FILEIO_LoadMBR (FILEIO_DRIVE * drive);
FILEIO_ERROR_TYPE FILEIO_LoadBootSector (FILEIO_DRIVE * drive);
uint32_t FILEIO_FullClusterNumberGet(FILEIO_DIRECTORY_ENTRY * entry);
uint32_t FILEIO_ClusterToSector(FILEIO_DRIVE * disk, uint32_t cluster);
FILEIO_DRIVE * FILEIO_CharToDrive (uint16_t c);
uint16_t * FILEIO_CacheDirectory (FILEIO_DIRECTORY * dir, uint16_t * path, bool createDirectories);
uint16_t FILEIO_FindNextDelimiter(const uint16_t * path);
FILEIO_RESULT FILEIO_DirectoryMakeSingle (FILEIO_DIRECTORY * dir, uint16_t * path);
FILEIO_RESULT FILEIO_DirectoryChangeSingle (FILEIO_DIRECTORY * dir, uint16_t * path);
int FILEIO_DirectoryRemoveSingle (FILEIO_DIRECTORY * directory, uint16_t * path);
void FILEIO_FormatShortFileName (const uint16_t * fileName, FILEIO_OBJECT * filePtr);
uint8_t FILEIO_FileNameTypeGet (const uint16_t * fileName, bool partialStringSearch);
bool FILEIO_ShortFileNameCompare (uint8_t * fileName1, uint8_t * fileName2, uint8_t mode);
uint32_t FILEIO_FATWrite (FILEIO_DRIVE *disk, uint32_t currentCluster, uint32_t value, uint8_t forceWrite);
uint32_t FILEIO_FATRead (FILEIO_DRIVE * disk, uint32_t currentCluster);
FILEIO_DIRECTORY_ENTRY * FILEIO_DirectoryEntryCache (FILEIO_DIRECTORY * directory, FILEIO_ERROR_TYPE * error, uint32_t * currentCluster, uint16_t * currentClusterOffset, uint16_t entryOffset);
bool FILEIO_FlushBuffer (FILEIO_DRIVE * disk, FILEIO_BUFFER_ID bufferId);
FILEIO_ERROR_TYPE FILEIO_EraseClusterChain (uint32_t cluster, FILEIO_DRIVE * disk);
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryCreate (FILEIO_OBJECT * filePtr, uint16_t * entryHandle, uint8_t attributes, bool allocateDataCluster);
FILEIO_ERROR_TYPE FILEIO_ClusterAllocate (FILEIO_DRIVE * drive, uint32_t * cluster, bool eraseCluster);
FILEIO_ERROR_TYPE FILEIO_EraseCluster (FILEIO_DRIVE * drive, uint32_t cluster);
uint32_t FILEIO_FindEmptyCluster (FILEIO_DRIVE * drive, uint32_t baseCluster);
uint32_t FILEIO_CreateFirstCluster (FILEIO_OBJECT * filePtr);
FILEIO_ERROR_TYPE FILEIO_FindShortFileName (FILEIO_DIRECTORY * directory, FILEIO_OBJECT * filePtr, uint8_t * fileName, uint32_t * currentCluster, uint16_t * currentClusterOffset, uint16_t entryOffset, uint16_t attributes, FILEIO_SEARCH_TYPE mode);
FILEIO_ERROR_TYPE FILEIO_EraseFile (FILEIO_OBJECT * filePtr, uint16_t * entryHandle, bool eraseData);
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryFindEmpty (FILEIO_OBJECT * filePtr, uint16_t * entryOffset);
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryPopulate(FILEIO_OBJECT * filePtr, uint16_t * entryHandle, uint8_t attributes, uint32_t cluster);
FILEIO_ERROR_TYPE FILEIO_NextClusterGet (FILEIO_OBJECT * fo, uint32_t count);
int FILEIO_DotEntryWrite (FILEIO_DRIVE * drive, uint32_t dot, uint32_t dotdot, FILEIO_TIMESTAMP * timeStamp);
void FILEIO_ShortFileNameConvert (char * newFileName, char * oldFileName);
bool FILEIO_IsClusterAllocated(FILEIO_DIRECTORY * directory, FILEIO_OBJECT * filePtr);
int FILEIO_GetSingleBuffer (FILEIO_DRIVE * drive);
FILEIO_ERROR_TYPE FILEIO_ForceRecache (FILEIO_DRIVE * disk);
int FILEIO_memcmp16 (uint16_t * name1, uint16_t * name2, uint16_t len);
uint16_t FILEIO_strlen16 (uint16_t * name);
uint16_t FILEIO_lfnlen (uint16_t * name);
bool FILEIO_LongFileNameCompare (uint16_t * fileName, FILEIO_SEARCH_TYPE mode);
FILEIO_ERROR_TYPE FILEIO_FindLongFileName (FILEIO_DIRECTORY * directory, FILEIO_OBJECT * filePtr, uint32_t * currentCluster, uint16_t * currentClusterOffset, uint16_t entryOffset, uint16_t attributes, FILEIO_SEARCH_TYPE mode);
FILEIO_LFN_ERROR FILEIO_LongFileNameCache (FILEIO_DIRECTORY * directory, uint16_t shortEntryOffset, uint32_t currentCluster, uint8_t checksum);
bool FILEIO_AliasLFN (FILEIO_OBJECT * filePtr);
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryLFNCreate (FILEIO_OBJECT * filePtr, uint16_t * entryHandle);
#endif

View File

@ -0,0 +1,32 @@
#include "sd_hw_ctl.h"
#include "../DigitalIO.h"
#include "../define.h"
#include <stdbool.h>
void SD_SPIConfigurePins (void)
{
SD_SPI_SDI_PIN_DIR = PIN_INPUT;
SD_SPI_CS_PIN_DIR = PIN_OUTPUT;
SD_SPI_SDO_PIN_DIR = PIN_OUTPUT;
SD_SPI_SCK_PIN_DIR = PIN_OUTPUT;
}
void SD_SPISetChipSelect(unsigned int a)
{
if(a == 0)
{
SD_SPI_CS_PIN = 0;
}
else
{
SD_SPI_CS_PIN = 1;
}
}
bool SD_GetCardDetect(void)
{
return false;
}
bool SD_GetWriteProtect(void)
{
return false;
}

View File

@ -0,0 +1,19 @@
/*
* File: sd_hw_ctl.h
* Author: JF
*
* Created on May 19, 2017, 8:10 AM
*/
#ifndef SD_HW_CTL_H
#define SD_HW_CTL_H
#include <stdbool.h>
void SD_SPIConfigurePins(void);
void SD_SPISetChipSelect(unsigned int a);
bool SD_GetCardDetect(void);
bool SD_GetWriteProtect(void);
#endif /* SD_HW_CTL_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,487 @@
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright 2015 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
//DOM-IGNORE-END
#ifndef SDMMC_H
#define SDMMC_H
#include "FileSystem_config.h"
//#include "system.h"
#include <stdint.h>
#include <stdbool.h>
#include "fileio_media.h"
/*****************************************************************************/
/* Custom structures and definitions */
/*****************************************************************************/
//Definition for a structure used when calling either FILEIO_SD_AsyncReadTasks()
//function, or the FILEIO_SD_AsyncWriteTasks() function.
typedef struct
{
uint16_t wNumBytes; //Number of bytes to attempt to read or write in the next call to MDD_SDSPI_AsyncReadTasks() or MDD_SDSPI_AsyncWriteTasks. May be updated between calls to the handler.
uint32_t dwBytesRemaining; //Should be initialized to the total number of uint8_ts that you wish to read or write. This value is allowed to be greater than a single block size of the media.
uint8_t* pBuffer; //Pointer to where the read/written uint8_ts should be copied to/from. May be updated between calls to the handler function.
uint32_t dwAddress; //Starting block address to read or to write to on the media. Should only get initialized, do not modify after that.
uint8_t bStateVariable; //State machine variable. Should get initialized to ASYNC_READ_QUEUED or ASYNC_WRITE_QUEUED to start an operation. After that, do not modify until the read or write is complete.
}FILEIO_SD_ASYNC_IO;
//Response codes for the FILEIO_SD_AsyncReadTasks() function.
#define FILEIO_SD_ASYNC_READ_COMPLETE 0x00
#define FILEIO_SD_ASYNC_READ_BUSY 0x01
#define FILEIO_SD_ASYNC_READ_NEW_PACKET_READY 0x02
#define FILEIO_SD_ASYNC_READ_ERROR 0xFF
//FILEIO_SD_AsyncReadTasks() state machine variable values. These are used internally to sd_spi.c.
#define FILEIO_SD_ASYNC_READ_COMPLETE 0x00
#define FILEIO_SD_ASYNC_READ_QUEUED 0x01 //Initialize to this to start a read sequence
#define FILEIO_SD_ASYNC_READ_WAIT_START_TOKEN 0x03
#define FILEIO_SD_ASYNC_READ_NEW_PACKET_READY 0x02
#define FILEIO_SD_ASYNC_READ_ABORT 0xFE
#define FILEIO_SD_ASYNC_READ_ERROR 0xFF
//Possible return values when calling FILEIO_SD_AsyncWriteTasks()
#define FILEIO_SD_ASYNC_WRITE_COMPLETE 0x00
#define FILEIO_SD_ASYNC_WRITE_SEND_PACKET 0x02
#define FILEIO_SD_ASYNC_WRITE_BUSY 0x03
#define FILEIO_SD_ASYNC_WRITE_ERROR 0xFF
//FILEIO_SD_AsyncWriteTasks() state machine variable values. These are used internally to sd_spi.c.
#define FILEIO_SD_ASYNC_WRITE_COMPLETE 0x00
#define FILEIO_SD_ASYNC_WRITE_QUEUED 0x01 //Initialize to this to start a write sequence
#define FILEIO_SD_ASYNC_WRITE_TRANSMIT_PACKET 0x02
#define FILEIO_SD_ASYNC_WRITE_MEDIA_BUSY 0x03
#define FILEIO_SD_ASYNC_STOP_TOKEN_SENT_WAIT_BUSY 0x04
#define FILEIO_SD_ASYNC_WRITE_ABORT 0xFE
#define FILEIO_SD_ASYNC_WRITE_ERROR 0xFF
/*****************************************************************************/
/* Function pointer types */
/*****************************************************************************/
/*************************************************************************************
Function:
typedef void (*FILEIO_SD_CSSet)(uint8_t value)
Summary:
Prototype for a user-implemented function to set or
clear the SPI's chip select pin.
Input:
value - The value of the chip select pin (1 or 0)
Return Values:
None
Description:
Most functions in this driver require the user to implement the functions
that comprise a FILEIO_SD_DRIVE_CONFIG structure. This function pointer
definition describes a function in this structure that will set/clear the
chip select pin.
Remarks:
None
***********************************************************************************/
typedef void (*FILEIO_SD_CSSet)(uint8_t value);
/*************************************************************************************
Function:
typedef bool (*FILEIO_SD_CDGet)(void);
Summary:
Prototype for a user-implemented function to get the current state of the
Card Detect pin, if one exists.
Input:
None
Return Values:
true if the card detect pin indicates the card is inserted, false otherwise.
If the physical socket in use does not have a card detect pin, this
function should always return true.
Description:
Most functions in this driver require the user to implement the functions
that comprise a FILEIO_SD_DRIVE_CONFIG structure. This function pointer
definition describes a function in this structure that will return the value
of a card detect pin. These pins are a typical feature on the physical
sockets manufactured for SD card (not on the SD cards themselves). On
some types of SD card (i.e. micro SD) this pin will not be available.
Remarks:
None
***********************************************************************************/
typedef bool (*FILEIO_SD_CDGet)(void);
/*************************************************************************************
Function:
typedef bool (*FILEIO_SD_WPGet)(void);
Summary:
Prototype for a user-implemented function to get the current state of the
Write Protect pin, if one exists.
Input:
None
Return Values:
true if the write protect pin indicates the card is inserted, false otherwise.
If the physical socket in use does not have a write protect pin, this
function should always return false.
Description:
Most functions in this driver require the user to implement the functions
that comprise a FILEIO_SD_DRIVE_CONFIG structure. This function pointer
definition describes a function in this structure that will return the value
of a write protect pin. These pins are a typical feature on the physical
sockets manufactured for SD card (not on the SD cards themselves). On
some types of SD card (i.e. micro SD) this pin will not be available.
Remarks:
None
***********************************************************************************/
typedef bool (*FILEIO_SD_WPGet)(void);
/*************************************************************************************
Function:
typedef void (*FILEIO_SD_PinConfigure)(void);
Summary:
Prototype for a user-implemented function to configure the pins used by
the SD card.
Input:
None
Return Values:
None.
Description:
Most functions in this driver require the user to implement the functions
that comprise a FILEIO_SD_DRIVE_CONFIG structure. This function pointer
definition describes a function in this structure that will configure all of
the pins used by the SD Card. The configuration may involve setting/clearing
the TRIS bits, disabling the analog state of the pins, setting up peripheral
pin select, or other operations (depending on the device).
The user must configure the chip select, card detect, and write protect pins.
Optionally, configuration for the SPI pins (SDI, SDO, SCK) and SPI module
may be performed in this function, though it may make more sense to configure
those in another part of any given application.
Remarks:
None
***********************************************************************************/
typedef void (*FILEIO_SD_PinConfigure)(void);
// A configuration structure used by the SD-SPI driver functions to perform specific
// tasks.
typedef struct
{
uint8_t index; // The numeric index of the SPI module to use (i.e. 1 for SPI1/SSP1, 2 for SPI2, SSP2,...)
FILEIO_SD_CSSet csFunc; // Pointer to a user-implemented function to set/clear the chip select pins
FILEIO_SD_CDGet cdFunc; // Pointer to a user-implemented function to get the status of the card detect pin
FILEIO_SD_WPGet wpFunc; // Pointer to a user-implemented function to get the status of the write protect pin
FILEIO_SD_PinConfigure configurePins; // Pointer to a user-implemented function to configure the pins used by the SD Card
} FILEIO_SD_DRIVE_CONFIG;
/*****************************************************************************/
/* Public Prototypes */
/*****************************************************************************/
/*********************************************************
Function:
bool FILEIO_SD_MediaDetect (FILEIO_SD_DRIVE_CONFIG * config)
Summary:
Determines whether an SD card is present
Conditions:
The FILEIO_SD_MediaDetect function pointer must be configured
to point to this function in FSconfig.h
Input:
config - The given drive configuration
Return Values:
true - Card detected
false - No card detected
Side Effects:
None.
Description:
The FILEIO_SD_MediaDetect function determine if an SD card is connected to
the microcontroller.
If the MEDIA_SOFT_DETECT is not defined, the detection is done by polling
the SD card detect pin.
The MicroSD connector does not have a card detect pin, and therefore a
software mechanism must be used. To do this, the SEND_STATUS command is sent
to the card. If the card is not answering with 0x00, the card is either not
present, not configured, or in an error state. If this is the case, we try
to reconfigure the card. If the configuration fails, we consider the card not
present (it still may be present, but malfunctioning). In order to use the
software card detect mechanism, the MEDIA_SOFT_DETECT macro must be defined.
Remarks:
None
*********************************************************/
bool FILEIO_SD_MediaDetect(FILEIO_SD_DRIVE_CONFIG * config);
/*****************************************************************************
Function:
FILEIO_MEDIA_INFORMATION * FILEIO_SD_MediaInitialize (void)
Summary:
Initializes the SD card.
Conditions:
The FILEIO_SD_MediaInitialize function pointer must be pointing to this function.
Input:
config - An SD Drive configuration structure pointer
Return Values:
The function returns a pointer to the FILEIO_MEDIA_INFORMATION structure. The
errorCode member may contain the following values:
* MEDIA_NO_ERROR - The media initialized successfully
* MEDIA_CANNOT_INITIALIZE - Cannot initialize the media.
Side Effects:
None.
Description:
This function will send initialization commands to and SD card.
Remarks:
Psuedo code flow for the media initialization process is as follows:
-------------------------------------------------------------------------------------------
SD Card SPI Initialization Sequence (for physical layer v1.x or v2.0 device) is as follows:
-------------------------------------------------------------------------------------------
0. Power up tasks
a. Initialize microcontroller SPI module to no more than 400kbps rate so as to support MMC devices.
b. Add delay for SD card power up, prior to sending it any commands. It wants the
longer of: 1ms, the Vdd ramp time (time from 2.7V to Vdd stable), and 74+ clock pulses.
1. Send CMD0 (GO_IDLE_STATE) with CS = 0. This puts the media in SPI mode and software resets the SD/MMC card.
2. Send CMD8 (SEND_IF_COND). This requests what voltage the card wants to run at.
Note: Some cards will not support this command.
a. If illegal command response is received, this implies either a v1.x physical spec device, or not an SD card (ex: MMC).
b. If normal response is received, then it must be a v2.0 or later SD memory card.
If v1.x device:
-----------------
3. Send CMD1 repeatedly, until initialization complete (indicated by R1 response uint8_t/idle bit == 0)
4. Basic initialization is complete. May now switch to higher SPI frequencies.
5. Send CMD9 to read the CSD structure. This will tell us the total flash size and other info which will be useful later.
6. Parse CSD structure bits (based on v1.x structure format) and extract useful information about the media.
7. The card is now ready to perform application data transfers.
If v2.0+ device:
-----------------
3. Verify the voltage range is feasible. If not, unusable card, should notify user that the card is incompatible with this host.
4. Send CMD58 (Read OCR).
5. Send CMD55, then ACMD41 (SD_SEND_OP_COND, with HCS = 1).
a. Loop CMD55/ACMD41 until R1 response uint8_t == 0x00 (indicating the card is no longer busy/no longer in idle state).
6. Send CMD58 (Get CCS).
a. If CCS = 1 --> SDHC card.
b. If CCS = 0 --> Standard capacity SD card (which is v2.0+).
7. Basic initialization is complete. May now switch to higher SPI frequencies.
8. Send CMD9 to read the CSD structure. This will tell us the total flash size and other info which will be useful later.
9. Parse CSD structure bits (based on v2.0 structure format) and extract useful information about the media.
10. The card is now ready to perform application data transfers.
--------------------------------------------------------------------------------
********************************************************************************/
FILEIO_MEDIA_INFORMATION * FILEIO_SD_MediaInitialize(FILEIO_SD_DRIVE_CONFIG * config);
/*********************************************************
Function:
bool FILEIO_SD_MediaDeinitialize(
FILEIO_SD_DRIVE_CONFIG * config)
Summary:
Disables the SD card
Conditions:
The FILEIO_SD_MediaDeinitialize function pointer is pointing
towards this function.
Input:
config - An SD Drive configuration structure pointer
Return:
true if successful, false otherwise
Side Effects:
None.
Description:
This function will disable the SPI port and deselect
the SD card.
Remarks:
None
*********************************************************/
bool FILEIO_SD_MediaDeinitialize(FILEIO_SD_DRIVE_CONFIG * config);
/*********************************************************
Function:
uint32_t FILEIO_SD_CapacityRead(
FILEIO_SD_DRIVE_CONFIG * config)
Summary:
Determines the current capacity of the SD card
Conditions:
FILEIO_SD_MediaInitialize() is complete
Input:
config - An SD Drive configuration structure pointer
Return:
The capacity of the device
Side Effects:
None.
Description:
The FILEIO_SD_CapacityRead function is used by the
USB mass storage class to return the total number
of sectors on the card.
Remarks:
None
*********************************************************/
uint32_t FILEIO_SD_CapacityRead(FILEIO_SD_DRIVE_CONFIG * config);
/*********************************************************
Function:
uint16_t FILEIO_SD_SectorSizeRead(
FILEIO_SD_DRIVE_CONFIG * config)
Summary:
Determines the current sector size on the SD card
Conditions:
FILEIO_SD_MediaInitialize() is complete
Input:
config - An SD Drive configuration structure pointer
Return:
The size of the sectors for the physical media
Side Effects:
None.
Description:
The FILEIO_SD_SectorSizeRead function is used by the
USB mass storage class to return the card's sector
size to the PC on request.
Remarks:
None
*********************************************************/
uint16_t FILEIO_SD_SectorSizeRead(FILEIO_SD_DRIVE_CONFIG * config);
/*********************************************************
Function:
void FILEIO_SD_IOInitialize (
FILEIO_SD_DRIVE_CONFIG * config)
Summary:
Initializes the I/O lines connected to the card
Conditions:
FILEIO_SD_MediaInitialize() is complete. The MDD_InitIO
function pointer is pointing to this function.
Input:
config - An SD Drive configuration structure pointer
Return:
None
Side Effects:
None.
Description:
The FILEIO_SD_IOInitialize function initializes the I/O
pins connected to the SD card.
Remarks:
None
*********************************************************/
void FILEIO_SD_IOInitialize(FILEIO_SD_DRIVE_CONFIG * config);
//extern void FILEIO_Driver_IOInitialize(void);
/*****************************************************************************
Function:
uint8_t FILEIO_SD_SectorRead (uint32_t sector_addr, uint8_t * buffer)
Summary:
Reads a sector of data from an SD card.
Conditions:
The FILEIO_SD_SectorRead function pointer must be pointing towards this function.
Input:
config - An SD Drive configuration structure pointer
sectorAddress - The address of the sector on the card.
buffer - The buffer where the retrieved data will be stored. If
buffer is NULL, do not store the data anywhere.
Return Values:
true - The sector was read successfully
false - The sector could not be read
Side Effects:
None
Description:
The FILEIO_SD_SectorRead function reads a sector of data uint8_ts (512 uint8_ts)
of data from the SD card starting at the sector address and stores them in
the location pointed to by 'buffer.'
Remarks:
The card expects the address field in the command packet to be a uint8_t address.
The sector_addr value is converted to a uint8_t address by shifting it left nine
times (multiplying by 512).
This function performs a synchronous read operation. In other uint16_ts, this
function is a blocking function, and will not return until either the data
has fully been read, or, a timeout or other error occurred.
***************************************************************************************/
bool FILEIO_SD_SectorRead(FILEIO_SD_DRIVE_CONFIG * config, uint32_t sector_addr, uint8_t * buffer);
/*****************************************************************************
Function:
bool FILEIO_SD_SectorWrite (FILEIO_SD_DRIVE_CONFIG * config,
uint32_t sector_addr, uint8_t * buffer, uint8_t allowWriteToZero)
Summary:
Writes a sector of data to an SD card.
Conditions:
The FILEIO_SD_SectorWrite function pointer must be pointing to this function.
Input:
config - An SD Drive configuration structure pointer
sectorAddress - The address of the sector on the card.
buffer - The buffer with the data to write.
allowWriteToZero -
- true - Writes to the 0 sector (MBR) are allowed
- false - Any write to the 0 sector will fail.
Return Values:
true - The sector was written successfully.
false - The sector could not be written.
Side Effects:
None.
Description:
The FILEIO_SD_SectorWrite function writes one sector of data (512 uint8_ts)
of data from the location pointed to by 'buffer' to the specified sector of
the SD card.
Remarks:
The card expects the address field in the command packet to be a uint8_t address.
The sector_addr value is converted to a uint8_t address by shifting it left nine
times (multiplying by 512).
***************************************************************************************/
bool FILEIO_SD_SectorWrite(FILEIO_SD_DRIVE_CONFIG * config, uint32_t sector_addr, uint8_t * buffer, bool allowWriteToZero);
/*******************************************************************************
Function:
uint8_t FILEIO_SD_WriteProtectStateGet
Summary:
Indicates whether the card is write-protected.
Conditions:
The FILEIO_SD_WriteProtectStateGet function pointer must be pointing to this function.
Input:
config - An SD Drive configuration structure pointer
Return Values:
true - The card is write-protected
false - The card is not write-protected
Side Effects:
None.
Description:
The FILEIO_SD_WriteProtectStateGet function will determine if the SD card is
write protected by checking the electrical signal that corresponds to the
physical write-protect switch.
Remarks:
None
*******************************************************************************/
bool FILEIO_SD_WriteProtectStateGet(FILEIO_SD_DRIVE_CONFIG * config);
uint8_t FILEIO_SD_AsyncReadTasks(FILEIO_SD_DRIVE_CONFIG * config, FILEIO_SD_ASYNC_IO*);
uint8_t FILEIO_SD_AsyncWriteTasks(FILEIO_SD_DRIVE_CONFIG * config, FILEIO_SD_ASYNC_IO*);
#endif

View File

@ -0,0 +1,65 @@
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright 2015 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
//DOM-IGNORE-END
//-------------Function name redirects------------------------------------------
// During the media initialization sequence for SD cards, it is
// necessary to clock the media at a frequency between 100 kHz and 400 kHz,
// since some media types power up in open drain output mode and cannot run
// fast initially.
// On PIC18 devices, when the CPU is running at full frequency, the standard SPI
// prescalars cannot reach a low enough SPI frequency. Therefore, we provide these
// configuration options to allow the user to remap the SPI functions called during
// the "slow" part of the initialization to user-implemented functions that can
// provide the correct functionality. For example, a bit-banged SPI module could
// be implemented to provide a clock between 100 and 400 kHz.
// For PIC18 versions of this demo, the slow functions are mapped to the fast SPI driver functions.
// The slower clock frequency will be achieved by disabling the PLL during the
// SD Card initialization. Note that the SYS_CLK_FrequencySystemGet function
// was implemented to return the correct clock frequency when using both a PLL-enabled
// or PLL-disabled clock.
#if defined (__XC8)
// Define the function to initialize the SPI module for operation at a slow clock rate
#define FILEIO_SD_SPIInitialize_Slow FILEIO_SD_SPISlowInitialize
// Define the function to send a media command at a slow clock rate
#define FILEIO_SD_SendMediaCmd_Slow FILEIO_SD_SendCmdSlow
// Define the function to write an SPI byte at a slow clock rate
#define FILEIO_SD_SPI_Put_Slow DRV_SPI_Put
// Define the function to read an SPI byte at a slow clock rate
#define FILEIO_SD_SPI_Get_Slow DRV_SPI_Get
#else
// Define the function to initialize the SPI module for operation at a slow clock rate
#define FILEIO_SD_SPIInitialize_Slow FILEIO_SD_SPISlowInitialize
// Define the function to send a media command at a slow clock rate
#define FILEIO_SD_SendMediaCmd_Slow FILEIO_SD_SendCmd
// Define the function to write an SPI byte at a slow clock rate
#define FILEIO_SD_SPI_Put_Slow DRV_SPI_Put
// Define the function to read an SPI byte at a slow clock rate
#define FILEIO_SD_SPI_Get_Slow DRV_SPI_Get
#endif
// Define FILEIO_SD_CONFIG_MEDIA_SOFT_DETECT to enable soft detect of an SD card.
// Some connectors do not have a card detect pin and must use software to detect
// the presence of a card.
#define FILEIO_SD_CONFIG_MEDIA_SOFT_DETECT

View File

@ -0,0 +1,374 @@
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright 2015 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
//DOM-IGNORE-END
#include "FileSystem_config.h"
#include <stdint.h>
#include <stdbool.h>
/*****************************************************************/
/* Structures and defines */
/*****************************************************************/
#ifdef __XC8__
// Description: This macro is used to initialize a PIC18 SPI module with a 4x prescale divider
#define SYNC_MODE_FAST 0x00
// Description: This macro is used to initialize a PIC18 SPI module with a 16x prescale divider
#define SYNC_MODE_MED 0x01
// Description: This macro is used to initialize a PIC18 SPI module with a 64x prescale divider
#define SYNC_MODE_SLOW 0x02
#elif defined __XC32__
// Description: This macro is used to initialize a PIC32 SPI module
#define SYNC_MODE_FAST 0x3E
// Description: This macro is used to initialize a PIC32 SPI module
#define SYNC_MODE_SLOW 0x3C
#else
// Description: This macro indicates the SPI enable bit for 16-bit PICs
#ifndef MASTER_ENABLE_ON
#define MASTER_ENABLE_ON 0x0020
#endif
// Description: This macro is used to initialize a 16-bit PIC SPI module
#ifndef SYNC_MODE_FAST
#define SYNC_MODE_FAST 0x3E
#endif
// Description: This macro is used to initialize a 16-bit PIC SPI module
#ifndef SYNC_MODE_SLOW
#define SYNC_MODE_SLOW 0x3C
#endif
// Description: This macro is used to initialize a 16-bit PIC SPI module secondary prescaler
#ifndef SEC_PRESCAL_1_1
#define SEC_PRESCAL_1_1 0x001c
#endif
// Description: This macro is used to initialize a 16-bit PIC SPI module primary prescaler
#ifndef PRI_PRESCAL_1_1
#define PRI_PRESCAL_1_1 0x0003
#endif
#endif
// Description: This macro represents an SD card start single data block token (used for single block writes)
#define FILEIO_SD_DATA_START_TOKEN 0xFE
// Description: This macro represents an SD card start multi-block data token (used for multi-block writes)
#define FILEIO_SD_DATA_START_MULTI_BLOCK_TOKEN 0xFC
// Description: This macro represents an SD card stop transmission token. This is used when finishing a multi block write sequence.
#define FILEIO_SD_DATA_STOP_TRAN_TOKEN 0xFD
// Description: This macro represents an SD card data accepted token
#define FILEIO_SD_DATA_ACCEPTED 0x05
// Description: This macro indicates that the SD card expects to transmit or receive more data
#define FILEIO_SD_MORE_DATA_EXPECTED !0
// Description: This macro indicates that the SD card does not expect to transmit or receive more data
#define FILEIO_SD_NO_DATA_EXPECTED 0
// Description: This macro represents a floating SPI bus condition
#define FILEIO_SD_FLOATING_BUS_TOKEN 0xFF
// The SDMMC Commands
// Description: This macro defines the command code to reset the SD card
#define FILEIO_SD_COMMAND_GO_IDLE_STATE 0
// Description: This macro defines the command code to initialize the SD card
#define FILEIO_SD_COMMAND_SEND_OP_COND 1
// Description: This macro defined the command code to check for sector addressing
#define FILEIO_SD_COMMAND_SEND_IF_COND 8
// Description: This macro defines the command code to get the Card Specific Data
#define FILEIO_SD_COMMAND_SEND_CSD 9
// Description: This macro defines the command code to get the Card Information
#define FILEIO_SD_COMMAND_SEND_CID 10
// Description: This macro defines the command code to stop transmission during a multi-block read
#define FILEIO_SD_COMMAND_STOP_TRANSMISSION 12
// Description: This macro defines the command code to get the card status information
#define FILEIO_SD_COMMAND_SEND_STATUS 13
// Description: This macro defines the command code to set the block length of the card
#define FILEIO_SD_COMMAND_SET_BLOCK_LENGTH 16
// Description: This macro defines the command code to read one block from the card
#define FILEIO_SD_COMMAND_READ_SINGLE_BLOCK 17
// Description: This macro defines the command code to read multiple blocks from the card
#define FILEIO_SD_COMMAND_READ_MULTI_BLOCK 18
// Description: This macro defines the command code to tell the media how many blocks to pre-erase (for faster multi-block writes to follow)
//Note: This is an "application specific" command. This tells the media how many blocks to pre-erase for the subsequent WRITE_MULTI_BLOCK
#define FILEIO_SD_COMMAND_SET_WRITE_BLOCK_ERASE_COUNT 23
// Description: This macro defines the command code to write one block to the card
#define FILEIO_SD_COMMAND_WRITE_SINGLE_BLOCK 24
// Description: This macro defines the command code to write multiple blocks to the card
#define FILEIO_SD_COMMAND_WRITE_MULTI_BLOCK 25
// Description: This macro defines the command code to set the address of the start of an erase operation
#define FILEIO_SD_COMMAND_TAG_SECTOR_START 32
// Description: This macro defines the command code to set the address of the end of an erase operation
#define FILEIO_SD_COMMAND_TAG_SECTOR_END 33
// Description: This macro defines the command code to erase all previously selected blocks
#define FILEIO_SD_COMMAND_ERASE 38
//Description: This macro defines the command code to intitialize an SD card and provide the CSD register value.
//Note: this is an "application specific" command (specific to SD cards) and must be preceded by cmdAPP_CMD.
#define FILEIO_SD_COMMAND_SD_SEND_OP_COND 41
// Description: This macro defines the command code to begin application specific command inputs
#define FILEIO_SD_COMMAND_APP_CMD 55
// Description: This macro defines the command code to get the OCR register information from the card
#define FILEIO_SD_COMMAND_READ_OCR 58
// Description: This macro defines the command code to disable CRC checking
#define FILEIO_SD_COMMAND_CRC_ON_OFF 59
// Description: Enumeration of different SD response types
typedef enum
{
FILEIO_SD_RESPONSE_R1, // R1 type response
FILEIO_SD_RESPONSE_R1b, // R1b type response
FILEIO_SD_RESPONSE_R2, // R2 type response
FILEIO_SD_RESPONSE_R3, // R3 type response
FILEIO_SD_RESPONSE_R7 // R7 type response
}RESP;
// Summary: SD card command data structure
// Description: The FILEIO_SD_COMMAND structure is used to create a command table of information needed for each relevant SD command
typedef struct
{
uint8_t CmdCode; // The command code
uint8_t CRC; // The CRC value for that command
RESP responsetype; // The response type
uint8_t moredataexpected; // Set to MOREDATA or NODATA, depending on whether more data is expected or not
} FILEIO_SD_COMMAND;
// Summary: An SD command packet
// Description: This union represents different ways to access an SD card command packet
typedef union
{
// This structure allows array-style access of command uint8_ts
struct
{
#ifdef __XC8__
uint8_t field[6]; // uint8_t array
#else
uint8_t field[7];
#endif
};
// This structure allows uint8_t-wise access of packet command uint8_ts
struct
{
uint8_t crc; // The CRC uint8_t
#if defined __XC16__
uint8_t c30filler; // Filler space (since bitwise declarations can't cross a uint16_t boundary)
#elif defined __XC32__
uint8_t c32filler[3]; // Filler space (since bitwise declarations can't cross a uint32_t boundary)
#endif
uint8_t addr0; // Address uint8_t 0
uint8_t addr1; // Address uint8_t 1
uint8_t addr2; // Address uint8_t 2
uint8_t addr3; // Address uint8_t 3
uint8_t cmd; // Command code uint8_t
};
// This structure allows bitwise access to elements of the command uint8_ts
struct
{
uint8_t END_BIT:1; // Packet end bit
uint8_t CRC7:7; // CRC value
uint32_t address; // Address
uint8_t CMD_INDEX:6; // Command code
uint8_t TRANSMIT_BIT:1; // Transmit bit
uint8_t START_BIT:1; // Packet start bit
};
} FILEIO_SD_CMD_PACKET;
// Summary: The format of an R1 type response
// Description: This union represents different ways to access an SD card R1 type response packet.
typedef union
{
uint8_t _byte; // uint8_t-wise access
// This structure allows bitwise access of the response
struct
{
unsigned IN_IDLE_STATE:1; // Card is in idle state
unsigned ERASE_RESET:1; // Erase reset flag
unsigned ILLEGAL_CMD:1; // Illegal command flag
unsigned CRC_ERR:1; // CRC error flag
unsigned ERASE_SEQ_ERR:1; // Erase sequence error flag
unsigned ADDRESS_ERR:1; // Address error flag
unsigned PARAM_ERR:1; // Parameter flag
unsigned B7:1; // Unused bit 7
};
} FILEIO_SD_RESPONSE_1;
// Summary: The format of an R2 type response
// Description: This union represents different ways to access an SD card R2 type response packet
typedef union
{
uint16_t _uint16_t;
struct
{
uint8_t _byte0;
uint8_t _byte1;
};
struct
{
unsigned IN_IDLE_STATE:1;
unsigned ERASE_RESET:1;
unsigned ILLEGAL_CMD:1;
unsigned CRC_ERR:1;
unsigned ERASE_SEQ_ERR:1;
unsigned ADDRESS_ERR:1;
unsigned PARAM_ERR:1;
unsigned B7:1;
unsigned CARD_IS_LOCKED:1;
unsigned WP_ERASE_SKIP_LK_FAIL:1;
unsigned ERROR:1;
unsigned CC_ERROR:1;
unsigned CARD_ECC_FAIL:1;
unsigned WP_VIOLATION:1;
unsigned ERASE_PARAM:1;
unsigned OUTRANGE_CSD_OVERWRITE:1;
};
} FILEIO_SD_RESPONSE_2;
// Summary: The format of an R7 or R3 type response
// Description: This union represents different ways to access an SD card R7 type response packet.
typedef union
{
struct
{
uint8_t _byte; // byte-wise access
union
{
//Note: The SD card argument response field is 32-bit, big endian format.
//However, the C compiler stores 32-bit values in little endian in RAM.
//When writing to the _returnVal/argument bytes, make sure to byte
//swap the order from which it arrived over the SPI from the SD card.
uint32_t _returnVal;
struct
{
uint8_t _byte0;
uint8_t _byte1;
uint8_t _byte2;
uint8_t _byte3;
};
}argument;
} bytewise;
// This structure allows bitwise access of the response
struct
{
struct
{
unsigned IN_IDLE_STATE:1; // Card is in idle state
unsigned ERASE_RESET:1; // Erase reset flag
unsigned ILLEGAL_CMD:1; // Illegal command flag
unsigned CRC_ERR:1; // CRC error flag
unsigned ERASE_SEQ_ERR:1; // Erase sequence error flag
unsigned ADDRESS_ERR:1; // Address error flag
unsigned PARAM_ERR:1; // Parameter flag
unsigned B7:1; // Unused bit 7
}bits;
uint32_t _returnVal;
} bitwise;
} FILEIO_SD_RESPONSE_7;
// Summary: A union of responses from an SD card
// Description: The FILEIO_SD_RESPONSE union represents any of the possible responses that an SD card can return after
// being issued a command.
typedef union
{
FILEIO_SD_RESPONSE_1 r1;
FILEIO_SD_RESPONSE_2 r2;
FILEIO_SD_RESPONSE_7 r7;
}FILEIO_SD_RESPONSE;
// Description: A delay prescaler
#define FILEIO_SD_DELAY_PRESCALER (uint8_t)8
// Description: An approximation of the number of cycles per delay loop of overhead
#define FILEIO_SD_DELAY_OVERHEAD (uint8_t)5
// Description: An approximate calculation of how many times to loop to delay 1 ms in the Delayms function
#define FILEIO_SD_MILLISECOND_DELAY (uint16_t)((SYS_CLK_FrequencyInstructionGet()/FILEIO_SD_DELAY_PRESCALER/(uint16_t)1000) - FILEIO_SD_DELAY_OVERHEAD)
// Description: Media Response Delay Timeout Values
#define FILEIO_SD_NCR_TIMEOUT (uint16_t)20 //uint8_t times before command response is expected (must be at least 8)
#define FILEIO_SD_NAC_TIMEOUT (uint32_t)0x40000 //SPI uint8_t times we should wait when performing read operations (should be at least 100ms for SD cards)
#define FILEIO_SD_WRITE_TIMEOUT (uint32_t)0xA0000 //SPI uint8_t times to wait before timing out when the media is performing a write operation (should be at least 250ms for SD cards).
// Summary: An enumeration of SD commands
// Description: This enumeration corresponds to the position of each command in the sdmmc_cmdtable array
// These macros indicate to the FILEIO_SD_SendCmd function which element of the sdmmc_cmdtable array
// to retrieve command code information from.
typedef enum
{
FILEIO_SD_GO_IDLE_STATE,
FILEIO_SD_SEND_OP_COND,
FILEIO_SD_SEND_IF_COND,
FILEIO_SD_SEND_CSD,
FILEIO_SD_SEND_CID,
FILEIO_SD_STOP_TRANSMISSION,
FILEIO_SD_SEND_STATUS,
FILEIO_SD_SET_BLOCK_LENGTH,
FILEIO_SD_READ_SINGLE_BLOCK,
FILEIO_SD_READ_MULTI_BLOCK,
FILEIO_SD_WRITE_SINGLE_BLOCK,
FILEIO_SD_WRITE_MULTI_BLOCK,
FILEIO_SD_TAG_SECTOR_START,
FILEIO_SD_TAG_SECTOR_END,
FILEIO_SD_ERASE,
FILEIO_SD_APP_CMD,
FILEIO_SD_READ_OCR,
FILEIO_SD_CRC_ON_OFF,
FILEIO_SD_SD_SEND_OP_COND,
FILEIO_SD_SET_WRITE_BLOCK_ERASE_COUNT
} FILEIO_SD_COMMAND_INDEX;
#define FILEIO_SD_MODE_NORMAL 0
#define FILEIO_SD_MODE_HC 1
//Constants
#define FILEIO_SD_MEDIA_BLOCK_SIZE 512u //Should always be 512 for v1 and v2 devices.
#define FILEIO_SD_WRITE_RESPONSE_TOKEN_MASK 0x1F //Bit mask to AND with the write token response uint8_t from the media, to clear the don't care bits.
/***************************************************************************/
/* Macros */
/***************************************************************************/
// Description: A macro to send clock cycles to dummy-write the CRC
#define FILEIO_SD_CRCSend(i) DRV_SPI_Put(i,0xFF);DRV_SPI_Put(i,0xFF);
// Description: A macro to send 8 clock cycles for SD timing requirements
#define FILEIO_SD_Send8ClockCycles(i) DRV_SPI_Put(i,0xFF);
/*****************************************************************************/
/* Private Prototypes */
/*****************************************************************************/

View File

@ -0,0 +1,24 @@
#include <stdint.h>
#include <stdbool.h>
// The File I/O library requires the user to define the system clock frequency (Hz)
#define SYS_CLK_FrequencySystemGet() 32000000
// The File I/O library requires the user to define the peripheral clock frequency (Hz)
#define SYS_CLK_FrequencyPeripheralGet() SYS_CLK_FrequencySystemGet()
// The File I/O library requires the user to define the instruction clock frequency (Hz)
#define SYS_CLK_FrequencyInstructionGet() (SYS_CLK_FrequencySystemGet() / 2)
// System initialization function
void SYSTEM_Initialize (void);
// User-defined function to set the chip select for our example drive
void USER_SdSpiSetCs_1 (uint8_t a);
// User-defined function to get the card detection status for our example drive
uint8_t USER_SdSpiGetCd_1 (void);
// User-defined function to get the write-protect status for our example drive
uint8_t USER_SdSpiGetWp_1 (void);
// User-defined function to initialize tristate bits for CS, CD, and WP
void USER_SdSpiConfigurePins_1 (void);

View File

@ -0,0 +1,233 @@
/*******************************************************************************
* *
* 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. *
* *
*******************************************************************************/
/*---- example include file ---------------------------------------------------*/
#include "define.h"
#include "FlashInterface.h"
void InitFlashInterface(void)
{
}
//see section 5 of PIC32 manual
unsigned int FlashUnlock(unsigned int Operation)
{
//Setup operation to do
NVMCON = Operation;
int i =0;
for(i=0;i<500;i++)
Nop();
//Unlock
NVMKEY = 0xAA996655;
NVMKEY = 0x556699AA;
//Execute operation
NVMCONSET = 0x8000;
//Wait for it to finish
while(NVMCON & 0x8000);
Nop();
NVMCONCLR = 0x4000;
//Return NVMERR et LVDERR status bits
return (NVMCON & 0x3000);
}
unsigned int FlashProgramWord(void *Address, unsigned int DataWord)
{
unsigned int res;
//Load Data into NVMDATA register
NVMDATA = DataWord;
//Load Address (Physical address)
NVMADDR = KVA_TO_PA((unsigned int)Address);
//Unlock Flash and init operation
res = FlashUnlock(FLASH_PROGRAM_WORD_CMD);
return res;
}
unsigned int FlashProgramRow(void *Address, void *DataPtr)
{
unsigned int res;
//Load Address (Physical address)
NVMADDR = KVA_TO_PA((unsigned int)Address);
// Set pointer to data buffer
NVMSRCADDR = KVA_TO_PA((unsigned int)DataPtr);
//Unlock Flash and init operation
res = FlashUnlock(FLASH_PROGRAM_ROW_CMD);
return res;
}
unsigned int FlashProgramData(void *FlashStartAddress, unsigned int *DataPtr, unsigned int Size)
{
//The Size parameter is the number of WORDS.
unsigned int SizeInBytes = Size * 4;
void *CurFlashAddress;
unsigned int i;
unsigned int res = 0;
unsigned int curData;
curData = *DataPtr;
CurFlashAddress = FlashStartAddress;
//1 row = 512 bytes --> 0x80. We must always program an entire row (cannot start in the middle).
//if this happens, we must write words individually before and after the rows.
if(Size < FLASH_ROW_SIZE) //if we don't have enough data to fill a row, program words...
{
for(i = 0; i < Size; i++)
{
curData = *DataPtr++;
res |= FlashProgramWord(CurFlashAddress, curData /*DataPtr++*/);
CurFlashAddress+=4;
}
if(res)
return FLASH_STATUS_ERROR;
else
return FLASH_STATUS_OK;
}
else //we have at least 1 row
{
unsigned int NbRow;
NbRow = Size / FLASH_ROW_SIZE;
int ProgramFinished = 0;
do
{
//check if the start address is aligned with a row.
if((unsigned int)CurFlashAddress & 0x1FF) //data is misaligned. Write all words to the next row.
{
do
{
res |= FlashProgramWord(CurFlashAddress, *DataPtr++);
CurFlashAddress+=4;
Size--;
}
while(((unsigned int)CurFlashAddress & 0x1FF) && Size != 0);
}
else //data is aligned with the row.
{
if(Size % FLASH_ROW_SIZE == 0) //we have an integer number of rows. Program all of them and return.
{
for(i = 0; i < NbRow; i++)
{
res |= FlashProgramRow(CurFlashAddress, (void*)DataPtr);
CurFlashAddress += FLASH_ROW_SIZE_IN_BYTES;
DataPtr += FLASH_ROW_SIZE;
}
if(res)
return FLASH_STATUS_ERROR;
else
return FLASH_STATUS_OK;
}
else //non integer number of rows...
{
res |= FlashProgramRow(CurFlashAddress, (void*)DataPtr);
CurFlashAddress += FLASH_ROW_SIZE_IN_BYTES;
DataPtr += FLASH_ROW_SIZE;
Size -= FLASH_ROW_SIZE;
}
}
if(Size < FLASH_ROW_SIZE) //if we don't have enough data to fill a row, program words...
{
for(i = 0; i < Size; i++)
{
res |= FlashProgramWord(CurFlashAddress, *DataPtr++);
CurFlashAddress+=4;
}
if(res)
return FLASH_STATUS_ERROR;
else
return FLASH_STATUS_OK;
}
if(Size == 0)
{
if(res)
return FLASH_STATUS_ERROR;
else
return FLASH_STATUS_OK;
}
}
while(1);
}
}
unsigned int FlashErase(void)
{
unsigned int res = 0;
unsigned int i;
void* PageAddress;
PageAddress = (void*)APPLICATION_FLASH_START_ADDRESS;
for(i = 0; i < FLASH_NB_APPLICATION_PAGES; i++)
{
res |= FlashErasePage(PageAddress);
if(res)
{
int page = PageAddress;
}
PageAddress += FLASH_PAGE_SIZE_IN_BYTES;
}
if(res)
return FLASH_STATUS_ERROR;
else
return FLASH_STATUS_OK;
}
unsigned int FlashErasePage(void *Address)
{
unsigned int res;
NVMADDR = KVA_TO_PA((unsigned int)Address);
res = FlashUnlock(FLASH_PAGE_ERASE_CMD);
return res;
}
//EOF

View File

@ -0,0 +1,58 @@
#ifndef FLASH_INTERFACE_H
#define FLASH_INTERFACE_H
#include "define.h" //for CPU selection
#define APPLICATION_START_ADDRESS 0x9D003000
#define APPLICATION_FLASH_START_ADDRESS 0x9D002000
#define FLASH_ROW_SIZE 128
#define FLASH_ROW_SIZE_IN_BYTES (4 * FLASH_ROW_SIZE) //512
#define FLASH_PAGE_SIZE (8 * FLASH_ROW_SIZE) //1024
#define FLASH_PAGE_SIZE_IN_BYTES (4 * FLASH_PAGE_SIZE) //4096
//The number of pages of application program flash
#ifdef USE_675F512_CPU
#define FLASH_NB_APPLICATION_PAGES (0x40000 / FLASH_PAGE_SIZE_IN_BYTES) - 2 //0x40000 is the size of the flash (32MX675F512L), the 2 first pages are reserved for bootloader. (-2)
#else
#define FLASH_NB_APPLICATION_PAGES (0x80000 / FLASH_PAGE_SIZE_IN_BYTES) - 2 //0x80000 is the size of the flash (32MX795F512L), the 2 first pages are reserved for bootloader. (-2)
#endif
#define PROGRAM_FLASH_BEGIN_ADDRESS 0x1D000000
#define PROGRAM_FLASH_END_ADDRESS 0x1D07FFFF
enum eFlashOperations
{
FLASH_NOP_CMD = 0X0000,
FLASH_PROGRAM_WORD_CMD = 0x4001,
FLASH_PROGRAM_ROW_CMD = 0x4003,
FLASH_PAGE_ERASE_CMD = 0x4004,
FLASH_ERASE_CMD = 0x4005
};
enum eFlashReturnValues
{
FLASH_STATUS_OK,
FLASH_STATUS_ERROR
};
void InitFlashInterface(void);
unsigned int FlashErase(void);
unsigned int FlashErasePage(void *Address);
unsigned int FlashUnlock(unsigned int Operation);
unsigned int FlashProgramWord(void *Address, unsigned int DataWord);
unsigned int FlashProgramRow(void *Address, void *DataPtr);
unsigned int FlashProgramData(void *FlashStartAddress, unsigned int *DataPtr, unsigned int Size);
#endif
//EOF

View File

@ -0,0 +1,656 @@
/*******************************************************************************
* *
* 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 "BootloaderProtocol.h"
//#include <stdio.h>
/* ************************************************************************** */
/* Local variables */
//char IntUartTxBuff[MAX_INTERNAL_UART_PORT][INTERNAL_UART_BUFFER_DEPTH]; //Tx Buffers
//char acIntUartRxBuff[INTERNAL_UART_BUFFER_DEPTH]; //Rx Buffers
stInternalUartData astInternalUartData; //port management data
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void InternalUartInit(void)
{
#ifdef USE_SERIAL_PORT_1
//Setup port 1A
//
U1STA = 0;
U1STAbits.UTXEN = 1; //enable transmitter
IPC6bits.U1IP = 5; //priority 5 //NOT USED
IPC6bits.U1IS = 2; //sub-priority 2 //NOT USED
U1STAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
IFS0bits.U1TXIF = 0; //clear interrupt flag
IEC0bits.U1TXIE = 0; //disable tx interrupt
U1STAbits.URXISEL = 0b00; //interrupt for each character received
IFS0bits.U1RXIF = 0;
IEC0bits.U1RXIE = 0; //disable rx interrupts
U1STAbits.URXEN = 1; //enable receiver
U1MODEbits.ON = 0; //disable module
#endif
#ifdef USE_SERIAL_PORT_2
//Setup port 1B
//
U2STA = 0;
U2STAbits.UTXEN = 1; //enable transmitter
IPC8bits.U2IP = 5; //priority 5 //NOT USED
IPC8bits.U2IS = 2; //sub-priority 2 //NOT USED
U2STAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
IFS1bits.U2TXIF = 0; //clear interrupt flag
IEC1bits.U2TXIE = 0; //disable tx interrupt
U2STAbits.URXISEL = 0b00; //interrupt for each character received
IFS1bits.U2RXIF = 0;
IEC1bits.U2RXIE = 0; //disable rx interrupts
U2STAbits.URXEN = 1; //enable receiver
U2MODEbits.ON = 0; //disable module
#endif
//
//#ifdef USE_SERIAL_PORT_1A
// //Setup port 1A
// //
// U1ASTA = 0;
// U1ASTAbits.UTXEN = 1; //enable transmitter
// IPC6bits.U1AIP = 5; //priority 5
// IPC6bits.U1AIS = 2; //sub-priority 2
// U1ASTAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
// IFS0bits.U1ATXIF = 0; //clear interrupt flag
// IEC0bits.U1ATXIE = 0; //disable tx interrupt
// U1ASTAbits.URXISEL = 0b00; //interrupt for each character received
// IFS0bits.U1ARXIF = 0;
// IEC0bits.U1ARXIE = 0; //disable rx interrupts
// U1ASTAbits.URXEN = 1; //enable receiver
// U1AMODEbits.ON = 0; //disable module
//
//#endif
//#ifdef USE_SERIAL_PORT_1B
// //Setup port 1B
// //
// U1BSTA = 0;
// U1BSTAbits.UTXEN = 1; //enable transmitter
// IPC12bits.U1BIP = 5; //priority 5
// IPC12bits.U1BIS = 2; //sub-priority 2
// U1BSTAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
// IFS2bits.U1BTXIF = 0; //clear interrupt flag
// IEC2bits.U1BTXIE = 0; //disable tx interrupt
// U1BSTAbits.URXISEL = 0b00; //interrupt for each character received
// IFS2bits.U1BRXIF = 0;
// IEC2bits.U1BRXIE = 0; //disable rx interrupts
// U1BSTAbits.URXEN = 1; //enable receiver
// U1BMODEbits.ON = 0; //disable module
//#endif
//
//#ifdef USE_SERIAL_PORT_2A
// //Setup port 2A
// //
// U2ASTA = 0;
// U2ASTAbits.UTXEN = 1; //enable transmitter
// IPC7bits.U2AIP = 5; //priority 5
// IPC7bits.U2AIS = 2; //sub-priority 2
// U2ASTAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
// IFS1bits.U2ATXIF = 0; //clear interrupt flag
// IEC1bits.U2ATXIE = 0; //disable tx interrupt
// U2ASTAbits.URXISEL = 0b00; //interrupt for each character received
// IFS1bits.U2ARXIF = 0;
// IEC1bits.U2ARXIE = 0; //disable rx interrupts
// U2ASTAbits.URXEN = 1; //enable receiver
// U2AMODEbits.ON = 0; //disable module
//#endif
//
//#ifdef USE_SERIAL_PORT_2B
//
// //Setup port 2B
// //
// U2BSTA = 0;
// U2BSTAbits.UTXEN = 1; //enable transmitter
// IPC12bits.U2BIP = 5; //priority 5
// IPC12bits.U2BIS = 2; //sub-priority 2
// U2BSTAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
// IFS2bits.U2BTXIF = 0; //clear interrupt flag
// IEC2bits.U2BTXIE = 0; //disable tx interrupt
// U2BSTAbits.URXISEL = 0b00; //interrupt for each character received
// IFS2bits.U2BRXIF = 0;
// IEC2bits.U2BRXIE = 0; //disable rx interrupts
// U2BSTAbits.URXEN = 1; //enable receiver
// U2BMODEbits.ON = 0; //disable module
//#endif
//
//#ifdef USE_SERIAL_PORT_3A
//
// //Setup port 3A
// //
// U3ASTA = 0;
// U3ASTAbits.UTXEN = 1; //enable transmitter
// IPC8bits.U3AIP = 5; //priority 5
// IPC8bits.U3AIS = 2; //sub-priority 2
// U3ASTAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
// IFS1bits.U3ATXIF = 0; //clear interrupt flag
// IEC1bits.U3ATXIE = 0; //disable tx interrupt
// U3ASTAbits.URXISEL = 0b00; //interrupt for each character received
// IFS1bits.U3ARXIF = 0; //clear interrupt flag
// IEC1bits.U3ARXIE = 0; //disable tx interrupt
// U3ASTAbits.URXEN = 1; //enable receiver
// U3AMODEbits.ON = 0; //disable module
//#endif
//
//#ifdef USE_SERIAL_PORT_3B
// //Setup port 3B
// //
// U3BSTA = 0;
// U3BSTAbits.UTXEN = 1; //enable transmitter
// IPC12bits.U3BIP = 5; //priority 5
// IPC12bits.U3BIS = 2; //sub-priority 2
// U3BSTAbits.UTXSEL = 0b01; //interrupt when all characters are transmitted
// IFS2bits.U3BTXIF = 0; //clear interrupt flag
// IEC2bits.U3BTXIE = 0; //disable tx interrupt
// U3BSTAbits.URXISEL = 0b00; //interrupt for each character received
// IFS2bits.U3BRXIF = 0; //clear interrupt flag
// IEC2bits.U3BRXIE = 0; //disable rx interrupt
// U3BSTAbits.URXEN = 1; //enable receiver
// U3BMODEbits.ON = 0; //disable module
//#endif
//
astInternalUartData.pcTxDataPtr = 0;
astInternalUartData.pcTxCircBufferTail = 0;
astInternalUartData.pcTxCircBufferHead = 0;
astInternalUartData.iTxDataSize = 0;
astInternalUartData.iTxDataCounter = 0;
astInternalUartData.iIsBusy = 0;
astInternalUartData.iIsOpened = 0;
astInternalUartData.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_1A:
{
if(p_iTxInterrupt)
{
IFS0bits.U1ATXIF = 0; //clear interrupt flag
IEC0bits.U1ATXIE = 1; //enable tx interrupt
}
else
{
IEC0bits.U1ATXIE = 0; //disable tx interrupt
U1ASTAbits.UTXEN = 1; //This bit must be set when working without interrupts
}
if(p_iRxInterrupt)
{
IFS0bits.U1ARXIF = 0;
IEC0bits.U1ARXIE = 1; //enable rx interrupt
}
else
{
IEC0bits.U1ARXIE = 0; //disable rx interrupt
}
break;
}
case INTERNAL_UART_PORT_1B:
{
if(p_iTxInterrupt)
{
IFS2bits.U1BTXIF = 0; //clear interrupt flag
IEC2bits.U1BTXIE = 1; //enable tx interrupt
}
else
{
IEC2bits.U1BTXIE = 0; //disable tx interrupt
U1BSTAbits.UTXEN = 1; //This bit must be set when working without interrupts
}
if(p_iRxInterrupt)
{
IFS2bits.U1BRXIF = 0;
IEC2bits.U1BRXIE = 1; //enable rx interrupt
}
else
{
IEC2bits.U1BRXIE = 0; //disable rx interrupt
}
break;
}
case INTERNAL_UART_PORT_2A:
{
if(p_iTxInterrupt)
{
IFS1bits.U2ATXIF = 0; //clear interrupt flag
IEC1bits.U2ATXIE = 1; //enable tx interrupt
}
else
{
IEC1bits.U2ATXIE = 0; //disable tx interrupt
U2ASTAbits.UTXEN = 1; //This bit must be set when working without interrupts
}
if(p_iRxInterrupt)
{
IFS1bits.U2ARXIF = 0;
IEC1bits.U2ARXIE = 1; //enable rx interrupt
}
else
{
IEC1bits.U2ARXIE = 0; //disable rx interrupt
}
break;
}
case INTERNAL_UART_PORT_2B:
{
if(p_iTxInterrupt)
{
IFS2bits.U2BTXIF = 0; //clear interrupt flag
IEC2bits.U2BTXIE = 1; //enable tx interrupt
}
else
{
IEC2bits.U2BTXIE = 0; //disable tx interrupt
U2ASTAbits.UTXEN = 1; //This bit must be set when working without interrupts
}
if(p_iRxInterrupt)
{
IFS2bits.U2BRXIF = 0;
IEC2bits.U2BRXIE = 1; //enable rx interrupt
}
else
{
IEC2bits.U2BRXIE = 0; //disable rx interrupt
}
break;
}
case INTERNAL_UART_PORT_3A:
{
if(p_iTxInterrupt)
{
IFS1bits.U3ATXIF = 0; //clear interrupt flag
IEC1bits.U3ATXIE = 1; //enable tx interrupt
}
else
{
IEC1bits.U3ATXIE = 0; //disable tx interrupt
U3ASTAbits.UTXEN = 1; //This bit must be set when working without interrupts
}
if(p_iRxInterrupt)
{
IFS1bits.U3ARXIF = 0; //clear interrupt flag
IEC1bits.U3ARXIE = 1; //enable tx interrupt
}
else
{
IEC1bits.U3ARXIE = 0; //disable rx interrupt
}
break;
}
case INTERNAL_UART_PORT_3B:
{
if(p_iTxInterrupt)
{
IFS2bits.U3BTXIF = 0; //clear interrupt flag
IEC2bits.U3BTXIE = 1; //enable tx interrupt
}
else
{
IEC2bits.U3BTXIE = 0; //disable tx interrupt
U3BSTAbits.UTXEN = 1; //This bit must be set when working without interrupts
}
if(p_iRxInterrupt)
{
IFS2bits.U3BRXIF = 0; //clear interrupt flag
IEC2bits.U3BRXIE = 1; //enable tx interrupt
}
else
{
IEC2bits.U3BRXIE = 0; //disable rx interrupt
}
break;
}
default:
{
return UART_INVALID_PORT;
}
}
return UART_OK;
} */
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int OpenInternalPort(char *p_pcHeadPtr, char *p_pcTailPtr, int p_iBaudRate, int p_iNbStopBits, int p_iParityEnable)
{
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.iUartHandle = p_iUartHandle;
astInternalUartData.pcTxCircBufferTail = p_pcTailPtr;
astInternalUartData.pcTxCircBufferHead = p_pcHeadPtr;
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;
}
}
#ifdef USE_SERIAL_PORT_1
{
U1MODE = iMask;
U1MODEbits.BRGH = 1;
U1BRG = iBRG;
U1MODEbits.ON = 1; //enable module
}
#endif
#ifdef USE_SERIAL_PORT_2
{
U2MODE = iMask;
U2MODEbits.BRGH = 1;
U2BRG = iBRG;
U2MODEbits.ON = 1; //enable module
}
#endif
//#ifdef USE_SERIAL_PORT_1A
// {
// U1AMODE = iMask;
// U1AMODEbits.BRGH = 1;
// U1ABRG = iBRG;
// U1AMODEbits.ON = 1; //enable module
// }
//#endif
//#ifdef USE_SERIAL_PORT_1B
// {
// U1BMODE = iMask;
// U1BMODEbits.BRGH = 1;
// U1BBRG = iBRG;
// U1BMODEbits.ON = 1; //enable module
// }
//#endif
//#ifdef USE_SERIAL_PORT_2A
// {
// U2AMODE = iMask;
// U2AMODEbits.BRGH = 1;
// U2ABRG = iBRG;
// U2AMODEbits.ON = 1; //enable module
// }
//#endif
//#ifdef USE_SERIAL_PORT_2B
// {
// U2BMODE = iMask;
// U2BMODEbits.BRGH = 1;
// U2BBRG = iBRG;
// U2BMODEbits.ON = 1; //enable module
// }
//#endif
//#ifdef USE_SERIAL_PORT_3A
// {
// U3AMODE = iMask;
// U3AMODEbits.BRGH = 1;
// U3ABRG = iBRG;
// U3AMODEbits.ON = 1; //enable module
// }
//#endif
//#ifdef USE_SERIAL_PORT_3B
// {
// U3BMODE = iMask;
// U3BMODEbits.BRGH = 1;
// U3BBRG = iBRG;
// U3BMODEbits.ON = 1; //enable module
// }
//#endif
astInternalUartData.iIsOpened = 1;
return UART_OK;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int SendInternalUartData(char *p_pcDataBuf, int p_iDataSize)
{
int i;
if(astInternalUartData.iIsOpened == 0)
return UART_PORT_NOT_OPENED;
if(astInternalUartData.iIsBusy)
return UART_PORT_BUSY;
astInternalUartData.pcTxDataPtr = p_pcDataBuf;
astInternalUartData.iTxDataSize = p_iDataSize;
astInternalUartData.iTxDataCounter = 0;
astInternalUartData.iIsBusy = 0;
for(i = 0; i < p_iDataSize; i++)
{
#ifdef USE_SERIAL_PORT_1
U1TXREG = *p_pcDataBuf++;
while(U1STAbits.TRMT == 0);
#endif
#ifdef USE_SERIAL_PORT_2
U2TXREG = *p_pcDataBuf++;
while(U2STAbits.TRMT == 0);
#endif
// #ifdef USE_SERIAL_PORT_1A
// U1ATXREG = *p_pcDataBuf++;
// while(U1ASTAbits.TRMT == 0);
// #endif
// #ifdef USE_SERIAL_PORT_1B
// U1BTXREG = *p_pcDataBuf++;
// while(U1BSTAbits.TRMT == 0);
// #endif
// #ifdef USE_SERIAL_PORT_2A
// U2ATXREG = *p_pcDataBuf++;
// while(U2ASTAbits.TRMT == 0);
// #endif
// #ifdef USE_SERIAL_PORT_2B
// U2BTXREG = *p_pcDataBuf++;
// while(U2BSTAbits.TRMT == 0);
// #endif
// #ifdef USE_SERIAL_PORT_3A
// U3ATXREG = *p_pcDataBuf++;
// while(U3ASTAbits.TRMT == 0);
// #endif
// #ifdef USE_SERIAL_PORT_3B
// U3BTXREG = *p_pcDataBuf++;
// while(U3BSTAbits.TRMT == 0);
// #endif
}
return UART_OK;
}
int ReadInternalUart(void)
{
int count = 0;
char byte;
#ifdef USE_SERIAL_PORT_1
while(U1STAbits.URXDA == 1)
{
byte = U1RXREG;
ProtocolRxData(byte);
count++;
}
#endif
#ifdef USE_SERIAL_PORT_2
while(U2STAbits.URXDA == 1)
{
byte = U2RXREG;
ProtocolRxData(byte);
count++;
}
#endif
// #ifdef USE_SERIAL_PORT_1A
// while(U1ASTAbits.URXDA == 1)
// {
// byte = U1ARXREG;
// ProtocolRxData(byte);
// count++;
// }
// #endif
// #ifdef USE_SERIAL_PORT_1B
// while(U1BSTAbits.URXDA == 1)
// {
// byte = U1BRXREG;
// ProtocolRxData(byte);
// count++;
// }
// #endif
// #ifdef USE_SERIAL_PORT_2A
// while(U2ASTAbits.URXDA == 1)
// {
// byte = U2ARXREG;
// ProtocolRxData(byte);
// count++;
// }
// #endif
// #ifdef USE_SERIAL_PORT_2B
// while(U2BSTAbits.URXDA == 1)
// {
// byte = U2BRXREG;
// ProtocolRxData(byte);
// count++;
// }
// #endif
// #ifdef USE_SERIAL_PORT_3A
// while(U3ASTAbits.URXDA == 1)
// {
// byte = U3ARXREG;
// ProtocolRxData(byte);
// count++;
// }
// #endif
// #ifdef USE_SERIAL_PORT_3B
// while(U3BSTAbits.URXDA == 1)
// {
// byte = U3BRXREG;
// ProtocolRxData(byte);
// count++;
// }
// #endif
return count;
}
void CloseInternalUart(void)
{
#ifdef USE_SERIAL_PORT_1
U1MODEbits.ON = 0; //disable module
U1STA = 0;
#endif
#ifdef USE_SERIAL_PORT_2
U2MODEbits.ON = 0; //disable module
U2STA = 0;
#endif
// #ifdef USE_SERIAL_PORT_1A
// U1AMODEbits.ON = 0; //disable module
// U1ASTA = 0;
// #endif
// #ifdef USE_SERIAL_PORT_1B
// U1BMODEbits.ON = 0; //disable module
// U1BSTA = 0;
// #endif
// #ifdef USE_SERIAL_PORT_2A
// U2AMODEbits.ON = 0; //disable module
// U2ASTA = 0;
// #endif
// #ifdef USE_SERIAL_PORT_2B
// U2BMODEbits.ON = 0; //disable module
// U2BSTA = 0;
// #endif
// #ifdef USE_SERIAL_PORT_3A
// U3AMODEbits.ON = 0; //disable module
// U3ASTA = 0;
// #endif
// #ifdef USE_SERIAL_PORT_3B
// U3BMODEbits.ON = 0; //disable module
// U3BSTA = 0;
// #endif
}
//EOF

View File

@ -0,0 +1,95 @@
/*******************************************************************************
* *
* 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 16
#define USE_TX_INTERNAL_BUFFER
/* ************************************************************************** */
/* Type definitions */
/*typedef enum
{
INTERNAL_UART_PORT_1A,
INTERNAL_UART_PORT_1B,
INTERNAL_UART_PORT_2A,
INTERNAL_UART_PORT_2B,
INTERNAL_UART_PORT_3A,
INTERNAL_UART_PORT_3B,
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 *pcTxCircBufferTail;
char *pcTxCircBufferHead;
int iTxDataSize;
int iTxDataCounter;
int iIsBusy;
int iIsOpened;
int iUartHandle;
}stInternalUartData;
/* ************************************************************************** */
/* Prototypes */
void InternalUartInit(void);
int OpenInternalPort(char *p_pcHeadPtr, char *p_pcTailPtr, int p_iBaudRate, int p_iNbStopBits, int p_iParityEnable);
int SendInternalUartData(char *p_pcDataBuf, int p_iDataSize);
int ReadInternalUart(void);
void CloseInternalUart(void);
#endif
//EOF

Binary file not shown.

View File

@ -0,0 +1,116 @@
#include "SDCardMgr.h"
#include "sd_hw_ctl.h"
#include "FileSystem/fileio_lfn.h"
#include <stdio.h>
#include "timer.h"
int mSDCardState;
int mCardDetected;
int mCardMounted;
uint16_t mDriveLetter;
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;
}

View File

@ -0,0 +1,37 @@
/*
* File: SDCardMgr.h
* Author: JF
*
* Created on May 18, 2017, 8:20 PM
*/
#ifndef SDCARDMGR_H
#define SDCARDMGR_H
#include "FileSystem/fileio_lfn.h"
enum eSDCardStates
{
SD_CARD_INIT_STATE,
SD_CARD_MOUNT_DRIVE_STATE,
SD_CARD_READY_STATE,
SD_CARD_ERROR_MOUNTING_STATE
};
void FILEIO_GetTimestamp(FILEIO_TIMESTAMP * timeStamp);
//void FILEIO_SETUP_HW();
int InitSDCard();
int MountDrive();
int IsDriveDetected();
int IsDriveMounted();
int TickSDCard();
//void FILEIO_
#endif /* SDCARDMGR_H */

View File

@ -0,0 +1,17 @@
#include "define.h"
#include "DigitalIO.h"
#include "SPI.h"
unsigned char SPITransaction(unsigned char OutBuf)
{
WIFI_SPI_SS_PIN = 0;
SPI2BUF = OutBuf;
while(!SPI2STATbits.SPIRBF);
OutBuf = SPI2BUF;
WIFI_SPI_SS_PIN = 1;
return OutBuf;
}

View 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);
#endif /* SPI_H */

View File

@ -0,0 +1,104 @@
/*******************************************************************************
* *
* 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 1024
#define UART_MAX_TX_BUFF_SIZE 1024
//#define UART_SET_FLAG_ON_SEND
/* ************************************************************************** */
/* 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 0 to 6 is mapped to P2 connector
UART_0, //(422)
UART_1, //(422)
UART_2, //(422)
UART_3, //(422)
UART_4, //(232)
UART_5, //(232)
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 acRxBuffer[UART_MAX_RX_BUFF_SIZE];
}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);
#endif
//EOF

View File

@ -0,0 +1,554 @@
#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 "DigitalIO.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"));
}
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;
}
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;
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 *)&param, 0, sizeof(tstrWifiInitParam));
/* Initialize Wi-Fi driver with data and status callbacks. */
param.pfAppWifiCb = wifi_cb;
ret = m2m_wifi_init(&param);
if (M2M_SUCCESS != ret)
{
mWiFiInitOK = false;
mWiFiState = WIFI_INIT_ERROR_STATE;
return RET_ERROR;
}
mWiFiInitOK = true;
mWiFiState = WIFI_DISCONNECTED_STATE;
socketInit();
registerSocketCallback(socket_cb, resolve_cb);
//Get MAC address from the module
m2m_wifi_get_otp_mac_address(mac_addr, &u8IsMacAddrValid);
if (!u8IsMacAddrValid) {
m2m_wifi_set_mac_address(gau8MacAddr);
}
//Get the working MAC address from driver.
m2m_wifi_get_mac_address(gau8MacAddr);
//Initialize the human readable MAC address based on the working MAC
set_dev_name_to_mac((uint8 *)gacDeviceName, gau8MacAddr);
//Use the MAC to define the SSID of the module
set_dev_name_to_mac((uint8 *)gstrM2MAPConfig.au8SSID, gau8MacAddr);
m2m_wifi_set_device_name((uint8 *)gacDeviceName, (uint8)m2m_strlen((uint8 *)gacDeviceName));
#ifdef USE_STATIC_IP
//Use static ip --> disable dhcp client before connecting
m2m_wifi_enable_dhcp(0);
#endif
if(m2m_wifi_connect(HOME_AP_NAME,sizeof(HOME_AP_NAME),HOME_AP_SEC_TYPE,HOME_AP_PWD,M2M_WIFI_CH_ALL) != M2M_SUCCESS)
{
//wifi connect error...
printf("error");
}
tstrPerphInitParam tst;
m2m_periph_init(&tst);
//Set all IOs as inputs except the LED (IO3)..
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO3,1);
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO4,0);
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO5,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_GPIO5,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;
m2m_wifi_disconnect();
m2m_wifi_deinit(&shit);
CloseSockets();
socketDeinit();
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_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);
}
}
m2m_wifi_handle_events(NULL);
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

View File

@ -0,0 +1,200 @@
/*
* 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"
enum eWiFiState
{
WIFI_MODULE_OFF_STATE = 0,
WIFI_CONNECTED_STATE,
WIFI_DISCONNECTED_STATE,
WIFI_INIT_ERROR_STATE,
WIFI_UNKNOWN_STATE
};
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 "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 >>>
//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 125
#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 */

View File

@ -0,0 +1,57 @@
/*******************************************************************************
* *
* 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.
*/
#ifndef DEFINE_H
#define DEFINE_H
/* ************************************************************************** */
/* Includes */
#include <plib.h>
//#include "CUHelperFcns.h"
/* ************************************************************************** */
/* Defines */
#define SYS_FREQ (77824000L)
#define PERIPHERAL_FREQ (77824000L)
#define PIN_INPUT 1
#define PIN_OUTPUT 0
#define false 0
#define true 1
#define MSB8(x) ((x >> 8) & 0xFF)
#define LSB8(x) (x & 0xFF)
#define USE_BLOCKING_PRINTF
#define NO_EXTERNAL_UART
#define USE_675F512_CPU //For prototype board, 795F512 CPUs were backordered.
/* ************************************************************************** */
/* Type definitions */
//typedef int bool;
typedef int Bool;
#define RET_OK 1
#define RET_ERROR 0
//Only uncomment 1 serial port !!! (otherwise you will have a bad day :)
//#define USE_SERIAL_PORT_1
#define USE_SERIAL_PORT_2
#endif
//EOF

View File

@ -0,0 +1,237 @@
/* This linker script is modified for boot loader. removes irq table */
/* Do not use in normal app */
OUTPUT_FORMAT("elf32-tradlittlemips")
OUTPUT_ARCH(pic32mx)
ENTRY(_reset)
/*
* Provide for a minimum stack and heap size
* - _min_stack_size - represents the minimum space that must be made
* available for the stack. Can be overridden from
* the command line using the linker's --defsym option.
* - _min_heap_size - represents the minimum space that must be made
* available for the heap. Can be overridden from
* the command line using the linker's --defsym option.
*/
EXTERN (_min_stack_size _min_heap_size)
PROVIDE(_min_stack_size = 0x400) ;
PROVIDE(_min_heap_size = 0) ;
INCLUDE procdefs.ld
SECTIONS
{
/* Boot Sections */
.reset _RESET_ADDR :
{
KEEP(*(.reset))
} > kseg1_boot_mem
.bev_excpt _BEV_EXCPT_ADDR :
{
KEEP(*(.bev_handler))
} > kseg1_boot_mem
.dbg_excpt _DBG_EXCPT_ADDR (NOLOAD) :
{
. += (DEFINED (_DEBUGGER) ? 0x8 : 0x0);
} > kseg1_boot_mem
.dbg_code _DBG_CODE_ADDR (NOLOAD) :
{
. += (DEFINED (_DEBUGGER) ? 0xFF0 : 0x0);
} > debug_exec_mem
.app_excpt _GEN_EXCPT_ADDR :
{
KEEP(*(.gen_handler))
} > exception_mem
.startup ORIGIN(kseg0_boot_mem) :
{
KEEP(*(.startup))
} > kseg0_boot_mem
/* Code Sections */
.text ORIGIN(kseg0_program_mem) :
{
_text_begin = . ;
*(.text .stub .text.* .gnu.linkonce.t.*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.mips16.fn.*)
*(.mips16.call.*)
_text_end = . ;
} >kseg0_program_mem =0
/* ASSERT(SIZEOF(.C32_EDITION_LIMITED_TO_64KB_EVALUATION) < (LENGTH(kseg0_program_mem) - (SIZEOF(.text)+SIZEOF(.rodata)+SIZEOF(.sdata2)+SIZEOF(.sbss2)+SIZEOF(.data)+SIZEOF(.got)+SIZEOF(.sdata)+SIZEOF(.lit8)+SIZEOF(.lit4)+SIZEOF(.ramfunc))), "HINT: This application may be too large for this 64KB-limited edition of the MPLAB C32 Compiler. Visit http://www.microchip.com/c32 to upgrade to full version.")*/
/* ASSERT(SIZEOF(.C32_EDITION_LIMITED_TO_16KB_EVALUATION) < (LENGTH(kseg0_program_mem) - (SIZEOF(.text)+SIZEOF(.rodata)+SIZEOF(.sdata2)+SIZEOF(.sbss2)+SIZEOF(.data)+SIZEOF(.got)+SIZEOF(.sdata)+SIZEOF(.lit8)+SIZEOF(.lit4)+SIZEOF(.ramfunc))), "HINT: This application may be too large for this 16KB-limited edition of the MPLAB C32 Compiler. Visit http://www.microchip.com/c32 to upgrade to full version.")*/
/* ASSERT(SIZEOF(.C32_EDITION_SIZELIMITED_EVALUATION) < (LENGTH(kseg0_program_mem) - (SIZEOF(.text)+SIZEOF(.rodata)+SIZEOF(.sdata2)+SIZEOF(.sbss2)+SIZEOF(.data)+SIZEOF(.got)+SIZEOF(.sdata)+SIZEOF(.lit8)+SIZEOF(.lit4)+SIZEOF(.ramfunc))), "HINT: This application may be too large for this size-limited edition of the MPLAB C32 Compiler. Visit http://www.microchip.com/c32 to upgrade to full version.")*/
/* Read-only sections */
.rodata :
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
. = ALIGN(32 / 8) ;
} >kseg0_program_mem
/*
* Small initialized constant global and static data can be placed in the
* .sdata2 section. This is different from .sdata, which contains small
* initialized non-constant global and static data.
*/
.sdata2 :
{
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
. = ALIGN(32 / 8) ;
} >kseg0_program_mem
/*
* Uninitialized constant global and static data (i.e., variables which will
* always be zero). Again, this is different from .sbss, which contains
* small non-initialized, non-constant global and static data.
*/
.sbss2 :
{
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
. = ALIGN(32 / 8) ;
} >kseg0_program_mem
.eh_frame_hdr : { *(.eh_frame_hdr) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
.dbg_data (NOLOAD) :
{
. += (DEFINED (_DEBUGGER) ? 0x200 : 0x0);
} >kseg1_data_mem
.data :
{
_data_begin = . ;
*(.data .data.* .gnu.linkonce.d.*)
KEEP (*(.gnu.linkonce.d.*personality*))
*(.data1)
} >kseg1_data_mem AT>kseg0_program_mem
_data_image_begin = LOADADDR(.data) ;
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
_gp = ALIGN(16) + 0x7FF0 ;
.got :
{
*(.got.plt) *(.got)
} >kseg1_data_mem AT>kseg0_program_mem
/*
* We want the small data sections together, so single-instruction offsets
* can access them all, and initialized data all before uninitialized, so
* we can shorten the on-disk segment size.
*/
.sdata :
{
_sdata_begin = . ;
*(.sdata .sdata.* .gnu.linkonce.s.*)
_sdata_end = . ;
} >kseg1_data_mem AT>kseg0_program_mem
.lit8 :
{
*(.lit8)
} >kseg1_data_mem AT>kseg0_program_mem
.lit4 :
{
*(.lit4)
} >kseg1_data_mem AT>kseg0_program_mem
. = ALIGN (4) ;
_data_end = . ;
_bss_begin = . ;
.sbss :
{
_sbss_begin = . ;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
_sbss_end = . ;
} >kseg1_data_mem
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/*
* Align here to ensure that the .bss section occupies space up to
* _end. Align after .bss to ensure correct alignment even if the
* .bss section disappears because there are no input sections.
*/
. = ALIGN(32 / 8) ;
} >kseg1_data_mem
. = ALIGN(32 / 8) ;
_end = . ;
_bss_end = . ;
/* Heap allocating takes a chunk of memory following BSS */
.heap ALIGN(4) :
{
_heap = . ;
. += _min_heap_size ;
} >kseg1_data_mem
/* Stack allocation follows the heap */
.stack ALIGN(4) :
{
. += _min_stack_size ;
} >kseg1_data_mem
/*
* RAM functions go at the end of our stack and heap allocation.
* Alignment of 2K required by the boundary register (BMXDKPBA).
*/
.ramfunc ALIGN(2K) :
{
_ramfunc_begin = . ;
*(.ramfunc .ramfunc.*)
. = ALIGN(4) ;
_ramfunc_end = . ;
} >kseg1_data_mem AT>kseg0_program_mem
_ramfunc_image_begin = LOADADDR(.ramfunc) ;
_ramfunc_length = SIZEOF(.ramfunc) ;
_bmxdkpba_address = _ramfunc_begin - ORIGIN(kseg1_data_mem) ;
_bmxdudba_address = LENGTH(kseg1_data_mem) ;
_bmxdupba_address = LENGTH(kseg1_data_mem) ;
/*
* The actual top of stack should include the gap between the stack
* section and the beginning of the .ramfunc section caused by the
* alignment of the .ramfunc section minus 1 word. If RAM functions
* do not exist, then the top of the stack should point to the end of
* the data memory.
*/
_stack = (_ramfunc_length > 0)
? _ramfunc_begin - 4
: ORIGIN(kseg1_data_mem) + LENGTH(kseg1_data_mem) ;
ASSERT((_min_stack_size + _min_heap_size) <= (_stack - _heap),
"Not enough space to allocate both stack and heap. Reduce heap and/or stack size.")
/* The .pdf section belongs in the absolute section */
.pdr 0 : { *(.pdr) }
/* We don't load .reginfo onto the target, so don't locate it
* in real memory
*/
.reginfo 0 : { *(.reginfo) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/DISCARD/ : { *(.note.GNU-stack) }
}

View File

@ -0,0 +1,551 @@
/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf32-tradlittlemips")
OUTPUT_ARCH(pic32mx)
ENTRY(_reset)
/*
* Provide for a minimum stack and heap size
* - _min_stack_size - represents the minimum space that must be made
* available for the stack. Can be overridden from
* the command line using the linker's --defsym option.
* - _min_heap_size - represents the minimum space that must be made
* available for the heap. Can be overridden from
* the command line using the linker's --defsym option.
*/
EXTERN (_min_stack_size _min_heap_size)
PROVIDE(_min_stack_size = 0x400) ;
PROVIDE(_min_heap_size = 0) ;
INCLUDE procdefs.ld
PROVIDE(_DBG_CODE_ADDR = 0xBFC02000) ;
PROVIDE(_DBG_CODE_SIZE = 0xFF0) ;
SECTIONS
{
/* Boot Sections */
.reset _RESET_ADDR :
{
KEEP(*(.reset))
KEEP(*(.reset.startup)) /*JFM 2012-10-09 THE INIT SECTION MUST BE IN THE kseg0_boot_mem FOR THE BOOTLOADER TO WORK. INTRODUCED IN V2.00 OF THE COMPILER. SEE */
} > kseg1_boot_mem /*JFM 2020-11-15 INIT MOVED BACK? PROBABLY BECAUSE I HAVE COMPILER V1.3*/
.bev_excpt _BEV_EXCPT_ADDR :
{
KEEP(*(.bev_handler))
} > kseg1_boot_mem
.dbg_excpt _DBG_EXCPT_ADDR (NOLOAD) :
{
. += (DEFINED (_DEBUGGER) ? 0x8 : 0x0);
} > kseg1_boot_mem
.dbg_code _DBG_CODE_ADDR (NOLOAD) :
{
. += (DEFINED (_DEBUGGER) ? _DBG_CODE_SIZE : 0x0);
} > debug_exec_mem
.app_excpt _GEN_EXCPT_ADDR :
{
KEEP(*(.gen_handler))
} > exception_mem
.vector_0 _ebase_address + 0x200 :
{
KEEP(*(.vector_0))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_0) <= (_vector_spacing << 5), "function at exception vector 0 too large")
.vector_1 _ebase_address + 0x200 + (_vector_spacing << 5) * 1 :
{
KEEP(*(.vector_1))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_1) <= (_vector_spacing << 5), "function at exception vector 1 too large")
.vector_2 _ebase_address + 0x200 + (_vector_spacing << 5) * 2 :
{
KEEP(*(.vector_2))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_2) <= (_vector_spacing << 5), "function at exception vector 2 too large")
.vector_3 _ebase_address + 0x200 + (_vector_spacing << 5) * 3 :
{
KEEP(*(.vector_3))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_3) <= (_vector_spacing << 5), "function at exception vector 3 too large")
.vector_4 _ebase_address + 0x200 + (_vector_spacing << 5) * 4 :
{
KEEP(*(.vector_4))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_4) <= (_vector_spacing << 5), "function at exception vector 4 too large")
.vector_5 _ebase_address + 0x200 + (_vector_spacing << 5) * 5 :
{
KEEP(*(.vector_5))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_5) <= (_vector_spacing << 5), "function at exception vector 5 too large")
.vector_6 _ebase_address + 0x200 + (_vector_spacing << 5) * 6 :
{
KEEP(*(.vector_6))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_6) <= (_vector_spacing << 5), "function at exception vector 6 too large")
.vector_7 _ebase_address + 0x200 + (_vector_spacing << 5) * 7 :
{
KEEP(*(.vector_7))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_7) <= (_vector_spacing << 5), "function at exception vector 7 too large")
.vector_8 _ebase_address + 0x200 + (_vector_spacing << 5) * 8 :
{
KEEP(*(.vector_8))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_8) <= (_vector_spacing << 5), "function at exception vector 8 too large")
.vector_9 _ebase_address + 0x200 + (_vector_spacing << 5) * 9 :
{
KEEP(*(.vector_9))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_9) <= (_vector_spacing << 5), "function at exception vector 9 too large")
.vector_10 _ebase_address + 0x200 + (_vector_spacing << 5) * 10 :
{
KEEP(*(.vector_10))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_10) <= (_vector_spacing << 5), "function at exception vector 10 too large")
.vector_11 _ebase_address + 0x200 + (_vector_spacing << 5) * 11 :
{
KEEP(*(.vector_11))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_11) <= (_vector_spacing << 5), "function at exception vector 11 too large")
.vector_12 _ebase_address + 0x200 + (_vector_spacing << 5) * 12 :
{
KEEP(*(.vector_12))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_12) <= (_vector_spacing << 5), "function at exception vector 12 too large")
.vector_13 _ebase_address + 0x200 + (_vector_spacing << 5) * 13 :
{
KEEP(*(.vector_13))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_13) <= (_vector_spacing << 5), "function at exception vector 13 too large")
.vector_14 _ebase_address + 0x200 + (_vector_spacing << 5) * 14 :
{
KEEP(*(.vector_14))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_14) <= (_vector_spacing << 5), "function at exception vector 14 too large")
.vector_15 _ebase_address + 0x200 + (_vector_spacing << 5) * 15 :
{
KEEP(*(.vector_15))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_15) <= (_vector_spacing << 5), "function at exception vector 15 too large")
.vector_16 _ebase_address + 0x200 + (_vector_spacing << 5) * 16 :
{
KEEP(*(.vector_16))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_16) <= (_vector_spacing << 5), "function at exception vector 16 too large")
.vector_17 _ebase_address + 0x200 + (_vector_spacing << 5) * 17 :
{
KEEP(*(.vector_17))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_17) <= (_vector_spacing << 5), "function at exception vector 17 too large")
.vector_18 _ebase_address + 0x200 + (_vector_spacing << 5) * 18 :
{
KEEP(*(.vector_18))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_18) <= (_vector_spacing << 5), "function at exception vector 18 too large")
.vector_19 _ebase_address + 0x200 + (_vector_spacing << 5) * 19 :
{
KEEP(*(.vector_19))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_19) <= (_vector_spacing << 5), "function at exception vector 19 too large")
.vector_20 _ebase_address + 0x200 + (_vector_spacing << 5) * 20 :
{
KEEP(*(.vector_20))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_20) <= (_vector_spacing << 5), "function at exception vector 20 too large")
.vector_21 _ebase_address + 0x200 + (_vector_spacing << 5) * 21 :
{
KEEP(*(.vector_21))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_21) <= (_vector_spacing << 5), "function at exception vector 21 too large")
.vector_22 _ebase_address + 0x200 + (_vector_spacing << 5) * 22 :
{
KEEP(*(.vector_22))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_22) <= (_vector_spacing << 5), "function at exception vector 22 too large")
.vector_23 _ebase_address + 0x200 + (_vector_spacing << 5) * 23 :
{
KEEP(*(.vector_23))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_23) <= (_vector_spacing << 5), "function at exception vector 23 too large")
.vector_24 _ebase_address + 0x200 + (_vector_spacing << 5) * 24 :
{
KEEP(*(.vector_24))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_24) <= (_vector_spacing << 5), "function at exception vector 24 too large")
.vector_25 _ebase_address + 0x200 + (_vector_spacing << 5) * 25 :
{
KEEP(*(.vector_25))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_25) <= (_vector_spacing << 5), "function at exception vector 25 too large")
.vector_26 _ebase_address + 0x200 + (_vector_spacing << 5) * 26 :
{
KEEP(*(.vector_26))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_26) <= (_vector_spacing << 5), "function at exception vector 26 too large")
.vector_27 _ebase_address + 0x200 + (_vector_spacing << 5) * 27 :
{
KEEP(*(.vector_27))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_27) <= (_vector_spacing << 5), "function at exception vector 27 too large")
.vector_28 _ebase_address + 0x200 + (_vector_spacing << 5) * 28 :
{
KEEP(*(.vector_28))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_28) <= (_vector_spacing << 5), "function at exception vector 28 too large")
.vector_29 _ebase_address + 0x200 + (_vector_spacing << 5) * 29 :
{
KEEP(*(.vector_29))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_29) <= (_vector_spacing << 5), "function at exception vector 29 too large")
.vector_30 _ebase_address + 0x200 + (_vector_spacing << 5) * 30 :
{
KEEP(*(.vector_30))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_30) <= (_vector_spacing << 5), "function at exception vector 30 too large")
.vector_31 _ebase_address + 0x200 + (_vector_spacing << 5) * 31 :
{
KEEP(*(.vector_31))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_31) <= (_vector_spacing << 5), "function at exception vector 31 too large")
.vector_32 _ebase_address + 0x200 + (_vector_spacing << 5) * 32 :
{
KEEP(*(.vector_32))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_32) <= (_vector_spacing << 5), "function at exception vector 32 too large")
.vector_33 _ebase_address + 0x200 + (_vector_spacing << 5) * 33 :
{
KEEP(*(.vector_33))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_33) <= (_vector_spacing << 5), "function at exception vector 33 too large")
.vector_34 _ebase_address + 0x200 + (_vector_spacing << 5) * 34 :
{
KEEP(*(.vector_34))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_34) <= (_vector_spacing << 5), "function at exception vector 34 too large")
.vector_35 _ebase_address + 0x200 + (_vector_spacing << 5) * 35 :
{
KEEP(*(.vector_35))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_35) <= (_vector_spacing << 5), "function at exception vector 35 too large")
.vector_36 _ebase_address + 0x200 + (_vector_spacing << 5) * 36 :
{
KEEP(*(.vector_36))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_36) <= (_vector_spacing << 5), "function at exception vector 36 too large")
.vector_37 _ebase_address + 0x200 + (_vector_spacing << 5) * 37 :
{
KEEP(*(.vector_37))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_37) <= (_vector_spacing << 5), "function at exception vector 37 too large")
.vector_38 _ebase_address + 0x200 + (_vector_spacing << 5) * 38 :
{
KEEP(*(.vector_38))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_38) <= (_vector_spacing << 5), "function at exception vector 38 too large")
.vector_39 _ebase_address + 0x200 + (_vector_spacing << 5) * 39 :
{
KEEP(*(.vector_39))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_39) <= (_vector_spacing << 5), "function at exception vector 39 too large")
.vector_40 _ebase_address + 0x200 + (_vector_spacing << 5) * 40 :
{
KEEP(*(.vector_40))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_40) <= (_vector_spacing << 5), "function at exception vector 40 too large")
.vector_41 _ebase_address + 0x200 + (_vector_spacing << 5) * 41 :
{
KEEP(*(.vector_41))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_41) <= (_vector_spacing << 5), "function at exception vector 41 too large")
.vector_42 _ebase_address + 0x200 + (_vector_spacing << 5) * 42 :
{
KEEP(*(.vector_42))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_42) <= (_vector_spacing << 5), "function at exception vector 42 too large")
.vector_43 _ebase_address + 0x200 + (_vector_spacing << 5) * 43 :
{
KEEP(*(.vector_43))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_43) <= (_vector_spacing << 5), "function at exception vector 43 too large")
.vector_44 _ebase_address + 0x200 + (_vector_spacing << 5) * 44 :
{
KEEP(*(.vector_44))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_44) <= (_vector_spacing << 5), "function at exception vector 44 too large")
.vector_45 _ebase_address + 0x200 + (_vector_spacing << 5) * 45 :
{
KEEP(*(.vector_45))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_45) <= (_vector_spacing << 5), "function at exception vector 45 too large")
.vector_46 _ebase_address + 0x200 + (_vector_spacing << 5) * 46 :
{
KEEP(*(.vector_46))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_46) <= (_vector_spacing << 5), "function at exception vector 46 too large")
.vector_47 _ebase_address + 0x200 + (_vector_spacing << 5) * 47 :
{
KEEP(*(.vector_47))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_47) <= (_vector_spacing << 5), "function at exception vector 47 too large")
.vector_48 _ebase_address + 0x200 + (_vector_spacing << 5) * 48 :
{
KEEP(*(.vector_48))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_48) <= (_vector_spacing << 5), "function at exception vector 48 too large")
.vector_49 _ebase_address + 0x200 + (_vector_spacing << 5) * 49 :
{
KEEP(*(.vector_49))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_49) <= (_vector_spacing << 5), "function at exception vector 49 too large")
.vector_50 _ebase_address + 0x200 + (_vector_spacing << 5) * 50 :
{
KEEP(*(.vector_50))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_50) <= (_vector_spacing << 5), "function at exception vector 50 too large")
.vector_51 _ebase_address + 0x200 + (_vector_spacing << 5) * 51 :
{
KEEP(*(.vector_51))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_51) <= (_vector_spacing << 5), "function at exception vector 51 too large")
.vector_52 _ebase_address + 0x200 + (_vector_spacing << 5) * 52 :
{
KEEP(*(.vector_52))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_52) <= (_vector_spacing << 5), "function at exception vector 52 too large")
.vector_53 _ebase_address + 0x200 + (_vector_spacing << 5) * 53 :
{
KEEP(*(.vector_53))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_53) <= (_vector_spacing << 5), "function at exception vector 53 too large")
.vector_54 _ebase_address + 0x200 + (_vector_spacing << 5) * 54 :
{
KEEP(*(.vector_54))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_54) <= (_vector_spacing << 5), "function at exception vector 54 too large")
.vector_55 _ebase_address + 0x200 + (_vector_spacing << 5) * 55 :
{
KEEP(*(.vector_55))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_55) <= (_vector_spacing << 5), "function at exception vector 55 too large")
.vector_56 _ebase_address + 0x200 + (_vector_spacing << 5) * 56 :
{
KEEP(*(.vector_56))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_56) <= (_vector_spacing << 5), "function at exception vector 56 too large")
.vector_57 _ebase_address + 0x200 + (_vector_spacing << 5) * 57 :
{
KEEP(*(.vector_57))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_57) <= (_vector_spacing << 5), "function at exception vector 57 too large")
.vector_58 _ebase_address + 0x200 + (_vector_spacing << 5) * 58 :
{
KEEP(*(.vector_58))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_58) <= (_vector_spacing << 5), "function at exception vector 58 too large")
.vector_59 _ebase_address + 0x200 + (_vector_spacing << 5) * 59 :
{
KEEP(*(.vector_59))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_59) <= (_vector_spacing << 5), "function at exception vector 59 too large")
.vector_60 _ebase_address + 0x200 + (_vector_spacing << 5) * 60 :
{
KEEP(*(.vector_60))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_60) <= (_vector_spacing << 5), "function at exception vector 60 too large")
.vector_61 _ebase_address + 0x200 + (_vector_spacing << 5) * 61 :
{
KEEP(*(.vector_61))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_61) <= (_vector_spacing << 5), "function at exception vector 61 too large")
.vector_62 _ebase_address + 0x200 + (_vector_spacing << 5) * 62 :
{
KEEP(*(.vector_62))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_62) <= (_vector_spacing << 5), "function at exception vector 62 too large")
.vector_63 _ebase_address + 0x200 + (_vector_spacing << 5) * 63 :
{
KEEP(*(.vector_63))
} > exception_mem
ASSERT (_vector_spacing == 0 || SIZEOF(.vector_63) <= (_vector_spacing << 5), "function at exception vector 63 too large")
/* Starting with C32 v2.00, the startup code is in the .reset.startup section.
* Keep this here for backwards compatibility.
*/
.startup ORIGIN(kseg0_boot_mem) :
{
KEEP(*(.startup))
/* KEEP(*(.reset.startup))*/ /*2012-10-09 MOVED FROM kseg1_boot_mem SECTION. AS WE CAN SEE IN THE MICROCHIP COMMENT THE STARTUP CODE HAS MOVED TO .reset.startup SECTION. */
} > kseg0_boot_mem
/* Code Sections - Note that input sections *(.text) and *(.text.*)
** are not mapped here. Starting in C32 v2.00, the best-fit allocator
** locates them, so that .text may flow around absolute sections
** as needed.
*/
.text :
{
*(.stub .gnu.linkonce.t.*)
KEEP (*(.text.*personality*))
*(.mips16.fn.*)
*(.mips16.call.*)
*(.gnu.warning)
} >kseg0_program_mem
/* Read-only sections */
.rodata :
{
*( /* .rodata */ .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
. = ALIGN(4) ;
} >kseg0_program_mem
/*
* Small initialized constant global and static data can be placed in the
* .sdata2 section. This is different from .sdata, which contains small
* initialized non-constant global and static data.
*/
.sdata2 ALIGN(4) :
{
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
. = ALIGN(4) ;
} >kseg0_program_mem
/*
* Uninitialized constant global and static data (i.e., variables which will
* always be zero). Again, this is different from .sbss, which contains
* small non-initialized, non-constant global and static data.
*/
.sbss2 ALIGN(4) :
{
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
. = ALIGN(4) ;
} >kseg0_program_mem
.eh_frame_hdr : { *(.eh_frame_hdr) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
.dbg_data (NOLOAD) :
{
. += (DEFINED (_DEBUGGER) ? 0x200 : 0x0);
} >kseg1_data_mem
/* Persistent data - Use the new C 'persistent' attribute instead. */
.persist :
{
_persist_begin = .;
*(.persist .persist.*)
. = ALIGN(4);
_persist_end = .;
} >kseg1_data_mem
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
. = .;
_gp = ALIGN(16) + 0x7ff0;
.got ALIGN(4) :
{
*(.got.plt) *(.got)
} >kseg1_data_mem /* AT>kseg0_program_mem */
/*
* Note that "small" data sections are still mapped in the linker
* script. This ensures that they are grouped together for
* gp-relative addressing. Absolute sections are allocated after
* the "small" data sections so small data cannot flow around them.
*/
/*
* We want the small data sections together, so single-instruction offsets
* can access them all, and initialized data all before uninitialized, so
* we can shorten the on-disk segment size.
*/
.sdata ALIGN(4) /* */ :
{
_sdata_begin = . ;
*(.sdata .sdata.* .gnu.linkonce.s.*)
_sdata_end = . ;
} >kseg1_data_mem
.lit8 :
{
*(.lit8)
} >kseg1_data_mem
.lit4 :
{
*(.lit4)
} >kseg1_data_mem
. = ALIGN (4) ;
_data_end = . ;
_bss_begin = . ;
.sbss ALIGN(4) :
{
_sbss_begin = . ;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
_sbss_end = . ;
} >kseg1_data_mem
/*
* Note that input sections named .data* are no longer mapped here.
* Starting in C32 v2.00, the best-fit allocator locates them, so
* that they may flow around absolute sections as needed.
*/
/*
* Align here to ensure that the .bss section occupies space up to
* _end. Align after .bss to ensure correct alignment even if the
* .bss section disappears because there are no input sections.
*
* Note that input sections named .bss* are no longer mapped here.
* Starting in C32 v2.00, the best-fit allocator locates them, so
* that they may flow around absolute sections as needed.
*
*/
.bss :
{
*(.dynbss)
*(COMMON)
. = ALIGN(4) ;
} >kseg1_data_mem
. = ALIGN(4) ;
_end = . ;
_bss_end = . ;
/* Starting with C32 v2.00, the heap and stack are dynamically
* allocated by the linker.
*/
/*
* RAM functions go at the end of our stack and heap allocation.
* Alignment of 2K required by the boundary register (BMXDKPBA).
*
* RAM functions are now allocated by the linker. The linker generates
* _ramfunc_begin and _bmxdkpba_address symbols depending on the
* location of RAM functions.
*/
_bmxdudba_address = LENGTH(kseg1_data_mem) ;
_bmxdupba_address = LENGTH(kseg1_data_mem) ;
/* The .pdr section belongs in the absolute section */
/DISCARD/ : { *(.pdr) }
/* We don't load .reginfo onto the target, so don't locate it
* in real memory
*/
/DISCARD/ : { *(.reginfo) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/DISCARD/ : { *(.rel.dyn) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.discard) }
}

View File

@ -0,0 +1,156 @@
/*******************************************************************************
* *
* 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 "define.h"
#include "InternalUart.h"
#include "FlashInterface.h"
#include "BootloaderProtocol.h"
#include "BootloaderStateMachine.h"
#include "DigitalIO.h"
//#pragma config FMIIEN = OFF, FSRSSEL = PRIORITY_7, FETHIO = ON
//#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
//#pragma config POSCMOD = XT, FNOSC = PRIPLL, FPBDIV = DIV_1
//#pragma config ICESEL = ICS_PGx2, BWP = ON
////#pragma config FMIIEN = OFF, FSRSSEL = PRIORITY_7, FETHIO = ON
////#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
//#pragma config FPLLMUL = MUL_19, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
//#pragma config POSCMOD = XT, FNOSC = PRIPLL, FPBDIV = DIV_1
//#pragma config ICESEL = ICS_PGx1, BWP = ON
#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
//void _general_exception_handler(void);
int main(void)
{
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
AD1PCFG = 0xFFFF; //Sart with I/O pins configured as digital I/O
InternalUartInit();
InitFlashInterface();
ProtocolInit();
BootloaderSMInit();
InitDigitalIO();
OpenInternalPort(0,0,115200,INT_UART_ONE_STOP_BIT,INT_UART_NO_PARITY);
ProtocolSendCmd(BOOTLOADER_READY_CMD,0,0);
HEARTBEAT_LED_1_PIN = 0;
char mbuf[30];
mbuf[0] = 'B';
mbuf[1] = 'o';
mbuf[2] = 'o';
mbuf[3] = 't';
mbuf[4] = 'l';
mbuf[5] = 'o';
mbuf[6] = 'a';
mbuf[7] = 'd';
mbuf[8] = 'e';
mbuf[9] = 'r';
mbuf[10] = ' ';
mbuf[11] = 'V';
mbuf[12] = '0';
mbuf[13] = '.';
mbuf[14] = '0';
mbuf[15] = '1';
mbuf[16] = '\r';
SendInternalUartData(&mbuf[0],17);
int i,j;
i =0;
j = 0;
while(1)
{
if(ReadInternalUart() > 0)
{
// New Data arrived.
// nothing special to do.
// could flash a led
HEARTBEAT_LED_2_PIN = !HEARTBEAT_LED_2_PIN;
}
if(e_CommandPending)
{
//Valid command received.
ProtocolExecCmd();
e_CommandPending = false;
}
BootloaderSM(SM_TICK_EVENT,SM_NULL_DATA);
if(++i >= 100000)
{
// if(++j >= 10000000)
{
HEARTBEAT_LED_1_PIN = ~HEARTBEAT_LED_1_PIN;
i = 0;
j = 0;
}
}
}
return true;
}
void _general_exception_handler(void)
{
char mbuf[30];
mbuf[0] = 'E';
mbuf[1] = 'x';
mbuf[2] = 'c';
mbuf[3] = 'e';
mbuf[4] = 'p';
mbuf[5] = 't';
mbuf[6] = 'i';
mbuf[7] = 'o';
mbuf[8] = 'n';
mbuf[9] = ' ';
mbuf[10] = 'o';
mbuf[11] = 'c';
mbuf[12] = 'c';
mbuf[13] = 'u';
mbuf[14] = 'r';
mbuf[15] = 'r';
mbuf[16] = 'e';
mbuf[17] = 'd';
mbuf[18] = '\r';
SendInternalUartData(&mbuf[0],19);
SoftReset();
}
//EOF

View File

@ -0,0 +1,60 @@
/*************************************************************************
* Processor-specific object file. Contains SFR definitions.
*************************************************************************/
INPUT("processor.o")
/*************************************************************************
* For interrupt vector handling
*************************************************************************/
PROVIDE(_vector_spacing = 0x00000001);
/*_ebase_address = 0x9D002000;*/ /*JFM 2012-10-06 - moved bootloader exception mem to BOOT mem so it doesn't get erased if a problem occurs during flashing*/
_ebase_address = 0x9FC01000;
/*************************************************************************
* Memory Address Equates
*************************************************************************/
_RESET_ADDR = 0xBFC00000;
_BEV_EXCPT_ADDR = 0xBFC00380;
_DBG_EXCPT_ADDR = 0xBFC00480;
_DBG_CODE_ADDR = 0xBFC02000;
_DBG_CODE_SIZE = 0xFF0 ;
_GEN_EXCPT_ADDR = _ebase_address + 0x180; /* As defined by the MIPS specification */
/*************************************************************************
* Memory Regions
*
* Memory regions without attributes cannot be used for orphaned sections.
* Only sections specifically assigned to these regions can be allocated
* into these regions.
*************************************************************************/
MEMORY
{
kseg0_program_mem (rx) : ORIGIN = 0x9D001000, LENGTH = 0x100 /*0x9000*/ /* 9 program Flash pages are reserved for bootloader code */
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970 /* C Init section goes here : ends at 0x9FC01370 */
/*exception_mem : ORIGIN = 0x9D002000, LENGTH = 0x1000 */
exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490
debug_exec_mem : ORIGIN = 0xBFC02000, LENGTH = 0xFF0
config3 : ORIGIN = 0xBFC02FF0, LENGTH = 0x4
config2 : ORIGIN = 0xBFC02FF4, LENGTH = 0x4
config1 : ORIGIN = 0xBFC02FF8, LENGTH = 0x4
config0 : ORIGIN = 0xBFC02FFC, LENGTH = 0x4
kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x8000 /*0x20000*/
sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000
configsfrs : ORIGIN = 0xBFC02FF0, LENGTH = 0x10
}
SECTIONS
{
.config_BFC02FF0 : {
KEEP(*(.config_BFC02FF0))
} > config3
.config_BFC02FF4 : {
KEEP(*(.config_BFC02FF4))
} > config2
.config_BFC02FF8 : {
KEEP(*(.config_BFC02FF8))
} > config1
.config_BFC02FFC : {
KEEP(*(.config_BFC02FFC))
} > config0
}

View File

@ -0,0 +1,136 @@
#include "thinfat32.h"
#include "fat32_ui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// TODO: Reimplement this function correctly
int fat_type(BPB_struct *s) {
return TYPE_FAT32;
}
void printBPB(BPB_struct *s) {
int i,j;
printf("==== BIOS PARAMETER BLOCK ====\n");
printf(" Boot Instruction: 0x%02x%02x%02x\n", s->BS_JumpBoot[0], s->BS_JumpBoot[1], s->BS_JumpBoot[2]);
printf(" OEM Name: '%8s'\n", s->BS_OEMName);
printf(" Bytes per Sector: %d\n", s->BytesPerSector);
printf("Sectors per Cluster: %d\n", s->SectorsPerCluster);
printf(" Reserved Sectors: %d\n", s->ReservedSectorCount);
printf(" FATS: %d\n", s->NumFATs);
printf(" Root Entries: %d\n", s->RootEntryCount);
printf(" Media: "); print_media(s->Media); printf("\n");
printf(" Fat Size (16b): %d\n", s->FATSize16);
printf(" Sectors per Track: %d\n", s->SectorsPerTrack);
printf(" Number of Heads: %d\n", s->NumberOfHeads);
printf(" Hidden Sectors: %d\n", s->HiddenSectors);
printf("Total Sectors (16b): %d\n", s->TotalSectors16);
printf("Total Sectors (32b): %d\n", s->TotalSectors32);
switch(fat_type(s)) {
case TYPE_FAT12: printf(" FAT Type: FAT12\n"); break;
case TYPE_FAT16: printf(" FAT Type: FAT16\n"); break;
case TYPE_FAT32: printf(" FAT Type: FAT32\n"); break;
default: printf("FAT TYPE UNRECOGNIZED!\n"); break;
}
if((fat_type(s) == TYPE_FAT12) | (fat_type(s) == TYPE_FAT16)) {
printf(" Drive Number: %d\n", s->FSTypeSpecificData.fat16.BS_DriveNumber);
printf(" Boot Signature: 0x%02x\n", s->FSTypeSpecificData.fat16.BS_BootSig);
printf(" Volume ID: 0x%04x\n", s->FSTypeSpecificData.fat16.BS_VolumeID);
printf(" Volume Label: '%.*s'\n", 11, s->FSTypeSpecificData.fat16.BS_VolumeLabel);
printf(" FileSystemType: '%.*s'\n", 8, s->FSTypeSpecificData.fat16.BS_FileSystemType);
}
else {
printf(" FAT Size (32b): %d\n", s->FSTypeSpecificData.fat32.FATSize);
printf(" FAT Flags: 0x%04x\n", s->FSTypeSpecificData.fat32.ExtFlags);
printf(" FS Version: 0x%04x\n", s->FSTypeSpecificData.fat32.FSVersion);
printf(" Root Cluster: %d\n", s->FSTypeSpecificData.fat32.RootCluster);
printf(" FSINFO Sector: %d\n", s->FSTypeSpecificData.fat32.FSInfo);
printf("Bkup BootRec Sector: %d\n", s->FSTypeSpecificData.fat32.BkBootSec);
j=0;
for(i=0; i<12; i++) {
if(s->FSTypeSpecificData.fat32.Reserved[i] != 0x00) j=1;
}
if(j) printf(" Reserved Area: NONZERO!\n");
else printf(" Reserved Area: Ok\n");
printf(" Drive Number: %d\n", s->FSTypeSpecificData.fat32.BS_DriveNumber);
printf(" Boot Signature: 0x%02x\n", s->FSTypeSpecificData.fat32.BS_BootSig);
printf(" Volume ID: 0x%04x\n", s->FSTypeSpecificData.fat32.BS_VolumeID);
printf(" Volume Label: '%.*s'\n", 11, s->FSTypeSpecificData.fat32.BS_VolumeLabel);
printf(" FileSystemType: '%.*s'\n", 8, s->FSTypeSpecificData.fat32.BS_FileSystemType);
}
printf("\n");
}
void print_media(unsigned char mediatype) {
switch(mediatype) {
case 0xf0: printf("Generic media type (0xf0)"); break;
case 0xf8: printf("Hard disk (0xf8)"); break;
case 0xf9: printf("3.5\" double sided 720k or 5.25 double sided 1.2MB (0xf9)"); break;
case 0xfa: printf("5.25\" single sided 320k (0xfa)"); break;
case 0xfb: printf("3.5\" double sided 640k (0xfb)"); break;
case 0xfc: printf("5.25\" single sided 180k (0xfc)"); break;
case 0xfd: printf("5.25\" double sided 360k (0xfd)"); break;
case 0xfe: printf("5.25\" single sided 180k (0xfe)"); break;
case 0xff: printf("5.25\" double sided 320k (0xff)"); break;
default: printf("Unknown (0x%02x)",mediatype); break;
}
}
void print_sector(unsigned char *sector) {
int i;
for(i=0; i<(512-8); i+=8) {
printf(" %02x%02x%02x%02x %02x%02x%02x%02x %c%c%c%c %c%c%c%c\n", sector[i], sector[i+1], sector[i+2], sector[i+3], sector[i+4], sector[i+5], sector[i+6], sector[i+7], sector[i], sector[i+1], sector[i+2], sector[i+3], sector[i+4], sector[i+5], sector[i+6], sector[i+7]);
}
}
void print_tf_info(TFInfo *t) {
printf(" TFInfo Structure\n ----------------\n");
switch(t->type) {
case TF_TYPE_FAT16: printf(" Type: FAT16\n"); break;
case TF_TYPE_FAT32: printf(" Type: FAT32\n"); break;
default: printf(" Type: UNRECOGNIZED! (0x%02x)\n", t->type); break;
}
printf("Sectors Per Cluster: %d\n", t->sectorsPerCluster);
printf(" Total Sectors: %d\n", t->totalSectors);
printf(" Reserved Sectors: %d\n", t->reservedSectors);
printf(" First Data Sector: %d\n", t->firstDataSector);
}
void print_TFFile(TFFile *fp) {
printf(" TFFile Structure\n ----------------\n");
printf(" currentCluster: %d\n", fp->currentCluster);
printf(" currentClusterIdx: %d\n", fp->currentClusterIdx);
printf("parentStartCluster: %d\n", fp->parentStartCluster);
printf(" startCluster: %d\n", fp->startCluster);
printf(" currentSector: %d\n", fp->currentSector);
printf(" currentByte: %d\n", fp->currentByte);
printf(" pos: %d\n", fp->pos);
printf(" flags: 0x%02x\n", fp->flags);
printf(" size: %d bytes\n", fp->size);
}
void print_FatFileEntry(FatFileEntry *entry) {
printf(" FatFile Structure\n ---------------\n");
if(entry->msdos.attributes == 0x0f) {
print_FatFileLFN(&(entry->lfn));
}
else {
print_FatFile83(&(entry->msdos));
}
}
void print_FatFile83(FatFile83 *entry) {
printf(" Type: 8.3 Filename\n");
printf(" Filename: %.*s\n", 8, entry->filename);
printf(" Extension: %.*s\n", 3, entry->extension);
printf(" Attributes: 0x%02x\n", entry->attributes);
printf("First Cluster: %d\n", ((entry->eaIndex & 0xffff) << 16) | ((entry->firstCluster & 0xffff)));
printf("Creation Time: %d/%d/%d\n", ((entry->creationDate & 0xfe00) >> 9) + 1980, ((entry->creationDate & 0x1e0) >> 5), (entry->creationDate & 0xf)*2);
}
void print_FatFileLFN(FatFileLFN *entry) {
printf(" Type: Long Filename (LFN)\n");
}

View File

@ -0,0 +1,221 @@
#ifndef __FAT32_H
#define __FAT32_H
#include <stdlib.h>
#include <stdio.h>
#define TF_MAX_PATH 256
#define TF_FILE_HANDLES 4
#define TF_FLAG_DIRTY 0x01
#define TF_FLAG_OPEN 0x02
#define TF_FLAG_SIZECHANGED 0x04
#define TF_FLAG_ROOT 0x08
#define TYPE_FAT12 0
#define TYPE_FAT16 1
#define TYPE_FAT32 2
#define TF_MARK_BAD_CLUSTER32 0x0ffffff7
#define TF_MARK_BAD_CLUSTER16 0xfff7
#define TF_MARK_EOC32 0x0ffffff8
#define TF_MARK_EOC16 0xfff8
#define TF_ATTR_DIRECTORY 0x10
#define TF_DEBUG 0
#undef TF_DEBUG
#ifdef TF_DEBUG
typedef struct struct_TFStats {
unsigned long sector_reads;
unsigned long sector_writes;
} TFStats;
#endif
// Ultimately, once the filesystem is checked for consistency, you only need a few
// things to keep it up and running. These are:
// 1) The type (fat16 or fat32, no fat12 support)
// 2) The number of sectors per cluster
// 3) Everything needed to compute indices into the FATs, which includes:
// * Bytes per sector, which is fixed at 512
// * The number of reserved sectors (pulled directly from the BPB)
// 4) The current sector in memory. No sense reading it if it's already in memory!
typedef struct struct_tfinfo {
// FILESYSTEM INFO PROPER
unsigned char type; // 0 for FAT16, 1 for FAT32. FAT12 NOT SUPPORTED
unsigned char sectorsPerCluster;
unsigned int firstDataSector;
unsigned int totalSectors;
unsigned short reservedSectors;
// "LIVE" DATA
unsigned int currentSector;
unsigned char sectorFlags;
unsigned int rootDirectorySize;
unsigned char buffer[512];
} TFInfo;
// Starting at offset 36 into the BPB, this is the structure for a FAT12/16 FS
typedef struct struct_BPBFAT1216_struct {
unsigned char BS_DriveNumber; // 1
unsigned char BS_Reserved1; // 1
unsigned char BS_BootSig; // 1
unsigned int BS_VolumeID; // 4
char BS_VolumeLabel[11]; // 11
char BS_FileSystemType[8]; // 8
} BPB1216_struct;
// Starting at offset 36 into the BPB, this is the structure for a FAT32 FS
typedef struct struct_BPBFAT32_struct {
unsigned int FATSize; // 4
unsigned short ExtFlags; // 2
unsigned short FSVersion; // 2
unsigned int RootCluster; // 4
unsigned short FSInfo; // 2
unsigned short BkBootSec; // 2
unsigned char Reserved[12]; // 12
unsigned char BS_DriveNumber; // 1
unsigned char BS_Reserved1; // 1
unsigned char BS_BootSig; // 1
unsigned int BS_VolumeID; // 4
char BS_VolumeLabel[11]; // 11
char BS_FileSystemType[8]; // 8
} BPB32_struct;
typedef struct struct_BPB_struct {
unsigned char BS_JumpBoot[3]; // 3
char BS_OEMName[8]; // 8
unsigned short BytesPerSector; // 2
unsigned char SectorsPerCluster; // 1
unsigned short ReservedSectorCount; // 2
unsigned char NumFATs; // 1
unsigned short RootEntryCount; // 2
unsigned short TotalSectors16; // 2
unsigned char Media; // 1
unsigned short FATSize16; // 2
unsigned short SectorsPerTrack; // 2
unsigned short NumberOfHeads; // 2
unsigned int HiddenSectors; // 4
unsigned int TotalSectors32; // 4
union {
BPB1216_struct fat16;
BPB32_struct fat32;
} FSTypeSpecificData;
} BPB_struct;
typedef struct struct_TFFILE {
int parentStartCluster;
int startCluster;
int currentClusterIdx;
int currentCluster;
short currentSector;
short currentByte;
unsigned int pos;
unsigned char flags;
unsigned char attributes;
unsigned char mode;
unsigned int size;
char filename[TF_MAX_PATH];
} TFFile;
#define TF_MODE_READ 0x01
#define TF_MODE_WRITE 0x02
#define TF_MODE_APPEND 0x04
#define TF_MODE_OVERWRITE 0x08
#define TF_ATTR_READ_ONLY 0x01
#define TF_ATTR_HIDDEN 0x02
#define TF_ATTR_SYSTEM 0x04
#define TF_ATTR_VOLUME_LABEL 0x08
#define TF_ATTR_DIRECTORY 0x10
#define TF_ATTR_ARCHIVE 0x20
#define TF_ATTR_DEVICE 0x40 // Should never happen!
#define TF_ATTR_UNUSED 0x80
typedef struct struct_FatFile83 {
char filename[8];
char extension[3];
unsigned char attributes;
unsigned char reserved;
unsigned char creationTimeMs;
unsigned short creationTime;
unsigned short creationDate;
unsigned short lastAccessTime;
unsigned short eaIndex;
unsigned short modifiedTime;
unsigned short modifiedDate;
unsigned short firstCluster;
unsigned int fileSize;
} FatFile83;
typedef struct struct_FatFileLFN {
unsigned char sequence_number;
unsigned short name1[5]; // 5 Chars of name (UTF 16???)
unsigned char attributes; // Always 0x0f
unsigned char reserved; // Always 0x00
unsigned char checksum; // Checksum of DOS Filename. See Docs.
unsigned short name2[6]; // 6 More chars of name (UTF-16)
unsigned short firstCluster; // Always 0x0000
unsigned short name3[2];
} FatFileLFN;
typedef union struct_FatFileEntry {
FatFile83 msdos;
FatFileLFN lfn;
} FatFileEntry;
// "Legacy" functions
int fat_size(BPB_struct *bpb);
int total_sectors(BPB_struct *bpb);
int root_dir_sectors(BPB_struct *bpb);
int cluster_count(BPB_struct *bpb);
int fat_type(BPB_struct *bpb);
int first_data_sector(BPB_struct *bpb);
int first_sector_of_cluster(BPB_struct *bpb, int N);
int data_sectors(BPB_struct *bpb);
int fat_sector_number(BPB_struct *bpb, int N);
int fat_entry_offset(BPB_struct *bpb, int N);
int fat_entry_for_cluster(BPB_struct *bpb, unsigned char *buffer, int N);
int read_sector(char *data, int blocknum);
int write_sector(char *data, int blocknum);
// New error codes
#define TF_ERR_NO_ERROR 0
#define TF_ERR_BAD_BOOT_SIGNATURE 1
#define TF_ERR_BAD_FS_TYPE 2
#define TF_ERR_INVALID_SEEK 1
// FS Types
#define TF_TYPE_FAT16 0
#define TF_TYPE_FAT32 1
// New backend functions
int tf_init();
int tf_fetch(int sector);
int tf_store();
int tf_get_fat_entry(int cluster);
int tf_set_fat_entry(int cluster, unsigned int value);
int tf_unsafe_fseek(TFFile *fp, int base, long offset);
TFFile *tf_fnopen(char *filename, const char *mode, int n);
int tf_free_clusterchain(int cluster);
int tf_create(char *filename);
void tf_release_handle(TFFile *fp);
TFFile *tf_parent(char *filename, const char *mode);
// New frontend functions
int tf_init();
int tf_fflush(TFFile *fp);
int tf_fseek(TFFile *fp, int base, long offset);
int tf_fclose(TFFile *fp);
int tf_fread(char *dest, int size, TFFile *fp);
int tf_find_file(TFFile *current_directory, char *name);
int tf_compare_filename(TFFile *fp, char *name);
int tf_first_sector(int cluster);
char *tf_walk(char *filename, TFFile *fp);
TFFile *tf_fopen(char *filename, const char *mode);
int tf_fwrite(void *src, int size, int count, TFFile *fp);
int tf_fputs(char *src, TFFile *fp);
unsigned int tf_find_free_cluster();
// New Datas
extern TFInfo tf_info;
extern TFFile tf_file;
#endif

View File

@ -0,0 +1,16 @@
#ifndef __FAT32_UI_H
#define __FAT32_UI_H
#include "thinfat32.h"
#include "thinternal.h"
void printBPB(BPB_struct *s);
void print_sector(unsigned char *sector);
void print_media(unsigned char mediatype);
void print_TFFile(TFFile *fp);
void print_tf_info(TFInfo *t);
void print_FatFileEntry(FatFileEntry *entry);
void print_FatFileLFN(FatFileLFN *entry);
void print_FatFile83(FatFile83 *entry);
#endif

View File

@ -0,0 +1,179 @@
#ifndef __FAT32_H
#define __FAT32_H
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#define TF_MAX_PATH 256
#define TF_FILE_HANDLES 5
#define TF_FLAG_DIRTY 0x01
#define TF_FLAG_OPEN 0x02
#define TF_FLAG_SIZECHANGED 0x04
#define TF_FLAG_ROOT 0x08
#define TYPE_FAT12 0
#define TYPE_FAT16 1
#define TYPE_FAT32 2
#define TF_MARK_BAD_CLUSTER32 0x0ffffff7
#define TF_MARK_BAD_CLUSTER16 0xfff7
#define TF_MARK_EOC32 0x0ffffff8
#define TF_MARK_EOC16 0xfff8
#define LFN_ENTRY_CAPACITY 13 // bytes per LFN entry
#define TF_ATTR_DIRECTORY 0x10
// #define TF_DEBUG 1
#undef DEBUG
#ifdef DEBUG
#define dbg_printf(...) printf(__VA_ARGS__)
#define dbg_printHex(x,y) printHex(x,y)
#ifdef TF_DEBUG
typedef struct struct_TFStats {
unsigned long sector_reads;
unsigned long sector_writes;
} TFStats;
#define tf_printf(...) printf(__VA_ARGS__)
#define tf_printHex(x,y) printHex(x,y)
#else
#define tf_printf(...)
#define tf_printHex(x,y)
#endif // TF_DEBUG
#else // DEBUG
#define dbg_printf(...)
#define dbg_printHex(x,y)
#define tf_printf(...)
#define tf_printHex(x,y)
#endif // DEBUG
#define LSN(CN, bpb) SSA + ((CN-2) * bpb->SectorsPerCluster)
#ifndef min
#define min(x,y) (x<y)? x:y
#define max(x,y) (x>y)? x:y
#endif
// Ultimately, once the filesystem is checked for consistency, you only need a few
// things to keep it up and running. These are:
// 1) The type (fat16 or fat32, no fat12 support)
// 2) The number of sectors per cluster
// 3) Everything needed to compute indices into the FATs, which includes:
// * Bytes per sector, which is fixed at 512
// * The number of reserved sectors (pulled directly from the BPB)
// 4) The current sector in memory. No sense reading it if it's already in memory!
typedef struct struct_tfinfo {
// FILESYSTEM INFO PROPER
uint8_t type; // 0 for FAT16, 1 for FAT32. FAT12 NOT SUPPORTED
uint8_t sectorsPerCluster;
uint32_t firstDataSector;
uint32_t totalSectors;
uint16_t reservedSectors;
// "LIVE" DATA
uint32_t currentSector;
uint8_t sectorFlags;
uint32_t rootDirectorySize;
uint8_t buffer[512];
} TFInfo;
/////////////////////////////////////////////////////////////////////////////////
typedef struct struct_TFFILE {
uint32_t parentStartCluster;
uint32_t startCluster;
uint32_t currentClusterIdx;
uint32_t currentCluster;
short currentSector;
short currentByte;
uint32_t pos;
uint8_t flags;
uint8_t attributes;
uint8_t mode;
uint32_t size;
uint8_t filename[TF_MAX_PATH];
} TFFile;
#define TF_MODE_READ 0x01
#define TF_MODE_WRITE 0x02
#define TF_MODE_APPEND 0x04
#define TF_MODE_OVERWRITE 0x08
#define TF_ATTR_READ_ONLY 0x01
#define TF_ATTR_HIDDEN 0x02
#define TF_ATTR_SYSTEM 0x04
#define TF_ATTR_VOLUME_LABEL 0x08
#define TF_ATTR_DIRECTORY 0x10
#define TF_ATTR_ARCHIVE 0x20
#define TF_ATTR_DEVICE 0x40 // Should never happen!
#define TF_ATTR_UNUSED 0x80
int read_sector(uint8_t *data, uint32_t blocknum);
int write_sector(uint8_t *data, uint32_t blocknum);
// New error codes
#define TF_ERR_NO_ERROR 0
#define TF_ERR_BAD_BOOT_SIGNATURE 1
#define TF_ERR_BAD_FS_TYPE 2
#define TF_ERR_INVALID_SEEK 1
// FS Types
#define TF_TYPE_FAT16 0
#define TF_TYPE_FAT32 1
// New backend functions
int tf_init(void);
int tf_fetch(uint32_t sector);
int tf_store(void);
uint32_t tf_get_fat_entry(uint32_t cluster);
int tf_set_fat_entry(uint32_t cluster, uint32_t value);
int tf_unsafe_fseek(TFFile *fp, int32_t base, long offset);
TFFile *tf_fnopen(uint8_t *filename, const uint8_t *mode, int n);
int tf_free_clusterchain(uint32_t cluster);
int tf_create(uint8_t *filename);
void tf_release_handle(TFFile *fp);
TFFile *tf_parent(uint8_t *filename, const uint8_t *mode, int mkParents);
int tf_shorten_filename(uint8_t *dest, uint8_t *src, uint8_t num);
// New frontend functions
int tf_init();
int tf_fflush(TFFile *fp);
int tf_fseek(TFFile *fp, int32_t base, long offset);
int tf_fclose(TFFile *fp);
int tf_fread(uint8_t *dest, int size, TFFile *fp);
int tf_find_file(TFFile *current_directory, uint8_t *name);
int tf_compare_filename(TFFile *fp, uint8_t *name);
uint32_t tf_first_sector(uint32_t cluster);
uint8_t *tf_walk(uint8_t *filename, TFFile *fp);
TFFile *tf_fopen(uint8_t *filename, const uint8_t *mode);
int tf_fwrite(uint8_t *src, int size, int count, TFFile *fp);
int tf_fputs(uint8_t *src, TFFile *fp);
int tf_mkdir(uint8_t *filename, int mkParents);
int tf_remove(uint8_t *filename);
void tf_print_open_handles(void);
uint32_t tf_find_free_cluster();
uint32_t tf_find_free_cluster_from(uint32_t c);
uint32_t tf_initializeMedia(uint32_t totalSectors);
uint32_t tf_initializeMediaNoBlock(uint32_t totalSectors, int start);
// hidden functions... IAR requires that all functions be declared
TFFile *tf_get_free_handle();
uint8_t upper(uint8_t c);
// New Datas
extern TFInfo tf_info;
extern TFFile tf_file;
#endif

View File

@ -0,0 +1,105 @@
#ifndef _THINTERNAL_H
#define _THINTERNAL_H
#define false 0
#define true 1
#pragma pack(push, 1)
// Starting at offset 36 into the BPB, this is the structure for a FAT12/16 FS
typedef struct struct_BPBFAT1216_struct {
uint8_t BS_DriveNumber; // 1
uint8_t BS_Reserved1; // 1
uint8_t BS_BootSig; // 1
uint32_t BS_VolumeID; // 4
uint8_t BS_VolumeLabel[11]; // 11
uint8_t BS_FileSystemType[8]; // 8
} BPB1216_struct;
// Starting at offset 36 into the BPB, this is the structure for a FAT32 FS
typedef struct struct_BPBFAT32_struct {
uint32_t FATSize; // 4
uint16_t ExtFlags; // 2
uint16_t FSVersion; // 2
uint32_t RootCluster; // 4
uint16_t FSInfo; // 2
uint16_t BkBootSec; // 2
uint8_t Reserved[12]; // 12
uint8_t BS_DriveNumber; // 1
uint8_t BS_Reserved1; // 1
uint8_t BS_BootSig; // 1
uint32_t BS_VolumeID; // 4
uint8_t BS_VolumeLabel[11]; // 11
uint8_t BS_FileSystemType[8]; // 8
} BPB32_struct;
typedef struct struct_BPB_struct {
uint8_t BS_JumpBoot[3]; // 3
uint8_t BS_OEMName[8]; // 8
uint16_t BytesPerSector; // 2
uint8_t SectorsPerCluster; // 1
uint16_t ReservedSectorCount; // 2
uint8_t NumFATs; // 1
uint16_t RootEntryCount; // 2
uint16_t TotalSectors16; // 2
uint8_t Media; // 1
uint16_t FATSize16; // 2
uint16_t SectorsPerTrack; // 2
uint16_t NumberOfHeads; // 2
uint32_t HiddenSectors; // 4
uint32_t TotalSectors32; // 4
union {
BPB1216_struct fat16;
BPB32_struct fat32;
} FSTypeSpecificData;
} BPB_struct;
typedef struct struct_FatFile83 {
uint8_t filename[8];
uint8_t extension[3];
uint8_t attributes;
uint8_t reserved;
uint8_t creationTimeMs;
uint16_t creationTime;
uint16_t creationDate;
uint16_t lastAccessTime;
uint16_t eaIndex;
uint16_t modifiedTime;
uint16_t modifiedDate;
uint16_t firstCluster;
uint32_t fileSize;
} FatFile83;
typedef struct struct_FatFileLFN {
uint8_t sequence_number;
uint16_t name1[5]; // 5 Chars of name (UTF 16???)
uint8_t attributes; // Always 0x0f
uint8_t reserved; // Always 0x00
uint8_t checksum; // Checksum of DOS Filename. See Docs.
uint16_t name2[6]; // 6 More chars of name (UTF-16)
uint16_t firstCluster; // Always 0x0000
uint16_t name3[2];
} FatFileLFN;
typedef union struct_FatFileEntry {
FatFile83 msdos;
FatFileLFN lfn;
} FatFileEntry;
#pragma pack(pop)
// "Legacy" functions
uint32_t fat_size(BPB_struct *bpb);
int total_sectors(BPB_struct *bpb);
int root_dir_sectors(BPB_struct *bpb);
int cluster_count(BPB_struct *bpb);
int fat_type(BPB_struct *bpb);
int first_data_sector(BPB_struct *bpb);
int first_sector_of_cluster(BPB_struct *bpb, int N);
int data_sectors(BPB_struct *bpb);
int fat_sector_number(BPB_struct *bpb, int N);
int fat_entry_offset(BPB_struct *bpb, int N);
int fat_entry_for_cluster(BPB_struct *bpb, uint8_t *buffer, int N);
#endif

View File

@ -0,0 +1,137 @@
#include "thinfat32.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fat32_ui.h"
#define NO_ERROR 0
#define FILE_OPEN_ERROR -1
#define DATA_READ_ERROR -2
#define DATA_WRITE_ERROR -3
#define DATA_MISMATCH_ERROR -4
// Tests
int basic_read(char *input_fle, char *expected);
int basic_write(char *input_file, char *write_string);
int basic_append(char *input_file, char *write_string);
int main(int argc, char **argv) {
TFFile *fp;
char data;
int rc;
printf("\r\nFAT32 Filesystem Test");
printf("\r\n-----------------------");
tf_init();
// BASIC WRITE, Root directory, LFN
printf("\r\n[TEST] Basic LFN write test ") ;
if(rc = test_basic_write("/test_longfilename0.txt", "Hello, World!")) {
printf("failed with error code 0x%x", rc) ;
}else { printf(" PASSED."); }
// BASIC READ, Root directory, LFN
printf("\r\n[TEST] Basic LFN read test ") ;
if(rc = test_basic_read("/test_longfilename0.txt", "Hello, World!")) {
printf("failed with error code 0x%x", rc) ;
}else { printf(" PASSED.\n"); }
// BASIC WRITE, Root directory, 8.3 filename
if(rc = test_basic_write("/test0.txt", "Hello, World!")) {
printf("\r\n[TEST] Basic 8.3 write test failed with error code 0x%x", rc);
}else { printf("\r\n[TEST] Basic 8.3 write test PASSED."); }
// BASIC READ, Root directory, 8.3 filename
if(rc = test_basic_read("/test0.txt", "Hello, World!")) {
printf("\r\n[TEST] Basic 8.3 read test failed with error code 0x%x", rc) ;
}else { printf("\r\n[TEST] Basic 8.3 read test PASSED."); }
return 0;
}
/*
* Open a file, read its contents, if the contents match, return 0
*If the contents don't match, or any other error occurs, return
* an appropriate error code.
*/
int test_basic_read(char *input_file, char *expected) {
TFFile *fp;
char data[128];
int size = strlen(expected);
fp = tf_fopen(input_file, "r");
int i=0;
if(fp) {
while(!tf_fread(&(data[i]), 1, fp)) {i+=1;}
data[i+1] = '\x00';
//printf("\r\n\r\nexpected: %s", expected);
//printf("\r\n\r\nreceived: %s", data);
if(strcmp(data, expected)) {
tf_fclose(fp);
return DATA_MISMATCH_ERROR;
}
else {
tf_fclose(fp);
return NO_ERROR;
}
}
else {
return FILE_OPEN_ERROR;
}
}
/*
* Open a file, write a string to it, return 0.
* Return an appropriate error code if there's any problem.
*/
int test_basic_write(char *input_file, char *write_string) {
TFFile *fp;
int rc;
fp = tf_fopen(input_file, "w");
if(fp) {
printf("\r\n[TEST] writing data to file: %s", write_string);
rc = tf_fwrite(write_string, 1, strlen(write_string), fp);
if(rc<1) {
tf_fclose(fp);
return DATA_WRITE_ERROR;
}
else {
tf_fclose(fp);
return NO_ERROR;
}
}
else {
return FILE_OPEN_ERROR;
}
}
/*
* Open a file, append a string to it, return 0.
* Return an appropriate error code if there's any problem.
*/
int test_basic_append(char *input_file, char *write_string) {
TFFile *fp;
int rc;
fp = tf_fopen(input_file, "a");
if(fp) {
rc = tf_fwrite(write_string, 1, strlen(write_string), fp);
if(rc) {
tf_fclose(fp);
return DATA_WRITE_ERROR;
}
else {
tf_fclose(fp);
return NO_ERROR;
}
}
else {
return FILE_OPEN_ERROR;
}
}

File diff suppressed because it is too large Load Diff

View 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

View File

@ -0,0 +1,77 @@
/*******************************************************************************
* *
* 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,
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

View 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_*/

View 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_

View 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 "DigitalIO.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);
}

View File

@ -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_*/

View 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 "DigitalIO.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;
}

View 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_*/

View 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_ */

View 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;
}

View 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__ */

View 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_

View 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__ */

View File

@ -0,0 +1,430 @@
/**
*
* \file
*
* \brief WINC OTA Upgrade API 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_OTA_H__
#define __M2M_OTA_H__
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/source/nmdrv.h"
/**@addtogroup WlanEnums DataTypes
* @ingroup m2m_wifi
*/
/* @{ */
/*!
@typedef void (*tpfOtaNotifCb) (tstrOtaUpdateInfo *);
@brief
A callback to get notification about a potential OTA update.
@param[in] pstrOtaUpdateInfo
A structure to provide notification payload.
@sa
tstrOtaUpdateInfo
@warning
The notification is not supported (Not implemented yet)
*/
typedef void (*tpfOtaNotifCb)(tstrOtaUpdateInfo *pstrOtaUpdateInfo);
/*!
@typedef void (*tpfOtaUpdateCb) (uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus);
@brief
A callback to get OTA status update, the callback provide the status type and its status.
The OTA callback provides the download status, the switch to the downloaded firmware status and roll-back status.
@param[in] u8OtaUpdateStatusType Possible values are listed in tenuOtaUpdateStatusType.
@param[in] u8OtaUpdateStatus Possible values are listed as enumerated by @ref tenuOtaUpdateStatus.
@see
tenuOtaUpdateStatusType
tenuOtaUpdateStatus
*/
typedef void (*tpfOtaUpdateCb)(uint8 u8OtaUpdateStatusType, uint8 u8OtaUpdateStatus);
/**@}*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup OtaInitFn m2m_ota_init
* @ingroup WLANAPI
* Synchronous initialization function for the OTA layer by registering the update callback.
* The notification callback is not supported at the current version. Calling this API is a
* MUST for all the OTA API's.
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb,tpfOtaNotifCb pfOtaNotifCb)
@param [in] pfOtaUpdateCb
OTA Update callback function
@param [in] pfOtaNotifCb
OTA notify callback function
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
/**@}*/
/** @defgroup OtaNotifStFn m2m_ota_notif_set_url
* @ingroup WLANAPI
* Set the OTA notification server URL, the functions need to be called before any check for update
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
@param [in] u8Url
Set the OTA notification server URL, the functions need to be called before any check for update.
@warning
Calling m2m_ota_init is required
Notification Server is not supported in the current version (function is not implemented)
@see
m2m_ota_init
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_set_url(uint8 *u8Url);
/**@}*/
/** @defgroup OtaNotifCheckFn m2m_ota_notif_check_for_update
* @ingroup WLANAPI
* Synchronous function to check for the OTA update using the Notification Server
* URL. Function is not implemented (not supported at the current version)
*
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_notif_check_for_update(void);
@warning
Function is not implemented (not supported at the current version)
@sa
m2m_ota_init
m2m_ota_notif_set_url
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_check_for_update(void);
/**@}*/
/** @defgroup OtaSched m2m_ota_notif_sched
* @ingroup WLANAPI
* Schedule OTA notification Server check for update request after specific number of days
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
@param [in] u32Period
Period in days
@sa
m2m_ota_init
m2m_ota_notif_check_for_update
m2m_ota_notif_set_url
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
/**@}*/
/** @defgroup OtaStartUpdatefn m2m_ota_start_update
* @ingroup WLANAPI
* Request OTA start update using the downloaded URL, the OTA module will download the OTA image and ensure integrity
*of the image, and update the validity of the image in control structure. Switching to that image requires calling @ref
*m2m_ota_switch_firmware API. As a prerequisite @ref m2m_ota_init should be called before using @ref
*m2m_ota_start().
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl);
@param [in] u8DownloadUrl
The download firmware URL, you get it from device info according to the application server
@warning
Calling this API does not guarantee OTA WINC image update, It depends on the connection with the download server and
the validity of the image. If the API response is failure this may invalidate the roll-back image if it was previously
valid, since the WINC does not have any internal memory except the flash roll-back image location to validate the
downloaded image from
@see
m2m_ota_init
tpfOtaUpdateCb
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
\section Example
The example shows an example of how the OTA image update is carried out.
@code
static void OtaUpdateCb(uint8 u8OtaUpdateStatusType ,uint8 u8OtaUpdateStatus)
{
if(u8OtaUpdateStatusType == DL_STATUS) {
if(u8OtaUpdateStatus == OTA_STATUS_SUCSESS) {
//switch to the upgraded firmware
m2m_ota_switch_firmware();
}
}
else if(u8OtaUpdateStatusType == SW_STATUS) {
if(u8OtaUpdateStatus == OTA_STATUS_SUCSESS) {
M2M_INFO("Now OTA successfully done");
//start the host SW upgrade then system reset is required (Reinitialize the driver)
}
}
}
void wifi_event_cb(uint8 u8WiFiEvent, void * pvMsg)
{
case M2M_WIFI_REQ_DHCP_CONF:
{
//after successfully connection, start the over air upgrade
m2m_ota_start_update(OTA_URL);
}
break;
default:
break;
}
int main (void)
{
tstrWifiInitParam param;
tstr1xAuthCredentials gstrCred1x = AUTH_CREDENTIALS;
nm_bsp_init();
m2m_memset((uint8*)&param, 0, sizeof(param));
param.pfAppWifiCb = wifi_event_cb;
//Initialize the WINC Driver
ret = m2m_wifi_init(&param);
if (M2M_SUCCESS != ret)
{
M2M_ERR("Driver Init Failed <%d>\n",ret);
while(1);
}
//Initialize the OTA module
m2m_ota_init(OtaUpdateCb,NULL);
//connect to AP that provide connection to the OTA server
m2m_wifi_default_connect();
while(1)
{
//Handle the app state machine plus the WINC event handler
while(m2m_wifi_handle_events(NULL) != M2M_SUCCESS) {
}
}
}
@endcode
*/
NMI_API sint8 m2m_ota_start_update(uint8 *u8DownloadUrl);
/**@}*/
/** @defgroup OtaStartUpdatefn m2m_ota_start_update_crt
* @ingroup WLANAPI
* Request OTA start for cortus application image using the downloaded URL, the OTA module will download the OTA image
*and ensure integrity of the image, and update the validity of the image in control structure. Switching to that image
*requires calling @ref m2m_ota_switch_crt API. As a prerequisite @ref m2m_ota_init should be called before using
*@ref m2m_ota_start_update_crt().
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_start_update_crt(uint8 * u8DownloadUrl);
@param [in] u8DownloadUrl
The cortus application image url.
@warning
Calling this API does not guarantee cortus application image update, It depends on the connection with the download
server and the validity of the image. If the API response is failure this may invalidate the roll-back image if it was
previously valid, since the WINC does not have any internal memory except the flash roll-back image location to validate
the downloaded image from
@see
m2m_ota_init
tpfOtaUpdateCb
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_start_update_crt(uint8 *u8DownloadUrl);
/**@}*/
/** @defgroup OtaRollbackfn m2m_ota_rollback
* @ingroup WLANAPI
Request OTA Roll-back to the old (other) WINC image, the WINC firmware will check the validation of the Roll-back
image and switch to it if it is valid. If the API response is success, system restart is required (re-initialize the
driver with hardware rest) update the host driver version may be required if it is did not match the minimum version
supported by the WINC firmware.
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_rollback(void);
@sa
m2m_ota_init
m2m_ota_start_update
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_rollback(void);
/**@}*/
/** @defgroup OtaRollbackfn m2m_ota_rollback_crt
* @ingroup WLANAPI
Request Cortus application OTA Roll-back to the old (other) cortus application image, the WINC firmware will check
the validation of the Roll-back image and switch to it if it is valid. If the API response is success, system restart is
required (re-initialize the driver with hardware rest) update the host driver version may be required.
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_rollback_crt(void);
@sa
m2m_ota_init
m2m_ota_start_update_crt
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_rollback_crt(void);
/**@}*/
/** @defgroup OtaAbortfn m2m_ota_abort
* @ingroup WLANAPI
Request abort of current OTA download.
The WINC firmware will terminate the OTA download if one is in progress.
If no download is in progress, the API will respond with failure.
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_abort(void);
@return
The function returns @ref M2M_SUCCESS for successful operation and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_abort(void);
/**@}*/
/**@}*/
/** @defgroup OtaSwitchFirmware m2m_ota_switch_firmware
* @ingroup WLANAPI
* Switch to the upgraded Firmware, that API will update the control structure working image to the upgraded image
take effect will be on the next system restart
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_switch_firmware(void);
@warning
It is important to note that if the API succeeds, system restart is required (re-initializing the driver with
hardware reset) updating the host driver version may be required if it does not match the minimum driver version
supported by the WINC's firmware.
@sa
m2m_ota_init
m2m_ota_start_update
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_switch_firmware(void);
/**@}*/
/**@}*/
/** @defgroup OtaSwitchFirmware m2m_ota_switch_crt
* @ingroup WLANAPI
* Switch to the upgraded cortus application, that API will update the control structure working image to the upgraded
image take effect will be on the next system restart
*/
/**@{*/
/*!
@fn \
NMI_API sint8 m2m_ota_switch_firmware(void);
@warning
It is important to note that if the API succeeds, system restart is required (re-initializing the driver with
hardware reset) updating the host driver version may be required if it does not match the minimum driver version
supported by the WINC's firmware.
@sa
m2m_ota_init
m2m_ota_start_update_crt
@return
The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_switch_crt(void);
/*!
@fn \
NMI_API sint8 m2m_ota_get_firmware_version(void);
@brief
Get the OTA Firmware version.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev *pstrRev);
/**@}*/
NMI_API sint8 m2m_ota_test(void);
#ifdef __cplusplus
}
#endif
#endif /* __M2M_OTA_H__ */

View File

@ -0,0 +1,404 @@
/**
*
* \file
*
* \brief WINC Peripherals Application Interface.
*
* 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
*
*/
#ifndef _M2M_PERIPH_H_
#define _M2M_PERIPH_H_
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@struct \
tstrPerphInitParam
@brief
Peripheral module initialization parameters.
*/
typedef struct {
void *arg;
} tstrPerphInitParam;
/*!
@enum \
tenuGpioNum
@brief
A list of GPIO numbers configurable through the m2m_periph module.
*/
typedef enum {
M2M_PERIPH_GPIO3, /*!< GPIO15 pad */
M2M_PERIPH_GPIO4, /*!< GPIO16 pad */
M2M_PERIPH_GPIO5, /*!< GPIO18 pad */
M2M_PERIPH_GPIO6, /*!< GPIO18 pad */
M2M_PERIPH_GPIO15, /*!< GPIO15 pad */
M2M_PERIPH_GPIO16, /*!< GPIO16 pad */
M2M_PERIPH_GPIO18, /*!< GPIO18 pad */
M2M_PERIPH_GPIO_MAX
} tenuGpioNum;
/*!
@enum \
tenuI2cMasterSclMuxOpt
@brief
Allowed pin multiplexing options for I2C master SCL signal.
*/
typedef enum {
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_HOST_WAKEUP, /*!< I2C master SCL is avaiable on HOST_WAKEUP. */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_SD_DAT3, /*!< I2C master SCL is avaiable on SD_DAT3 (GPIO 7). */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_GPIO13, /*!< I2C master SCL is avaiable on GPIO 13. */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_GPIO4, /*!< I2C master SCL is avaiable on GPIO 4.*/
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_I2C_SCL, /*!< I2C master SCL is avaiable on I2C slave SCL. */
M2M_PERIPH_I2C_MASTER_SCL_MUX_OPT_NUM
} tenuI2cMasterSclMuxOpt;
/*!
@enum \
tenuI2cMasterSdaMuxOpt
@brief
Allowed pin multiplexing options for I2C master SDA signal.
*/
typedef enum {
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_RTC_CLK, /*!< I2C master SDA is avaiable on RTC_CLK. */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_SD_CLK, /*!< I2C master SDA is avaiable on SD_CLK (GPIO 8). */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_GPIO14, /*!< I2C master SDA is avaiable on GPIO 14. */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_GPIO6, /*!< I2C master SDA is avaiable on GPIO 6.*/
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_I2C_SDA, /*!< I2C master SDA is avaiable on I2C slave SDA. */
M2M_PERIPH_I2C_MASTER_SDA_MUX_OPT_NUM
} tenuI2cMasterSdaMuxOpt;
/*!
@struct \
tstrI2cMasterInitParam
@brief
I2C master configuration parameters.
@sa
tenuI2cMasterSclMuxOpt
tenuI2cMasterSdaMuxOpt
*/
typedef struct {
uint8 enuSclMuxOpt; /*!< SCL multiplexing option. Allowed value are defined in tenuI2cMasterSclMuxOpt */
uint8 enuSdaMuxOpt; /*!< SDA multiplexing option. Allowed value are defined in tenuI2cMasterSdaMuxOpt */
uint8 u8ClkSpeedKHz; /*!< I2C master clock speed in KHz. */
} tstrI2cMasterInitParam;
/*!
@enum \
tenuI2cMasterFlags
@brief
Bitwise-ORed flags for use in m2m_periph_i2c_master_write and m2m_periph_i2c_master_read
@sa
m2m_periph_i2c_master_write
m2m_periph_i2c_master_read
*/
typedef enum {
I2C_MASTER_NO_FLAGS = 0x00,
/*!< No flags. */
I2C_MASTER_NO_STOP = 0x01,
/*!< No stop bit after this transaction. Useful for scattered buffer read/write operations. */
I2C_MASTER_NO_START = 0x02,
/*!< No start bit at the beginning of this transaction. Useful for scattered buffer read/write operations.*/
} tenuI2cMasterFlags;
/*!
@enum \
tenuPullupMask
@brief
Bitwise-ORed flags for use in m2m_perph_pullup_ctrl.
@sa
m2m_periph_pullup_ctrl
*/
typedef enum {
M2M_PERIPH_PULLUP_DIS_HOST_WAKEUP = (1ul << 0),
M2M_PERIPH_PULLUP_DIS_RTC_CLK = (1ul << 1),
M2M_PERIPH_PULLUP_DIS_IRQN = (1ul << 2),
M2M_PERIPH_PULLUP_DIS_GPIO_3 = (1ul << 3),
M2M_PERIPH_PULLUP_DIS_GPIO_4 = (1ul << 4),
M2M_PERIPH_PULLUP_DIS_GPIO_5 = (1ul << 5),
M2M_PERIPH_PULLUP_DIS_SD_DAT3 = (1ul << 6),
M2M_PERIPH_PULLUP_DIS_SD_DAT2_SPI_RXD = (1ul << 7),
M2M_PERIPH_PULLUP_DIS_SD_DAT1_SPI_SSN = (1ul << 9),
M2M_PERIPH_PULLUP_DIS_SD_CMD_SPI_SCK = (1ul << 10),
M2M_PERIPH_PULLUP_DIS_SD_DAT0_SPI_TXD = (1ul << 11),
M2M_PERIPH_PULLUP_DIS_GPIO_6 = (1ul << 12),
M2M_PERIPH_PULLUP_DIS_SD_CLK = (1ul << 13),
M2M_PERIPH_PULLUP_DIS_I2C_SCL = (1ul << 14),
M2M_PERIPH_PULLUP_DIS_I2C_SDA = (1ul << 15),
M2M_PERIPH_PULLUP_DIS_GPIO_11 = (1ul << 16),
M2M_PERIPH_PULLUP_DIS_GPIO_12 = (1ul << 17),
M2M_PERIPH_PULLUP_DIS_GPIO_13 = (1ul << 18),
M2M_PERIPH_PULLUP_DIS_GPIO_14 = (1ul << 19),
M2M_PERIPH_PULLUP_DIS_GPIO_15 = (1ul << 20),
M2M_PERIPH_PULLUP_DIS_GPIO_16 = (1ul << 21),
M2M_PERIPH_PULLUP_DIS_GPIO_17 = (1ul << 22),
M2M_PERIPH_PULLUP_DIS_GPIO_18 = (1ul << 23),
M2M_PERIPH_PULLUP_DIS_GPIO_19 = (1ul << 24),
M2M_PERIPH_PULLUP_DIS_GPIO_20 = (1ul << 25),
M2M_PERIPH_PULLUP_DIS_GPIO_21 = (1ul << 26),
M2M_PERIPH_PULLUP_DIS_GPIO_22 = (1ul << 27),
M2M_PERIPH_PULLUP_DIS_GPIO_23 = (1ul << 28),
M2M_PERIPH_PULLUP_DIS_GPIO_24 = (1ul << 29),
} tenuPullupMask;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifdef __cplusplus
extern "C" {
#endif
/*!
@fn \
NMI_API sint8 m2m_periph_init(tstrPerphInitParam * param);
@brief
Initialize the NMC1500 peripheral driver module.
@param [in] param
Peripheral module initialization structure. See members of tstrPerphInitParam.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tstrPerphInitParam
*/
NMI_API sint8 m2m_periph_init(tstrPerphInitParam *param);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir);
@brief
Configure a specific NMC1500 pad as a GPIO and sets its direction (input or output).
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param [in] u8GpioDir
GPIO direction: Zero = input. Non-zero = output.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal);
@brief
Set an NMC1500 GPIO output level high or low.
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param [in] u8GpioVal
GPIO output value. Zero = low, non-zero = high.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 * pu8GpioVal);
@brief
Read an NMC1500 GPIO input level.
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param [out] pu8GpioVal
GPIO input value. Zero = low, non-zero = high.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 *pu8GpioVal);
/*!
@fn \
NMI_API sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn);
@brief
Set an NMC1500 GPIO pullup resisitor enable or disable.
@param [in] u8GpioNum
GPIO number. Allowed values are defined in tenuGpioNum.
@param [in] u8PullupEn
Zero: pullup disabled. Non-zero: pullup enabled.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuGpioNum
*/
NMI_API sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn);
/*!
@fn \
NMI_API sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam * param);
@brief
Initialize and configure the NMC1500 I2C master peripheral.
@param [in] param
I2C master initialization structure. See members of tstrI2cMasterInitParam.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tstrI2cMasterInitParam
*/
NMI_API sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam *param);
/*!
@fn \
NMI_API sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint8 flags);
@brief
Write a stream of bytes to the I2C slave device.
@param [in] u8SlaveAddr
7-bit I2C slave address.
@param [in] pu8Buf
A pointer to an input buffer which contains a stream of bytes.
@param [in] u16BufLen
Input buffer length in bytes.
@param [in] flags
Write operation bitwise-ORed flags. See tenuI2cMasterFlags.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuI2cMasterFlags
*/
NMI_API sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 *pu8Buf, uint16 u16BufLen, uint8 flags);
/*!
@fn \
NMI_API sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 * pu8Buf, uint16 u16BufLen, uint16 * pu16ReadLen,
uint8 flags);
@brief
Write a stream of bytes to the I2C slave device.
@param [in] u8SlaveAddr
7-bit I2C slave address.
@param [out] pu8Buf
A pointer to an output buffer in which a stream of bytes are received.
@param [in] u16BufLen
Max output buffer length in bytes.
@param [out] pu16ReadLen
Actual number of bytes received.
@param [in] flags
Write operation bitwise-ORed flags. See tenuI2cMasterFlags.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuI2cMasterFlags
*/
NMI_API sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 *pu8Buf, uint16 u16BufLen, uint16 *pu16ReadLen,
uint8 flags);
/*!
@fn \
NMI_API sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable);
@brief
Control the programmable pull-up resistor on the chip pads .
@param [in] pinmask
Write operation bitwise-ORed mask for which pads to control. Allowed values are defined in
tenuPullupMask.
@param [in] enable
Set to 0 to disable pull-up resistor. Non-zero will enable the pull-up.
@return
The function SHALL return 0 for success and a negative value otherwise.
@sa
tenuPullupMask
*/
NMI_API sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable);
#ifdef __cplusplus
}
#endif
#endif /* _M2M_PERIPH_H_ */

View File

@ -0,0 +1,182 @@
/**
*
* \file
*
* \brief WINC Application Interface Internal Types.
*
* Copyright (c) 2017-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 SSLAPI SSL
*/
#ifndef __M2M_SSL_H__
#define __M2M_SSL_H__
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/source/nmdrv.h"
#include "ecc_types.h"
#include "socket/include/socket.h"
/**@defgroup SSLEnums Enumeration/Typedefs
* @ingroup SSLAPI
* @{*/
/*!
@typedef \
void (*tpfAppSslCb) (uint8 u8MsgType, void * pvMsg);
@brief A callback to get SSL notifications.
@param[in] u8MsgType
@param[in] pvMsg A structure to provide notification payload.
*/
typedef void (*tpfAppSSLCb)(uint8 u8MsgType, void *pvMsg);
/**@}
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/** \defgroup SSLFUNCTIONS Functions
* @ingroup SSLAPI
*/
/**@{*/
/*!
@fn \ m2m_ssl_init(tpfAppSslCb pfAppSslCb);
@brief Initializes the SSL layer.
@param [in] pfAppSslCb
Application SSL callback function.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb);
/*!
@fn \ NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
@brief Sends ECC responses to the WINC
@param [in] strECCResp
ECC Response struct.
@param [in] pu8RspDataBuffe
Pointer of the response data to be sent.
@param [in] u16RspDataSz
Response data size.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo *strECCResp, uint8 *pu8RspDataBuff, uint16 u16RspDataSz);
/*!
@fn \ NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
@brief Sends certificates to the WINC
@param [in] pu8Buffer
Pointer to the certificates.
@param [in] u32BufferSz
Size of the certificates.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz);
/*!
@fn \ NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint*
pu8Key)
@brief Retrieve the certificate to be verified from the WINC
@param [in] pu16CurveType
Pointer to the certificate curve type.
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] pu8Sig
Pointer to the certificate signature.
@param [in] pu8Key
Pointer to the certificate Key.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_retrieve_cert(uint16 *pu16CurveType, uint8 *pu8Hash, uint8 *pu8Sig, tstrECPoint *pu8Key);
/*!
@fn \ NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Hash, uint16 u16HashSz)
@brief Retrieve the certificate hash
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] u16HashSz
Hash size.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8 *pu8Hash, uint16 u16HashSz);
/*!
@fn \ NMI_API void m2m_ssl_stop_processing_certs(void)
@brief Allow ssl driver to tidy up in case application does not read all available certificates.
@warning This API must only be called if some certificates are left unread.
@return None.
*/
NMI_API void m2m_ssl_stop_processing_certs(void);
/*!
@fn \ NMI_API void m2m_ssl_ecc_process_done(void)
@brief Allow ssl driver to tidy up after application has finished processing ecc message.
@warning This API must be called after receiving a SSL callback with type @ref M2M_SSL_REQ_ECC
@return None.
*/
NMI_API void m2m_ssl_ecc_process_done(void);
/*!
@fn \
NMI_API sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the
form of a bitmap containing the required ciphers to be on. There is no need to call this function if the application
will not change the default ciphersuites.
@param [in] u32SslCsBMP
Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
@ref SSLCipherSuiteID.
The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC
ciphersuites. The caller can override the default with any desired combination, except for combinations involving both
RSA and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC ciphersuites. If u32SslCsBMP does not
contain any ciphersuites supported by firmware, then the current active list will not be changed.
@return
- [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)
- [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
*/
sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
/**@}*/
#endif /* __M2M_SSL_H__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,787 @@
/**
*
* \file
*
* \brief NMC1500 Peripherials Application Interface.
*
* Copyright (c) 2014 - 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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_
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "driver/include/m2m_ate_mode.h"
#include "driver/source/nmasic.h"
#include "driver/source/nmdrv.h"
#include "m2m_hif.h"
#include "driver/source/nmbus.h"
#include "bsp/include/nm_bsp.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define rInterrupt_CORTUS_0 (0x10a8)
#define rInterrupt_CORTUS_1 (0x10ac)
#define rInterrupt_CORTUS_2 (0x10b0)
#define rBurstTx_NMI_TX_RATE (0x161d00)
#define rBurstTx_NMI_NUM_TX_FRAMES (0x161d04)
#define rBurstTx_NMI_TX_FRAME_LEN (0x161d08)
#define rBurstTx_NMI_TX_CW_PARAM (0x161d0c)
#define rBurstTx_NMI_TX_GAIN (0x161d10)
#define rBurstTx_NMI_TX_DPD_CTRL (0x161d14)
#define rBurstTx_NMI_USE_PMU (0x161d18)
#define rBurstTx_NMI_TEST_CH (0x161d1c)
#define rBurstTx_NMI_TX_PHY_CONT (0x161d20)
#define rBurstTx_NMI_TX_CW_MODE (0x161d24)
#define rBurstTx_NMI_TEST_XO_OFF (0x161d28)
#define rBurstTx_NMI_USE_EFUSE_XO_OFF (0x161d2c)
#define rBurstTx_NMI_MAC_FILTER_ENABLE_DA (0x161d30)
#define rBurstTx_NMI_MAC_ADDR_LO_PEER (0x161d34)
#define rBurstTx_NMI_MAC_ADDR_LO_SELF (0x161d38)
#define rBurstTx_NMI_MAC_ADDR_HI_PEER (0x161d3c)
#define rBurstTx_NMI_MAC_ADDR_HI_SELF (0x161d40)
#define rBurstTx_NMI_RX_PKT_CNT_SUCCESS (0x161d44)
#define rBurstTx_NMI_RX_PKT_CNT_FAIL (0x161d48)
#define rBurstTx_NMI_SET_SELF_MAC_ADDR (0x161d4c)
#define rBurstTx_NMI_MAC_ADDR_LO_SA (0x161d50)
#define rBurstTx_NMI_MAC_ADDR_HI_SA (0x161d54)
#define rBurstTx_NMI_MAC_FILTER_ENABLE_SA (0x161d58)
#define rBurstRx_NMI_RX_ALL_PKTS_CONT (0x9898)
#define rBurstRx_NMI_RX_ERR_PKTS_CONT (0x988c)
#define TX_DGAIN_MAX_NUM_REGS (4)
#define TX_DGAIN_REG_BASE_ADDRESS (0x1240)
#define TX_GAIN_CODE_MAX_NUM_REGS (3)
#define TX_GAIN_CODE_BASE_ADDRESS (0x1250)
#define TX_PA_MAX_NUM_REGS (3)
#define TX_PA_BASE_ADDRESS (0x1e58)
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
VARIABLES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
volatile static uint8 gu8AteIsRunning = 0; /*!< ATE firmware status, 1 means ATE is running otherwise stopped */
volatile static uint8 gu8RxState = 0; /*!< RX status, 1 means Rx is running otherwise stopped */
volatile static uint8 gu8TxState = 0; /*!< TX status, 1 means Tx is running otherwise stopped */
volatile static uint32 gaAteFwTxRates[M2M_ATE_MAX_NUM_OF_RATES] = {
0x01, 0x02, 0x05, 0x0B, /*B-Rats*/
0x06, 0x09, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x36, /*G-Rats*/
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87 /*N-Rats*/
};
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
STATIC FUNCTIONS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static void m2m_ate_set_rx_status(uint8 u8Value)
{
gu8RxState = u8Value;
}
static void m2m_ate_set_tx_status(uint8 u8Value)
{
gu8TxState = u8Value;
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION IMPLEMENTATION
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@fn \
sint8 m2m_ate_init(void);
@brief
This function used to download ATE firmware from flash and start it
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_init(void)
{
sint8 s8Ret = M2M_SUCCESS;
uint8 u8WifiMode = M2M_WIFI_MODE_ATE_HIGH;
s8Ret = nm_drv_init(&u8WifiMode);
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_init(tstrM2mAteInit *pstrInit);
@brief
This function used to download ATE firmware from flash and start it
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_init_param(tstrM2mAteInit *pstrInit)
{
sint8 s8Ret = M2M_SUCCESS;
s8Ret = nm_drv_init((void *)&pstrInit->u8RxPwrMode);
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_deinit(void);
@brief
De-Initialization of ATE firmware mode
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_deinit(void)
{
return nm_drv_deinit(NULL);
}
/*!
@fn \
sint8 m2m_ate_set_fw_state(uint8);
@brief
This function used to change ATE firmware status from running to stopped or vice versa.
@param [in] u8State
Required state of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init
*/
sint8 m2m_ate_set_fw_state(uint8 u8State)
{
sint8 s8Ret = M2M_SUCCESS;
uint32_t u32Val = 0;
if ((M2M_ATE_FW_STATE_STOP == u8State) && (M2M_ATE_FW_STATE_STOP != gu8AteIsRunning)) {
u32Val = nm_read_reg(rNMI_GLB_RESET);
u32Val &= ~(1 << 10);
s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
gu8AteIsRunning = M2M_ATE_FW_STATE_STOP;
} else if ((M2M_ATE_FW_STATE_RUN == u8State) && (M2M_ATE_FW_STATE_RUN != gu8AteIsRunning)) {
/* 0x1118[0]=0 at power-on-reset: pad-based control. */
/* Switch cortus reset register to register control. 0x1118[0]=1. */
u32Val = nm_read_reg(rNMI_BOOT_RESET_MUX);
u32Val |= (1 << 0);
s8Ret = nm_write_reg(rNMI_BOOT_RESET_MUX, u32Val);
if (M2M_SUCCESS != s8Ret) {
goto __EXIT;
}
/**
Write the firmware download complete magic value 0x10ADD09E at
location 0xFFFF000C (Cortus map) or C000C (AHB map).
This will let the boot-rom code execute from RAM.
**/
s8Ret = nm_write_reg(0xc0000, 0x71);
if (M2M_SUCCESS != s8Ret) {
goto __EXIT;
}
u32Val = nm_read_reg(rNMI_GLB_RESET);
if ((u32Val & (1ul << 10)) == (1ul << 10)) {
u32Val &= ~(1ul << 10);
s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
if (M2M_SUCCESS != s8Ret) {
goto __EXIT;
}
}
u32Val |= (1ul << 10);
s8Ret = nm_write_reg(rNMI_GLB_RESET, u32Val);
if (M2M_SUCCESS != s8Ret) {
goto __EXIT;
}
gu8AteIsRunning = M2M_ATE_FW_STATE_RUN;
} else {
s8Ret = M2M_ATE_ERR_UNHANDLED_CASE;
}
__EXIT:
if ((M2M_SUCCESS == s8Ret) && (M2M_ATE_FW_STATE_RUN == gu8AteIsRunning)) {
nm_bsp_sleep(500); /*wait for ATE firmware start up*/
}
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_get_fw_state(uint8);
@brief
This function used to return status of ATE firmware.
@return
The function SHALL return status of ATE firmware, one of \ref tenuM2mAteFwState enumeration values.
\sa
m2m_ate_init, m2m_ate_set_fw_state
*/
sint8 m2m_ate_get_fw_state(void)
{
return gu8AteIsRunning;
}
/*!
@fn \
uint32 m2m_ate_get_tx_rate(uint8);
@brief
This function used to return value of TX rate required by application developer.
@param [in] u8Index
Index of required rate , one of \ref tenuM2mAteTxIndexOfRates enumeration values.
@return
The function SHALL return 0 for in case of failure otherwise selected rate value.
\sa
tenuM2mAteTxIndexOfRates
*/
uint32 m2m_ate_get_tx_rate(uint8 u8Index)
{
if (M2M_ATE_MAX_NUM_OF_RATES <= u8Index) {
return 0;
}
return gaAteFwTxRates[u8Index];
}
/*!
@fn \
sint8 m2m_ate_get_tx_status(void);
@brief
This function used to return status of TX test case either running or stopped.
@return
The function SHALL return status of ATE firmware, 1 if TX is running otherwise 0.
\sa
m2m_ate_start_tx, m2m_ate_stop_tx
*/
sint8 m2m_ate_get_tx_status(void)
{
return gu8TxState;
}
/*!
@fn \
sint8 m2m_ate_start_tx(tstrM2mAteTx *)
@brief
This function used to start TX test case.
@param [in] strM2mAteTx
Type of \ref tstrM2mAteTx, with the values required to enable TX test case. You must use \ref m2m_ate_init
first.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_stop_tx, m2m_ate_get_tx_status
*/
sint8 m2m_ate_start_tx(tstrM2mAteTx *strM2mAteTx)
{
sint8 s8Ret = M2M_SUCCESS;
uint8 u8LoopCntr = 0;
uint32_t val32;
if (NULL == strM2mAteTx) {
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
if (0 != m2m_ate_get_tx_status()) {
s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
goto __EXIT;
}
if (0 != m2m_ate_get_rx_status()) {
s8Ret = M2M_ATE_ERR_RX_ALREADY_RUNNING;
goto __EXIT;
}
if ((strM2mAteTx->channel_num < M2M_ATE_CHANNEL_1) || (strM2mAteTx->channel_num > M2M_ATE_CHANNEL_14)
|| (strM2mAteTx->tx_gain_sel < M2M_ATE_TX_GAIN_DYNAMIC) || (strM2mAteTx->tx_gain_sel > M2M_ATE_TX_GAIN_TELEC)
|| (strM2mAteTx->frame_len > M2M_ATE_MAX_FRAME_LENGTH) || (strM2mAteTx->frame_len < M2M_ATE_MIN_FRAME_LENGTH)) {
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
if ((strM2mAteTx->duty_cycle < M2M_ATE_TX_DUTY_MAX_VALUE /*1*/)
|| (strM2mAteTx->duty_cycle > M2M_ATE_TX_DUTY_MIN_VALUE /*10*/)
|| (strM2mAteTx->dpd_ctrl < M2M_ATE_TX_DPD_DYNAMIC) || (strM2mAteTx->dpd_ctrl > M2M_ATE_TX_DPD_ENABLED)
|| (strM2mAteTx->use_pmu > M2M_ATE_PMU_ENABLE) || (strM2mAteTx->phy_burst_tx < M2M_ATE_TX_SRC_MAC)
|| (strM2mAteTx->phy_burst_tx > M2M_ATE_TX_SRC_PHY) || (strM2mAteTx->cw_tx < M2M_ATE_TX_MODE_NORM)
|| (strM2mAteTx->cw_tx > M2M_ATE_TX_MODE_CW)) {
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
for (u8LoopCntr = 0; u8LoopCntr < M2M_ATE_MAX_NUM_OF_RATES; u8LoopCntr++) {
if (gaAteFwTxRates[u8LoopCntr] == strM2mAteTx->data_rate) {
break;
}
}
if (M2M_ATE_MAX_NUM_OF_RATES == u8LoopCntr) {
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
s8Ret += nm_write_reg(rBurstTx_NMI_USE_PMU, strM2mAteTx->use_pmu);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_PHY_CONT, strM2mAteTx->phy_burst_tx);
s8Ret += nm_write_reg(rBurstTx_NMI_NUM_TX_FRAMES, strM2mAteTx->num_frames);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_GAIN, strM2mAteTx->tx_gain_sel);
s8Ret += nm_write_reg(rBurstTx_NMI_TEST_CH, strM2mAteTx->channel_num);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_FRAME_LEN, strM2mAteTx->frame_len);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_CW_PARAM, strM2mAteTx->duty_cycle);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_DPD_CTRL, strM2mAteTx->dpd_ctrl);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_RATE, strM2mAteTx->data_rate);
s8Ret += nm_write_reg(rBurstTx_NMI_TX_CW_MODE, strM2mAteTx->cw_tx);
s8Ret += nm_write_reg(rBurstTx_NMI_TEST_XO_OFF, strM2mAteTx->xo_offset_x1000);
s8Ret += nm_write_reg(rBurstTx_NMI_USE_EFUSE_XO_OFF, strM2mAteTx->use_efuse_xo_offset);
val32 = strM2mAteTx->peer_mac_addr[5] << 0;
val32 |= strM2mAteTx->peer_mac_addr[4] << 8;
val32 |= strM2mAteTx->peer_mac_addr[3] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_PEER, val32);
val32 = strM2mAteTx->peer_mac_addr[2] << 0;
val32 |= strM2mAteTx->peer_mac_addr[1] << 8;
val32 |= strM2mAteTx->peer_mac_addr[0] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_PEER, val32);
if (M2M_SUCCESS == s8Ret) {
s8Ret += nm_write_reg(rInterrupt_CORTUS_0, 1); /*Interrupt Cortus*/
m2m_ate_set_tx_status(1);
nm_bsp_sleep(200); /*Recommended*/
}
__EXIT:
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_stop_tx(void)
@brief
This function used to stop TX test case.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_start_tx, m2m_ate_get_tx_status
*/
sint8 m2m_ate_stop_tx(void)
{
sint8 s8Ret = M2M_SUCCESS;
s8Ret = nm_write_reg(rInterrupt_CORTUS_1, 1);
if (M2M_SUCCESS == s8Ret) {
m2m_ate_set_tx_status(0);
}
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_get_rx_status(uint8);
@brief
This function used to return status of RX test case either running or stopped.
@return
The function SHALL return status of ATE firmware, 1 if RX is running otherwise 0.
\sa
m2m_ate_start_rx, m2m_ate_stop_rx
*/
sint8 m2m_ate_get_rx_status(void)
{
return gu8RxState;
}
/*!
@fn \
sint8 m2m_ate_start_rx(tstrM2mAteRx *)
@brief
This function used to start RX test case.
@param [in] strM2mAteRx
Type of \ref tstrM2mAteRx, with the values required to enable RX test case. You must use \ref m2m_ate_init
first.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_stop_rx, m2m_ate_get_rx_status
*/
sint8 m2m_ate_start_rx(tstrM2mAteRx *strM2mAteRxStr)
{
sint8 s8Ret = M2M_SUCCESS;
uint32 val32;
if (NULL == strM2mAteRxStr) {
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
if (0 != m2m_ate_get_tx_status()) {
s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
goto __EXIT;
}
if (0 != m2m_ate_get_rx_status()) {
s8Ret = M2M_ATE_ERR_RX_ALREADY_RUNNING;
goto __EXIT;
}
if ((strM2mAteRxStr->channel_num < M2M_ATE_CHANNEL_1) || (strM2mAteRxStr->channel_num > M2M_ATE_CHANNEL_14)
|| (strM2mAteRxStr->use_pmu > M2M_ATE_PMU_ENABLE)) {
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
s8Ret += nm_write_reg(rBurstTx_NMI_TEST_CH, strM2mAteRxStr->channel_num);
s8Ret += nm_write_reg(rBurstTx_NMI_USE_PMU, strM2mAteRxStr->use_pmu);
s8Ret += nm_write_reg(rBurstTx_NMI_TEST_XO_OFF, strM2mAteRxStr->xo_offset_x1000);
s8Ret += nm_write_reg(rBurstTx_NMI_USE_EFUSE_XO_OFF, strM2mAteRxStr->use_efuse_xo_offset);
if (strM2mAteRxStr->override_self_mac_addr) {
val32 = strM2mAteRxStr->self_mac_addr[5] << 0;
val32 |= strM2mAteRxStr->self_mac_addr[4] << 8;
val32 |= strM2mAteRxStr->self_mac_addr[3] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_SELF, val32);
val32 = strM2mAteRxStr->self_mac_addr[2] << 0;
val32 |= strM2mAteRxStr->self_mac_addr[1] << 8;
val32 |= strM2mAteRxStr->self_mac_addr[0] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_SELF, val32);
}
if (strM2mAteRxStr->mac_filter_en_sa) {
val32 = strM2mAteRxStr->peer_mac_addr[5] << 0;
val32 |= strM2mAteRxStr->peer_mac_addr[4] << 8;
val32 |= strM2mAteRxStr->peer_mac_addr[3] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_LO_SA, val32);
val32 = strM2mAteRxStr->peer_mac_addr[2] << 0;
val32 |= strM2mAteRxStr->peer_mac_addr[1] << 8;
val32 |= strM2mAteRxStr->peer_mac_addr[0] << 16;
nm_write_reg(rBurstTx_NMI_MAC_ADDR_HI_SA, val32);
}
nm_write_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_DA, strM2mAteRxStr->mac_filter_en_da);
nm_write_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_SA, strM2mAteRxStr->mac_filter_en_sa);
nm_write_reg(rBurstTx_NMI_SET_SELF_MAC_ADDR, strM2mAteRxStr->override_self_mac_addr);
if (M2M_SUCCESS == s8Ret) {
s8Ret += nm_write_reg(rInterrupt_CORTUS_2, 1); /*Interrupt Cortus*/
m2m_ate_set_rx_status(1);
nm_bsp_sleep(10); /*Recommended*/
}
__EXIT:
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_stop_rx(void)
@brief
This function used to stop RX test case.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_start_rx, m2m_ate_get_rx_status
*/
sint8 m2m_ate_stop_rx(void)
{
m2m_ate_set_rx_status(0);
nm_bsp_sleep(200); /*Recommended*/
return M2M_SUCCESS;
}
/*!
@fn \
sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *)
@brief
This function used to read RX statistics from ATE firmware.
@param [out] strM2mAteRxStatus
Type of \ref tstrM2mAteRxStatus used to save statistics of RX test case. You must use \ref m2m_ate_start_rx
first.
@return
The function SHALL return 0 for success and a negative value otherwise.
\sa
m2m_ate_init, m2m_ate_start_rx
*/
sint8 m2m_ate_read_rx_status(tstrM2mAteRxStatus *strM2mAteRxStatus)
{
sint8 s8Ret = M2M_SUCCESS;
if (NULL == strM2mAteRxStatus) {
s8Ret = M2M_ATE_ERR_VALIDATE;
goto __EXIT;
}
if (0 != m2m_ate_get_tx_status()) {
s8Ret = M2M_ATE_ERR_TX_ALREADY_RUNNING;
goto __EXIT;
}
if (nm_read_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_DA) || nm_read_reg(rBurstTx_NMI_MAC_FILTER_ENABLE_SA)) {
strM2mAteRxStatus->num_rx_pkts
= nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_SUCCESS) + nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_FAIL);
strM2mAteRxStatus->num_good_pkts = nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_SUCCESS);
strM2mAteRxStatus->num_err_pkts = nm_read_reg(rBurstTx_NMI_RX_PKT_CNT_FAIL);
} else {
strM2mAteRxStatus->num_rx_pkts = nm_read_reg(rBurstRx_NMI_RX_ALL_PKTS_CONT) + nm_read_reg(0x989c);
strM2mAteRxStatus->num_err_pkts = nm_read_reg(rBurstRx_NMI_RX_ERR_PKTS_CONT);
strM2mAteRxStatus->num_good_pkts = strM2mAteRxStatus->num_rx_pkts - strM2mAteRxStatus->num_err_pkts;
}
__EXIT:
return s8Ret;
}
/*!
@fn \
sint8 m2m_ate_set_dig_gain(double dGaindB)
@brief
This function is used to set the digital gain
@param [in] double dGaindB
The digital gain value required to be set.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_set_dig_gain(double dGaindB)
{
uint32_t dGain, val32;
dGain = (uint32_t)(pow(10, dGaindB / 20.0) * 1024.0);
val32 = nm_read_reg(0x160cd0);
val32 &= ~(0x1ffful << 0);
val32 |= (((uint32_t)dGain) << 0);
nm_write_reg(0x160cd0, val32);
return M2M_SUCCESS;
}
/*!
@fn \
sint8 m2m_ate_get_dig_gain(double * dGaindB)
@brief
This function is used to get the digital gain
@param [out] double * dGaindB
The retrieved digital gain value obtained from HW registers in dB.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_dig_gain(double *dGaindB)
{
uint32 dGain, val32;
if (!dGaindB)
return M2M_ERR_INVALID_ARG;
val32 = nm_read_reg(0x160cd0);
dGain = (val32 >> 0) & 0x1ffful;
*dGaindB = 20.0 * log10((double)dGain / 1024.0);
return M2M_SUCCESS;
}
/*!
@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)
{
uint32 PA_1e9c;
uint8 aGain[] = {/* "0 dB" */ 0x00,
/* "3 dB" */ 0x01,
/* "6 dB" */ 0x03,
/* "9 dB" */ 0x07,
/* "12 dB" */ 0x0f,
/* "15 dB" */ 0x1f,
/* "18 dB" */ 0x3f};
/* The variable PA gain is valid only for High power mode */
PA_1e9c = nm_read_reg(0x1e9c);
/* TX bank 0. */
PA_1e9c &= ~(0x3ful << 8);
PA_1e9c |= (((uint32)aGain[gain_db / 3] & 0x3f) << 8);
nm_write_reg(0x1e9c, PA_1e9c);
}
/*!
@fn \
sint8 m2m_ate_get_pa_gain(double *paGaindB)
@brief
This function is used to get the PA gain
@param [out] double *paGaindB
The retrieved PA gain value obtained from HW registers in dB.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_pa_gain(double *paGaindB)
{
uint32 val32, paGain;
uint32 m_cmbPAGainStep;
if (!paGaindB)
return M2M_ERR_INVALID_ARG;
val32 = nm_read_reg(0x1e9c);
paGain = (val32 >> 8) & 0x3f;
switch (paGain) {
case 0x1:
m_cmbPAGainStep = 5;
break;
case 0x3:
m_cmbPAGainStep = 4;
break;
case 0x7:
m_cmbPAGainStep = 3;
break;
case 0xf:
m_cmbPAGainStep = 2;
break;
case 0x1f:
m_cmbPAGainStep = 1;
break;
case 0x3f:
m_cmbPAGainStep = 0;
break;
default:
m_cmbPAGainStep = 0;
break;
}
*paGaindB = 18 - m_cmbPAGainStep * 3;
return M2M_SUCCESS;
}
/*!
@fn \
sint8 m2m_ate_get_ppa_gain(double * ppaGaindB)
@brief
This function is used to get the 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.
*/
sint8 m2m_ate_get_ppa_gain(double *ppaGaindB)
{
uint32 val32, ppaGain, m_cmbPPAGainStep;
if (!ppaGaindB)
return M2M_ERR_INVALID_ARG;
val32 = nm_read_reg(0x1ea0);
ppaGain = (val32 >> 5) & 0x7;
switch (ppaGain) {
case 0x1:
m_cmbPPAGainStep = 2;
break;
case 0x3:
m_cmbPPAGainStep = 1;
break;
case 0x7:
m_cmbPPAGainStep = 0;
break;
default:
m_cmbPPAGainStep = 3;
break;
}
*ppaGaindB = 9 - m_cmbPPAGainStep * 3;
return M2M_SUCCESS;
}
/*!
@fn \
sint8 m2m_ate_get_tot_gain(double * totGaindB)
@brief
This function is used to calculate the total gain
@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 0 for success and a negative value otherwise.
*/
sint8 m2m_ate_get_tot_gain(double *totGaindB)
{
double dGaindB, paGaindB, ppaGaindB;
if (!totGaindB)
return M2M_ERR_INVALID_ARG;
m2m_ate_get_pa_gain(&paGaindB);
m2m_ate_get_ppa_gain(&ppaGaindB);
m2m_ate_get_dig_gain(&dGaindB);
*totGaindB = dGaindB + paGaindB + ppaGaindB;
return M2M_SUCCESS;
}
#endif //_M2M_ATE_FW_

View File

@ -0,0 +1,949 @@
/**
*
* \file m2m_crypto.c
*
* \brief WINC Crypto module.
*
* Copyright (c) 2014 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "driver/include/m2m_crypto.h"
#include "driver/source/nmbus.h"
#include "driver/source/nmasic.h"
#ifdef CONF_CRYPTO_HW
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*======*======*======*======*======*=======*
* WINC SHA256 HW Engine Register Definition *
*======*======*======*======*======*========*/
#define SHA_BLOCK_SIZE (64)
#define SHARED_MEM_BASE (0xd0000)
#define SHA256_MEM_BASE (0x180000UL)
#define SHA256_ENGINE_ADDR (0x180000ul)
/* SHA256 Registers */
#define SHA256_CTRL (SHA256_MEM_BASE + 0x00)
#define SHA256_CTRL_START_CALC_MASK (NBIT0)
#define SHA256_CTRL_START_CALC_SHIFT (0)
#define SHA256_CTRL_PREPROCESS_MASK (NBIT1)
#define SHA256_CTRL_PREPROCESS_SHIFT (1)
#define SHA256_CTRL_HASH_HASH_MASK (NBIT2)
#define SHA256_CTRL_HASH_HASH_SHIFT (2)
#define SHA256_CTRL_INIT_SHA256_STATE_MASK (NBIT3)
#define SHA256_CTRL_INIT_SHA256_STATE_SHIFT (3)
#define SHA256_CTRL_WR_BACK_HASH_VALUE_MASK (NBIT4)
#define SHA256_CTRL_WR_BACK_HASH_VALUE_SHIFT (4)
#define SHA256_CTRL_FORCE_SHA256_QUIT_MASK (NBIT5)
#define SHA256_CTRL_FORCE_SHA256_QUIT_SHIFT (5)
#define SHA256_REGS_SHA256_CTRL_AHB_BYTE_REV_EN (NBIT6)
#define SHA256_REGS_SHA256_CTRL_RESERVED (NBIT7)
#define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO (NBIT8 + NBIT9 + NBIT10)
#define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_MASK (NBIT2 + NBIT1 + NBIT0)
#define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_SHIFT (8)
#define SHA256_REGS_SHA256_CTRL_RESERVED_11 (NBIT11)
#define SHA256_REGS_SHA256_CTRL_SHA1_CALC (NBIT12)
#define SHA256_REGS_SHA256_CTRL_PBKDF2_SHA1_CALC (NBIT13)
#define SHA256_START_RD_ADDR (SHA256_MEM_BASE + 0x04UL)
#define SHA256_DATA_LENGTH (SHA256_MEM_BASE + 0x08UL)
#define SHA256_START_WR_ADDR (SHA256_MEM_BASE + 0x0cUL)
#define SHA256_COND_CHK_CTRL (SHA256_MEM_BASE + 0x10)
#define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_MASK (NBIT1 | NBIT0)
#define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_SHIFT (0)
#define SHA256_COND_CHK_CTRL_STEP_VAL_MASK (NBIT6 | NBIT5 | NBIT4 | NBIT3 | NBIT2)
#define SHA256_COND_CHK_CTRL_STEP_VAL_SHIFT (2)
#define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_MASK (NBIT7)
#define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_SHIFT (7)
#define SHA256_MOD_DATA_RANGE (SHA256_MEM_BASE + 0x14)
#define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_MASK (NBIT24 - 1)
#define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_SHIFT (0)
#define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_MASK (NBIT24 | NBIT25 | NBIT26)
#define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_SHIFT (24)
#define SHA256_COND_CHK_STS_1 (SHA256_MEM_BASE + 0x18)
#define SHA256_COND_CHK_STS_2 (SHA256_MEM_BASE + 0x1c)
#define SHA256_DONE_INTR_ENABLE (SHA256_MEM_BASE + 0x20)
#define SHA256_DONE_INTR_STS (SHA256_MEM_BASE + 0x24)
#define SHA256_TARGET_HASH_H1 (SHA256_MEM_BASE + 0x28)
#define SHA256_TARGET_HASH_H2 (SHA256_MEM_BASE + 0x2c)
#define SHA256_TARGET_HASH_H3 (SHA256_MEM_BASE + 0x30)
#define SHA256_TARGET_HASH_H4 (SHA256_MEM_BASE + 0x34)
#define SHA256_TARGET_HASH_H5 (SHA256_MEM_BASE + 0x38)
#define SHA256_TARGET_HASH_H6 (SHA256_MEM_BASE + 0x3c)
#define SHA256_TARGET_HASH_H7 (SHA256_MEM_BASE + 0x40)
#define SHA256_TARGET_HASH_H8 (SHA256_MEM_BASE + 0x44)
/*======*======*======*======*======*=======*
* WINC BIGINT HW Engine Register Definition *
*======*======*======*======*======*========*/
#define BIGINT_ENGINE_ADDR (0x180080ul)
#define BIGINT_VERSION (BIGINT_ENGINE_ADDR + 0x00)
#define BIGINT_MISC_CTRL (BIGINT_ENGINE_ADDR + 0x04)
#define BIGINT_MISC_CTRL_CTL_START (NBIT0)
#define BIGINT_MISC_CTRL_CTL_RESET (NBIT1)
#define BIGINT_MISC_CTRL_CTL_MSW_FIRST (NBIT2)
#define BIGINT_MISC_CTRL_CTL_SWAP_BYTE_ORDER (NBIT3)
#define BIGINT_MISC_CTRL_CTL_FORCE_BARRETT (NBIT4)
#define BIGINT_MISC_CTRL_CTL_M_PRIME_VALID (NBIT5)
#define BIGINT_M_PRIME (BIGINT_ENGINE_ADDR + 0x08)
#define BIGINT_STATUS (BIGINT_ENGINE_ADDR + 0x0C)
#define BIGINT_STATUS_STS_DONE (NBIT0)
#define BIGINT_CLK_COUNT (BIGINT_ENGINE_ADDR + 0x10)
#define BIGINT_ADDR_X (BIGINT_ENGINE_ADDR + 0x14)
#define BIGINT_ADDR_E (BIGINT_ENGINE_ADDR + 0x18)
#define BIGINT_ADDR_M (BIGINT_ENGINE_ADDR + 0x1C)
#define BIGINT_ADDR_R (BIGINT_ENGINE_ADDR + 0x20)
#define BIGINT_LENGTH (BIGINT_ENGINE_ADDR + 0x24)
#define BIGINT_IRQ_STS (BIGINT_ENGINE_ADDR + 0x28)
#define BIGINT_IRQ_STS_DONE (NBIT0)
#define BIGINT_IRQ_STS_CHOOSE_MONT (NBIT1)
#define BIGINT_IRQ_STS_M_READ (NBIT2)
#define BIGINT_IRQ_STS_X_READ (NBIT3)
#define BIGINT_IRQ_STS_START (NBIT4)
#define BIGINT_IRQ_STS_PRECOMP_FINISH (NBIT5)
#define BIGINT_IRQ_MASK (BIGINT_ENGINE_ADDR + 0x2C)
#define BIGINT_IRQ_MASK_CTL_IRQ_MASK_START (NBIT4)
#define ENABLE_FLIPPING 1
#define GET_UINT32(BUF, OFFSET) \
(((uint32)((BUF)[OFFSET])) | ((uint32)(((BUF)[OFFSET + 1]) << 8)) | ((uint32)(((BUF)[OFFSET + 2]) << 16)) \
| ((uint32)(((BUF)[OFFSET + 3]) << 24)))
#define PUTU32(VAL32, BUF, OFFSET) \
do { \
(BUF)[OFFSET] = BYTE_3((VAL32)); \
(BUF)[OFFSET + 1] = BYTE_2((VAL32)); \
(BUF)[OFFSET + 2] = BYTE_1((VAL32)); \
(BUF)[OFFSET + 3] = BYTE_0((VAL32)); \
} while (0)
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@struct \
tstrHashContext
@brief
*/
typedef struct {
uint32 au32HashState[M2M_SHA256_DIGEST_LEN / 4];
uint8 au8CurrentBlock[64];
uint32 u32TotalLength;
uint8 u8InitHashFlag;
} tstrSHA256HashCtxt;
/*======*======*======*======*======*=======*
* SHA256 IMPLEMENTATION *
*======*======*======*======*======*========*/
sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *pstrSha256Ctxt)
{
tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt *)pstrSha256Ctxt;
if (pstrSHA256 != NULL) {
m2m_memset((uint8 *)pstrSha256Ctxt, 0, sizeof(tstrM2mSha256Ctxt));
pstrSHA256->u8InitHashFlag = 1;
}
return 0;
}
sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
{
sint8 s8Ret = M2M_ERR_FAIL;
tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt *)pstrSha256Ctxt;
if (pstrSHA256 != NULL) {
uint32 u32ReadAddr;
uint32 u32WriteAddr = SHARED_MEM_BASE;
uint32 u32Addr = u32WriteAddr;
uint32 u32ResidualBytes;
uint32 u32NBlocks;
uint32 u32Offset;
uint32 u32CurrentBlock = 0;
uint8 u8IsDone = 0;
/* Get the remaining bytes from the previous update (if the length is not block aligned). */
u32ResidualBytes = pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE;
/* Update the total data length. */
pstrSHA256->u32TotalLength += u16DataLength;
if (u32ResidualBytes != 0) {
if ((u32ResidualBytes + u16DataLength) >= SHA_BLOCK_SIZE) {
u32Offset = SHA_BLOCK_SIZE - u32ResidualBytes;
m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset);
pu8Data += u32Offset;
u16DataLength -= u32Offset;
nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
u32Addr += SHA_BLOCK_SIZE;
u32CurrentBlock = 1;
} else {
m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u16DataLength);
u16DataLength = 0;
}
}
/* Get the number of HASH BLOCKs and the residual bytes. */
u32NBlocks = u16DataLength / SHA_BLOCK_SIZE;
u32ResidualBytes = u16DataLength % SHA_BLOCK_SIZE;
if (u32NBlocks != 0) {
nm_write_block(u32Addr, pu8Data, (uint16)(u32NBlocks * SHA_BLOCK_SIZE));
pu8Data += (u32NBlocks * SHA_BLOCK_SIZE);
}
u32NBlocks += u32CurrentBlock;
if (u32NBlocks != 0) {
uint32 u32RegVal = 0;
nm_write_reg(SHA256_CTRL, u32RegVal);
u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
nm_write_reg(SHA256_CTRL, u32RegVal);
if (pstrSHA256->u8InitHashFlag) {
pstrSHA256->u8InitHashFlag = 0;
u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
}
u32ReadAddr = u32WriteAddr + (u32NBlocks * SHA_BLOCK_SIZE);
nm_write_reg(SHA256_DATA_LENGTH, (u32NBlocks * SHA_BLOCK_SIZE));
nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
u32RegVal |= SHA256_CTRL_START_CALC_MASK;
u32RegVal &= ~(0x7 << 8);
u32RegVal |= (2 << 8);
nm_write_reg(SHA256_CTRL, u32RegVal);
/* 5. Wait for done_intr */
while (!u8IsDone) {
u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
u8IsDone = u32RegVal & NBIT0;
}
}
if (u32ResidualBytes != 0) {
m2m_memcpy(pstrSHA256->au8CurrentBlock, pu8Data, u32ResidualBytes);
}
s8Ret = M2M_SUCCESS;
}
return s8Ret;
}
sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Sha256Digest)
{
sint8 s8Ret = M2M_ERR_FAIL;
tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt *)pstrSha256Ctxt;
if (pstrSHA256 != NULL) {
uint32 u32ReadAddr;
uint32 u32WriteAddr = SHARED_MEM_BASE;
uint32 u32Addr = u32WriteAddr;
uint16 u16Offset;
uint16 u16PaddingLength;
uint16 u16NBlocks = 1;
uint32 u32RegVal = 0;
uint32 u32Idx, u32ByteIdx;
uint32 au32Digest[M2M_SHA256_DIGEST_LEN / 4];
uint8 u8IsDone = 0;
nm_write_reg(SHA256_CTRL, u32RegVal);
u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
nm_write_reg(SHA256_CTRL, u32RegVal);
if (pstrSHA256->u8InitHashFlag) {
pstrSHA256->u8InitHashFlag = 0;
u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
}
/* Calculate the offset of the last data byte in the current block. */
u16Offset = (uint16)(pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE);
/* Add the padding byte 0x80. */
pstrSHA256->au8CurrentBlock[u16Offset++] = 0x80;
/* Calculate the required padding to complete
one Hash Block Size.
*/
u16PaddingLength = SHA_BLOCK_SIZE - u16Offset;
m2m_memset(&pstrSHA256->au8CurrentBlock[u16Offset], 0, u16PaddingLength);
/* If the padding count is not enough to hold 64-bit representation of
the total input message length, one padding block is required.
*/
if (u16PaddingLength < 8) {
nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
u32Addr += SHA_BLOCK_SIZE;
m2m_memset(pstrSHA256->au8CurrentBlock, 0, SHA_BLOCK_SIZE);
u16NBlocks++;
}
/* pack the length at the end of the padding block */
PUTU32(pstrSHA256->u32TotalLength << 3, pstrSHA256->au8CurrentBlock, (SHA_BLOCK_SIZE - 4));
u32ReadAddr = u32WriteAddr + (u16NBlocks * SHA_BLOCK_SIZE);
nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
nm_write_reg(SHA256_DATA_LENGTH, (u16NBlocks * SHA_BLOCK_SIZE));
nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
u32RegVal |= SHA256_CTRL_START_CALC_MASK;
u32RegVal |= SHA256_CTRL_WR_BACK_HASH_VALUE_MASK;
u32RegVal &= ~(0x7UL << 8);
u32RegVal |= (0x2UL << 8);
nm_write_reg(SHA256_CTRL, u32RegVal);
/* 5. Wait for done_intr */
while (!u8IsDone) {
u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
u8IsDone = u32RegVal & NBIT0;
}
nm_read_block(u32ReadAddr, (uint8 *)au32Digest, 32);
/* Convert the output words to an array of bytes.
*/
u32ByteIdx = 0;
for (u32Idx = 0; u32Idx < (M2M_SHA256_DIGEST_LEN / 4); u32Idx++) {
pu8Sha256Digest[u32ByteIdx++] = BYTE_3(au32Digest[u32Idx]);
pu8Sha256Digest[u32ByteIdx++] = BYTE_2(au32Digest[u32Idx]);
pu8Sha256Digest[u32ByteIdx++] = BYTE_1(au32Digest[u32Idx]);
pu8Sha256Digest[u32ByteIdx++] = BYTE_0(au32Digest[u32Idx]);
}
s8Ret = M2M_SUCCESS;
}
return s8Ret;
}
/*======*======*======*======*======*=======*
* RSA IMPLEMENTATION *
*======*======*======*======*======*========*/
static void FlipBuffer(uint8 *pu8InBuffer, uint8 *pu8OutBuffer, uint16 u16BufferSize)
{
uint16 u16Idx;
for (u16Idx = 0; u16Idx < u16BufferSize; u16Idx++) {
#if ENABLE_FLIPPING == 1
pu8OutBuffer[u16Idx] = pu8InBuffer[u16BufferSize - u16Idx - 1];
#else
pu8OutBuffer[u16Idx] = pu8InBuffer[u16Idx];
#endif
}
}
void BigInt_ModExp(uint8 *pu8X, uint16 u16XSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8M, uint16 u16MSize,
uint8 *pu8R, uint16 u16RSize)
{
uint32 u32Reg;
uint8 au8Tmp[780] = {0};
uint32 u32XAddr = SHARED_MEM_BASE;
uint32 u32MAddr;
uint32 u32EAddr;
uint32 u32RAddr;
uint8 u8EMswBits = 32;
uint32 u32Mprime = 0x7F;
uint16 u16XSizeWords, u16ESizeWords;
uint32 u32Exponent;
u16XSizeWords = (u16XSize + 3) / 4;
u16ESizeWords = (u16ESize + 3) / 4;
u32MAddr = u32XAddr + (u16XSizeWords * 4);
u32EAddr = u32MAddr + (u16XSizeWords * 4);
u32RAddr = u32EAddr + (u16ESizeWords * 4);
/* Reset the core.
*/
u32Reg = 0;
u32Reg |= BIGINT_MISC_CTRL_CTL_RESET;
u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
u32Reg &= ~BIGINT_MISC_CTRL_CTL_RESET;
u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
nm_write_block(u32RAddr, au8Tmp, u16RSize);
/* Write Input Operands to Chip Memory.
*/
/*------- X -------*/
FlipBuffer(pu8X, au8Tmp, u16XSize);
nm_write_block(u32XAddr, au8Tmp, u16XSizeWords * 4);
/*------- E -------*/
m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
FlipBuffer(pu8E, au8Tmp, u16ESize);
nm_write_block(u32EAddr, au8Tmp, u16ESizeWords * 4);
u32Exponent = GET_UINT32(au8Tmp, (u16ESizeWords * 4) - 4);
while ((u32Exponent & NBIT31) == 0) {
u32Exponent <<= 1;
u8EMswBits--;
}
/*------- M -------*/
m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
FlipBuffer(pu8M, au8Tmp, u16XSize);
nm_write_block(u32MAddr, au8Tmp, u16XSizeWords * 4);
/* Program the addresses of the input operands.
*/
nm_write_reg(BIGINT_ADDR_X, u32XAddr);
nm_write_reg(BIGINT_ADDR_E, u32EAddr);
nm_write_reg(BIGINT_ADDR_M, u32MAddr);
nm_write_reg(BIGINT_ADDR_R, u32RAddr);
/* Mprime.
*/
nm_write_reg(BIGINT_M_PRIME, u32Mprime);
/* Length.
*/
u32Reg = (u16XSizeWords & 0xFF);
u32Reg += ((u16ESizeWords & 0xFF) << 8);
u32Reg += (u8EMswBits << 16);
nm_write_reg(BIGINT_LENGTH, u32Reg);
/* CTRL Register.
*/
u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
u32Reg ^= BIGINT_MISC_CTRL_CTL_START;
u32Reg |= BIGINT_MISC_CTRL_CTL_FORCE_BARRETT;
// u32Reg |= BIGINT_MISC_CTRL_CTL_M_PRIME_VALID;
#if ENABLE_FLIPPING == 0
u32Reg |= BIGINT_MISC_CTRL_CTL_MSW_FIRST;
#endif
nm_write_reg(BIGINT_MISC_CTRL, u32Reg);
/* Wait for computation to complete. */
while (1) {
u32Reg = nm_read_reg(BIGINT_IRQ_STS);
if (u32Reg & BIGINT_IRQ_STS_DONE) {
break;
}
}
nm_write_reg(BIGINT_IRQ_STS, 0);
m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
nm_read_block(u32RAddr, au8Tmp, u16RSize);
FlipBuffer(au8Tmp, pu8R, u16RSize);
}
#define MD5_DIGEST_SIZE (16)
#define SHA1_DIGEST_SIZE (20)
static const uint8 au8TEncodingMD5[]
= {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04};
/*!< Fixed part of the Encoding T for the MD5 hash algorithm.
*/
static const uint8 au8TEncodingSHA1[]
= {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04};
/*!< Fixed part of the Encoding T for the SHA-1 hash algorithm.
*/
static const uint8 au8TEncodingSHA2[]
= {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04};
/*!< Fixed part of the Encoding T for the SHA-2 hash algorithm.
*/
sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
uint16 u16HashLength, uint8 *pu8RsaSignature)
{
sint8 s8Ret = M2M_RSA_SIGN_FAIL;
if ((pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL)) {
uint16 u16TLength, u16TEncodingLength;
uint8 *pu8T;
uint8 au8EM[512];
/* Selection of correct T Encoding based on the hash size.
*/
if (u16HashLength == MD5_DIGEST_SIZE) {
pu8T = (uint8 *)au8TEncodingMD5;
u16TEncodingLength = sizeof(au8TEncodingMD5);
} else if (u16HashLength == SHA1_DIGEST_SIZE) {
pu8T = (uint8 *)au8TEncodingSHA1;
u16TEncodingLength = sizeof(au8TEncodingSHA1);
} else {
pu8T = (uint8 *)au8TEncodingSHA2;
u16TEncodingLength = sizeof(au8TEncodingSHA2);
}
u16TLength = u16TEncodingLength + 1 + u16HashLength;
/* If emLen < tLen + 11.
*/
if (u16NSize >= (u16TLength + 11)) {
uint32 u32PSLength, u32Idx = 0;
/*
RSA verification
*/
BigInt_ModExp(pu8RsaSignature, u16NSize, pu8E, u16ESize, pu8N, u16NSize, au8EM, u16NSize);
u32PSLength = u16NSize - u16TLength - 3;
/*
The calculated EM must match the following pattern.
*======*======*======*======*======*
* 0x00 || 0x01 || PS || 0x00 || T *
*======*======*======*======*======*
Where PS is all 0xFF
T is defined based on the hash algorithm.
*/
if ((au8EM[0] == 0x00) && (au8EM[1] == 0x01)) {
for (u32Idx = 2; au8EM[u32Idx] == 0xFF; u32Idx++)
;
if (u32Idx == (u32PSLength + 2)) {
if (au8EM[u32Idx++] == 0x00) {
if (!m2m_memcmp(&au8EM[u32Idx], pu8T, u16TEncodingLength)) {
u32Idx += u16TEncodingLength;
if (au8EM[u32Idx++] == u16HashLength)
s8Ret = m2m_memcmp(&au8EM[u32Idx], pu8SignedMsgHash, u16HashLength);
}
}
}
}
}
}
return s8Ret;
}
sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
uint16 u16HashLength, uint8 *pu8RsaSignature)
{
sint8 s8Ret = M2M_RSA_SIGN_FAIL;
if ((pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL)) {
uint16 u16TLength, u16TEncodingLength;
uint8 *pu8T;
uint8 au8EM[512];
/* Selection of correct T Encoding based on the hash size.
*/
if (u16HashLength == MD5_DIGEST_SIZE) {
pu8T = (uint8 *)au8TEncodingMD5;
u16TEncodingLength = sizeof(au8TEncodingMD5);
} else if (u16HashLength == SHA1_DIGEST_SIZE) {
pu8T = (uint8 *)au8TEncodingSHA1;
u16TEncodingLength = sizeof(au8TEncodingSHA1);
} else {
pu8T = (uint8 *)au8TEncodingSHA2;
u16TEncodingLength = sizeof(au8TEncodingSHA2);
}
u16TLength = u16TEncodingLength + 1 + u16HashLength;
/* If emLen < tLen + 11.
*/
if (u16NSize >= (u16TLength + 11)) {
uint16 u16PSLength = 0;
uint16 u16Offset = 0;
/*
The calculated EM must match the following pattern.
*======*======*======*======*======*
* 0x00 || 0x01 || PS || 0x00 || T *
*======*======*======*======*======*
Where PS is all 0xFF
T is defined based on the hash algorithm.
*/
au8EM[u16Offset++] = 0;
au8EM[u16Offset++] = 1;
u16PSLength = u16NSize - u16TLength - 3;
m2m_memset(&au8EM[u16Offset], 0xFF, u16PSLength);
u16Offset += u16PSLength;
au8EM[u16Offset++] = 0;
m2m_memcpy(&au8EM[u16Offset], pu8T, u16TEncodingLength);
u16Offset += u16TEncodingLength;
au8EM[u16Offset++] = u16HashLength;
m2m_memcpy(&au8EM[u16Offset], pu8SignedMsgHash, u16HashLength);
/*
RSA Signature Generation
*/
BigInt_ModExp(au8EM, u16NSize, pu8d, u16dSize, pu8N, u16NSize, pu8RsaSignature, u16NSize);
s8Ret = M2M_RSA_SIGN_OK;
}
}
return s8Ret;
}
#endif /* CONF_CRYPTO */
#ifdef CONF_CRYPTO_SOFT
typedef struct {
tpfAppCryproCb pfAppCryptoCb;
uint8 * pu8Digest;
uint8 * pu8Rsa;
uint8 u8CryptoBusy;
} tstrCryptoCtxt;
typedef struct {
uint8 au8N[M2M_MAX_RSA_LEN];
uint8 au8E[M2M_MAX_RSA_LEN];
uint8 au8Hash[M2M_SHA256_DIGEST_LEN];
uint16 u16Nsz;
uint16 u16Esz;
uint16 u16Hsz;
uint8 _pad16_[2];
} tstrRsaPayload;
static tstrCryptoCtxt gstrCryptoCtxt;
/**
* @fn m2m_crypto_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
* @brief WiFi call back function
* @param [in] u8OpCode
* HIF Opcode type.
* @param [in] u16DataSize
* HIF data length.
* @param [in] u32Addr
* HIF address.
* @author
* @date
* @version 1.0
*/
static void m2m_crypto_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
sint8 ret = M2M_SUCCESS;
gstrCryptoCtxt.u8CryptoBusy = 0;
if (u8OpCode == M2M_CRYPTO_RESP_SHA256_INIT) {
tstrM2mSha256Ctxt strCtxt;
if (hif_receive(u32Addr, (uint8 *)&strCtxt, sizeof(tstrM2mSha256Ctxt), 0) == M2M_SUCCESS) {
tstrCyptoResp strResp;
if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8 *)&strResp, sizeof(tstrCyptoResp), 1)
== M2M_SUCCESS) {
if (gstrCryptoCtxt.pfAppCryptoCb)
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, &strCtxt);
}
}
} else if (u8OpCode == M2M_CRYPTO_RESP_SHA256_UPDATE) {
tstrM2mSha256Ctxt strCtxt;
if (hif_receive(u32Addr, (uint8 *)&strCtxt, sizeof(tstrM2mSha256Ctxt), 0) == M2M_SUCCESS) {
tstrCyptoResp strResp;
if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8 *)&strResp, sizeof(tstrCyptoResp), 1)
== M2M_SUCCESS) {
if (gstrCryptoCtxt.pfAppCryptoCb)
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, &strCtxt);
}
}
} else if (u8OpCode == M2M_CRYPTO_RESP_SHA256_FINSIH) {
tstrCyptoResp strResp;
if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8 *)&strResp, sizeof(tstrCyptoResp), 0)
== M2M_SUCCESS) {
if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt) + sizeof(tstrCyptoResp),
(uint8 *)gstrCryptoCtxt.pu8Digest,
M2M_SHA256_DIGEST_LEN,
1)
== M2M_SUCCESS) {
if (gstrCryptoCtxt.pfAppCryptoCb)
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, gstrCryptoCtxt.pu8Digest);
}
}
} else if (u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_GEN) {
tstrCyptoResp strResp;
if (hif_receive(u32Addr + sizeof(tstrRsaPayload), (uint8 *)&strResp, sizeof(tstrCyptoResp), 0) == M2M_SUCCESS) {
if (hif_receive(u32Addr + sizeof(tstrRsaPayload) + sizeof(tstrCyptoResp),
(uint8 *)gstrCryptoCtxt.pu8Rsa,
M2M_MAX_RSA_LEN,
0)
== M2M_SUCCESS) {
if (gstrCryptoCtxt.pfAppCryptoCb)
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, gstrCryptoCtxt.pu8Rsa);
}
}
} else if (u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_VERIFY) {
tstrCyptoResp strResp;
if (hif_receive(u32Addr + sizeof(tstrRsaPayload), (uint8 *)&strResp, sizeof(tstrCyptoResp), 1) == M2M_SUCCESS) {
if (gstrCryptoCtxt.pfAppCryptoCb)
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, NULL);
}
} else {
M2M_ERR("u8Code %d ??\n", u8OpCode);
}
}
/*!
@fn \
sint8 m2m_crypto_init();
@brief crypto initialization
@param[in] pfAppCryproCb
*/
sint8 m2m_crypto_init(tpfAppCryproCb pfAppCryproCb)
{
sint8 ret = M2M_ERR_FAIL;
m2m_memset((uint8 *)&gstrCryptoCtxt, 0, sizeof(tstrCryptoCtxt));
if (pfAppCryproCb != NULL) {
gstrCryptoCtxt.pfAppCryptoCb = pfAppCryproCb;
ret = hif_register_cb(M2M_REQ_GROUP_CRYPTO, m2m_crypto_cb);
}
return ret;
}
/*!
@fn \
sint8 m2m_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt);
@brief SHA256 hash initialization
@param[in] psha256Ctxt
Pointer to a sha256 context allocated by the caller.
*/
sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt)
{
sint8 ret = M2M_ERR_FAIL;
if ((psha256Ctxt != NULL) && (!gstrCryptoCtxt.u8CryptoBusy)) {
ret = hif_send(M2M_REQ_GROUP_CRYPTO,
M2M_CRYPTO_REQ_SHA256_INIT | M2M_REQ_DATA_PKT,
(uint8 *)psha256Ctxt,
sizeof(tstrM2mSha256Ctxt),
NULL,
0,
0);
}
return ret;
}
/*!
@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.
*/
sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
{
sint8 ret = M2M_ERR_FAIL;
if ((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Data != NULL)
&& (u16DataLength < M2M_SHA256_MAX_DATA)) {
ret = hif_send(M2M_REQ_GROUP_CRYPTO,
M2M_CRYPTO_REQ_SHA256_UPDATE | M2M_REQ_DATA_PKT,
(uint8 *)psha256Ctxt,
sizeof(tstrM2mSha256Ctxt),
pu8Data,
u16DataLength,
sizeof(tstrM2mSha256Ctxt) + sizeof(tstrCyptoResp));
}
return ret;
}
/*!
@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.
*/
sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest)
{
sint8 ret = M2M_ERR_FAIL;
if ((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Sha256Digest != NULL)) {
gstrCryptoCtxt.pu8Digest = pu8Sha256Digest;
ret = hif_send(M2M_REQ_GROUP_CRYPTO,
M2M_CRYPTO_REQ_SHA256_FINSIH | M2M_REQ_DATA_PKT,
(uint8 *)psha256Ctxt,
sizeof(tstrM2mSha256Ctxt),
NULL,
0,
0);
}
return ret;
}
/*!
@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.
*/
sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
uint16 u16HashLength, uint8 *pu8RsaSignature)
{
sint8 ret = M2M_ERR_FAIL;
if ((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL)
&& (pu8SignedMsgHash != NULL) && (u16NSize != 0) && (u16ESize != 0) && (u16HashLength != 0)
&& (pu8RsaSignature != NULL))
{
tstrRsaPayload strRsa = {0};
m2m_memcpy(strRsa.au8N, pu8N, u16NSize);
m2m_memcpy(strRsa.au8E, pu8E, u16ESize);
m2m_memcpy(strRsa.au8Hash, pu8SignedMsgHash, u16HashLength);
strRsa.u16Esz = u16ESize;
strRsa.u16Hsz = u16HashLength;
strRsa.u16Nsz = u16NSize;
ret = hif_send(M2M_REQ_GROUP_CRYPTO,
M2M_CRYPTO_REQ_RSA_SIGN_VERIFY | M2M_REQ_DATA_PKT,
(uint8 *)&strRsa,
sizeof(tstrRsaPayload),
NULL,
0,
0);
}
return ret;
}
/*!
@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.
*/
sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
uint16 u16HashLength, uint8 *pu8RsaSignature)
{
sint8 ret = M2M_ERR_FAIL;
if ((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL)
&& (pu8SignedMsgHash != NULL) && (u16NSize != 0) && (u16dSize != 0) && (u16HashLength != 0)
&& (pu8RsaSignature != NULL))
{
tstrRsaPayload strRsa = {0};
m2m_memcpy(strRsa.au8N, pu8N, u16NSize);
m2m_memcpy(strRsa.au8E, pu8d, u16dSize);
m2m_memcpy(strRsa.au8Hash, pu8SignedMsgHash, u16HashLength);
strRsa.u16Esz = u16dSize;
strRsa.u16Hsz = u16HashLength;
strRsa.u16Nsz = u16NSize;
gstrCryptoCtxt.pu8Rsa = pu8RsaSignature;
ret = hif_send(M2M_REQ_GROUP_CRYPTO,
M2M_CRYPTO_REQ_RSA_SIGN_GEN | M2M_REQ_DATA_PKT,
(uint8 *)&strRsa,
sizeof(tstrRsaPayload),
NULL,
0,
0);
}
return ret;
}
#endif

View File

@ -0,0 +1,679 @@
/**
*
* \file
*
* \brief This module contains M2M host interface APIs implementation.
*
* 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
*
*/
#include "common/include/nm_common.h"
#include "driver/source/nmbus.h"
#include "bsp/include/nm_bsp.h"
#include "m2m_hif.h"
#include "driver/include/m2m_types.h"
#include "driver/source/nmasic.h"
#include "driver/include/m2m_periph.h"
#if (defined NM_EDGE_INTERRUPT) && (defined NM_LEVEL_INTERRUPT)
#error "only one type of interrupt NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
#endif
#if !((defined NM_EDGE_INTERRUPT) || (defined NM_LEVEL_INTERRUPT))
#error "define interrupt type NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
#endif
#ifndef CORTUS_APP
#define NMI_AHB_DATA_MEM_BASE 0x30000
#define NMI_AHB_SHARE_MEM_BASE 0xd0000
#define WIFI_HOST_RCV_CTRL_0 (0x1070)
#define WIFI_HOST_RCV_CTRL_1 (0x1084)
#define WIFI_HOST_RCV_CTRL_2 (0x1078)
#define WIFI_HOST_RCV_CTRL_3 (0x106c)
#define WIFI_HOST_RCV_CTRL_4 (0x150400)
#define WIFI_HOST_RCV_CTRL_5 (0x1088)
typedef struct {
uint8 u8ChipMode;
uint8 u8ChipSleep;
uint8 u8HifRXDone;
uint8 u8Interrupt;
uint8 u8Yield;
uint32 u32RxAddr;
uint32 u32RxSize;
tpfHifCallBack pfWifiCb;
tpfHifCallBack pfIpCb;
tpfHifCallBack pfOtaCb;
tpfHifCallBack pfSigmaCb;
tpfHifCallBack pfHifCb;
tpfHifCallBack pfCryptoCb;
tpfHifCallBack pfSslCb;
} tstrHifContext;
volatile tstrHifContext gstrHifCxt;
#ifdef ETH_MODE
extern void os_hook_isr(void);
#endif
static void isr(void)
{
gstrHifCxt.u8Interrupt++;
#ifdef NM_LEVEL_INTERRUPT
nm_bsp_interrupt_ctrl(0);
#endif
#ifdef ETH_MODE
os_hook_isr();
#endif
}
static sint8 hif_set_rx_done(void)
{
uint32 reg;
sint8 ret = M2M_SUCCESS;
gstrHifCxt.u8HifRXDone = 0;
#ifdef NM_EDGE_INTERRUPT
nm_bsp_interrupt_ctrl(1);
#endif
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
if (ret != M2M_SUCCESS)
goto ERR1;
/* Set RX Done */
reg |= NBIT1;
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0, reg);
if (ret != M2M_SUCCESS)
goto ERR1;
#ifdef NM_LEVEL_INTERRUPT
nm_bsp_interrupt_ctrl(1);
#endif
ERR1:
return ret;
}
/**
* @fn static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
* @brief WiFi call back function
* @param [in] u8OpCode
* HIF Opcode type.
* @param [in] u16DataSize
* HIF data length.
* @param [in] u32Addr
* HIF address.
* @param [in] grp
* HIF group type.
* @author
* @date
* @version 1.0
*/
static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
}
/**
* @fn NMI_API sint8 hif_chip_wake(void);
* @brief To Wakeup the chip.
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_chip_wake(void)
{
sint8 ret = M2M_SUCCESS;
if (gstrHifCxt.u8HifRXDone) {
/*chip already wake for the rx not done no need to send wake request*/
return ret;
}
if (gstrHifCxt.u8ChipSleep == 0) {
if (gstrHifCxt.u8ChipMode != M2M_NO_PS) {
ret = chip_wake();
if (ret != M2M_SUCCESS)
goto ERR1;
} else {
}
}
gstrHifCxt.u8ChipSleep++;
ERR1:
return ret;
}
/*!
@fn \
NMI_API void hif_set_sleep_mode(uint8 u8Pstype);
@brief
Set the sleep mode of the HIF layer.
@param [in] u8Pstype
Sleep mode.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
void hif_set_sleep_mode(uint8 u8Pstype)
{
gstrHifCxt.u8ChipMode = u8Pstype;
}
/*!
@fn \
NMI_API uint8 hif_get_sleep_mode(void);
@brief
Get the sleep mode of the HIF layer.
@return
The function SHALL return the sleep mode of the HIF layer.
*/
uint8 hif_get_sleep_mode(void)
{
return gstrHifCxt.u8ChipMode;
}
/**
* @fn NMI_API sint8 hif_chip_sleep_sc(void);
* @brief To clear the chip sleep but keep the chip sleep
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_chip_sleep_sc(void)
{
if (gstrHifCxt.u8ChipSleep >= 1) {
gstrHifCxt.u8ChipSleep--;
}
return M2M_SUCCESS;
}
/**
* @fn NMI_API sint8 hif_chip_sleep(void);
* @brief To make the chip sleep.
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_chip_sleep(void)
{
sint8 ret = M2M_SUCCESS;
if (gstrHifCxt.u8ChipSleep >= 1) {
gstrHifCxt.u8ChipSleep--;
}
if (gstrHifCxt.u8ChipSleep == 0) {
if (gstrHifCxt.u8ChipMode != M2M_NO_PS) {
ret = chip_sleep();
if (ret != M2M_SUCCESS)
goto ERR1;
} else {
}
}
ERR1:
return ret;
}
/**
* @fn NMI_API sint8 hif_init(void * arg);
* @brief To initialize HIF layer.
* @param [in] arg
* Pointer to the arguments.
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_init(void *arg)
{
m2m_memset((uint8 *)&gstrHifCxt, 0, sizeof(tstrHifContext));
nm_bsp_register_isr(isr);
hif_register_cb(M2M_REQ_GROUP_HIF, m2m_hif_cb);
return M2M_SUCCESS;
}
/**
* @fn NMI_API sint8 hif_deinit(void * arg);
* @brief To De-initialize HIF layer.
* @param [in] arg
* Pointer to the arguments.
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_deinit(void *arg)
{
sint8 ret = M2M_SUCCESS;
ret = hif_chip_wake();
m2m_memset((uint8 *)&gstrHifCxt, 0, sizeof(tstrHifContext));
return ret;
}
/**
* @fn NMI_API sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
* @brief Send packet using host interface.
* @param [in] u8Gid
* Group ID.
* @param [in] u8Opcode
* Operation ID.
* @param [in] pu8CtrlBuf
* Pointer to the Control buffer.
* @param [in] u16CtrlBufSize
Control buffer size.
* @param [in] u16DataOffset
Packet Data offset.
* @param [in] pu8DataBuf
* Packet buffer Allocated by the caller.
* @param [in] u16DataSize
Packet buffer size (including the HIF header).
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_send(uint8 u8Gid, uint8 u8Opcode, uint8 *pu8CtrlBuf, uint16 u16CtrlBufSize, uint8 *pu8DataBuf,
uint16 u16DataSize, uint16 u16DataOffset)
{
sint8 ret = M2M_ERR_SEND;
volatile tstrHifHdr strHif;
strHif.u8Opcode = u8Opcode & (~NBIT7);
strHif.u8Gid = u8Gid;
strHif.u16Length = M2M_HIF_HDR_OFFSET;
if (pu8DataBuf != NULL) {
strHif.u16Length += u16DataOffset + u16DataSize;
} else {
strHif.u16Length += u16CtrlBufSize;
}
ret = hif_chip_wake();
if (ret == M2M_SUCCESS) {
volatile uint32 reg, dma_addr = 0;
volatile uint16 cnt = 0;
//#define OPTIMIZE_BUS
/*please define in firmware also*/
#ifndef OPTIMIZE_BUS
reg = 0UL;
reg |= (uint32)u8Gid;
reg |= ((uint32)u8Opcode << 8);
reg |= ((uint32)strHif.u16Length << 16);
ret = nm_write_reg(NMI_STATE_REG, reg);
if (M2M_SUCCESS != ret)
goto ERR1;
reg = 0UL;
reg |= NBIT1;
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
if (M2M_SUCCESS != ret)
goto ERR1;
#else
reg = 0UL;
reg |= NBIT1;
reg |= ((u8Opcode & NBIT7) ? (NBIT2) : (0)); /*Data = 1 or config*/
reg |= (u8Gid == M2M_REQ_GROUP_IP) ? (NBIT3) : (0); /*IP = 1 or non IP*/
reg |= ((uint32)strHif.u16Length << 4); /*length of pkt max = 4096*/
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
if (M2M_SUCCESS != ret)
goto ERR1;
#endif
dma_addr = 0;
for (cnt = 0; cnt < 1000; cnt++) {
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2, (uint32 *)&reg);
if (ret != M2M_SUCCESS)
break;
/*
* If it takes too long to get a response, the slow down to
* avoid back-to-back register read operations.
*/
if (cnt >= 500) {
if (cnt < 501) {
M2M_INFO("Slowing down...\n");
}
nm_bsp_sleep(1);
}
if (!(reg & NBIT1)) {
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4, (uint32 *)&dma_addr);
if (ret != M2M_SUCCESS) {
/*in case of read error clear the DMA address and return error*/
dma_addr = 0;
goto ERR1;
}
/*in case of success break */
break;
}
}
if (dma_addr != 0) {
volatile uint32 u32CurrAddr;
u32CurrAddr = dma_addr;
strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length);
ret = nm_write_block(u32CurrAddr, (uint8 *)&strHif, M2M_HIF_HDR_OFFSET);
if (M2M_SUCCESS != ret)
goto ERR1;
u32CurrAddr += M2M_HIF_HDR_OFFSET;
if (pu8CtrlBuf != NULL) {
ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize);
if (M2M_SUCCESS != ret)
goto ERR1;
u32CurrAddr += u16CtrlBufSize;
}
if (pu8DataBuf != NULL) {
u32CurrAddr += (u16DataOffset - u16CtrlBufSize);
ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize);
if (M2M_SUCCESS != ret)
goto ERR1;
u32CurrAddr += u16DataSize;
}
reg = dma_addr << 2;
reg |= NBIT1;
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg);
if (M2M_SUCCESS != ret)
goto ERR1;
} else {
ret = hif_chip_sleep();
M2M_DBG("Failed to alloc rx size %d\r", ret);
ret = M2M_ERR_MEM_ALLOC;
goto ERR2;
}
} else {
M2M_ERR("(HIF)Fail to wakup the chip\n");
goto ERR2;
}
/*actual sleep ret = M2M_SUCCESS*/
ret = hif_chip_sleep();
return ret;
ERR1:
/*reset the count but no actual sleep as it already bus error*/
hif_chip_sleep_sc();
ERR2:
/*logical error*/
return ret;
}
/**
* @fn hif_isr
* @brief Host interface interrupt service routine
* @author M. Abdelmawla
* @date 15 July 2012
* @return 1 in case of interrupt received else 0 will be returned
* @version 1.0
*/
static sint8 hif_isr(void)
{
sint8 ret = M2M_SUCCESS;
uint32 reg;
volatile tstrHifHdr strHif;
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, &reg);
if (M2M_SUCCESS == ret) {
if (reg & 0x1) /* New interrupt has been received */
{
uint16 size;
nm_bsp_interrupt_ctrl(0);
/*Clearing RX interrupt*/
reg &= ~NBIT0;
ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0, reg);
if (ret != M2M_SUCCESS)
goto ERR1;
gstrHifCxt.u8HifRXDone = 1;
size = (uint16)((reg >> 2) & 0xfff);
if (size > 0) {
uint32 address = 0;
/**
start bus transfer
**/
ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1, &address);
if (M2M_SUCCESS != ret) {
M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_1 bus fail\n");
nm_bsp_interrupt_ctrl(1);
goto ERR1;
}
gstrHifCxt.u32RxAddr = address;
gstrHifCxt.u32RxSize = size;
ret = nm_read_block(address, (uint8 *)&strHif, sizeof(tstrHifHdr));
strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length);
if (M2M_SUCCESS != ret) {
M2M_ERR("(hif) address bus fail\n");
nm_bsp_interrupt_ctrl(1);
goto ERR1;
}
if (strHif.u16Length != size) {
if ((size - strHif.u16Length) > 4) {
M2M_ERR("(hif) Corrupted packet Size = %u <L = %u, G = %u, OP = %02X>\n",
size,
strHif.u16Length,
strHif.u8Gid,
strHif.u8Opcode);
nm_bsp_interrupt_ctrl(1);
ret = M2M_ERR_BUS_FAIL;
goto ERR1;
}
}
if (M2M_REQ_GROUP_WIFI == strHif.u8Gid) {
if (gstrHifCxt.pfWifiCb)
gstrHifCxt.pfWifiCb(
strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
else
M2M_ERR("WIFI callback is not registered\n");
} else if (M2M_REQ_GROUP_IP == strHif.u8Gid) {
if (gstrHifCxt.pfIpCb)
gstrHifCxt.pfIpCb(
strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
else
M2M_ERR("Scoket callback is not registered\n");
} else if (M2M_REQ_GROUP_OTA == strHif.u8Gid) {
if (gstrHifCxt.pfOtaCb)
gstrHifCxt.pfOtaCb(
strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
else
M2M_ERR("Ota callback is not registered\n");
} else if (M2M_REQ_GROUP_CRYPTO == strHif.u8Gid) {
if (gstrHifCxt.pfCryptoCb)
gstrHifCxt.pfCryptoCb(
strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
else
M2M_ERR("Crypto callback is not registered\n");
} else if (M2M_REQ_GROUP_SIGMA == strHif.u8Gid) {
if (gstrHifCxt.pfSigmaCb)
gstrHifCxt.pfSigmaCb(
strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
else
M2M_ERR("Sigma callback is not registered\n");
} else if (M2M_REQ_GROUP_SSL == strHif.u8Gid) {
if (gstrHifCxt.pfSslCb)
gstrHifCxt.pfSslCb(
strHif.u8Opcode, strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
} else {
M2M_ERR("(hif) invalid group ID\n");
ret = M2M_ERR_BUS_FAIL;
goto ERR1;
}
if (gstrHifCxt.u8HifRXDone) {
M2M_ERR("(hif) host app didn't set RX Done <%u><%X>\n", strHif.u8Gid, strHif.u8Opcode);
ret = hif_set_rx_done();
if (ret != M2M_SUCCESS)
goto ERR1;
}
} else {
M2M_ERR("(hif) Wrong Size\n");
ret = M2M_ERR_RCV;
goto ERR1;
}
} else {
#ifndef WIN32
M2M_ERR("(hif) False interrupt %lx", reg);
ret = M2M_ERR_FAIL;
goto ERR1;
#else
#endif
}
} else {
M2M_ERR("(hif) Fail to Read interrupt reg\n");
goto ERR1;
}
ERR1:
return ret;
}
/**
* @fn hif_yield(void)
* @brief
Yields control from interrupt event handler.
*/
void hif_yield(void)
{
gstrHifCxt.u8Yield = 1;
}
/**
* @fn hif_handle_isr(void)
* @brief Handle interrupt received from NMC1500 firmware.
* @return The function SHALL return 0 for success and a negative value otherwise.
*/
sint8 hif_handle_isr(void)
{
sint8 ret = M2M_SUCCESS;
gstrHifCxt.u8Yield = 0;
while (gstrHifCxt.u8Interrupt && !gstrHifCxt.u8Yield) {
/*must be at that place because of the race of interrupt increment and that decrement*/
/*when the interrupt enabled*/
gstrHifCxt.u8Interrupt--;
while (1) {
ret = hif_isr();
if (ret == M2M_SUCCESS) {
/*we will try forever untill we get that interrupt*/
/*Fail return errors here due to bus errors (reading expected values)*/
break;
} else {
M2M_ERR("(HIF) Fail to handle interrupt %d try Again..\n", ret);
}
}
}
return ret;
}
/*
* @fn hif_receive
* @brief Host interface interrupt serviece routine
* @param [in] u32Addr
* Receive start address
* @param [out] pu8Buf
* Pointer to receive buffer. Allocated by the caller
* @param [in] u16Sz
* Receive buffer size
* @param [in] isDone
* If you don't need any more packets send True otherwise send false
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_receive(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz, uint8 isDone)
{
sint8 ret = M2M_SUCCESS;
if ((u32Addr == 0) || (pu8Buf == NULL) || (u16Sz == 0)) {
if (isDone) {
/* set RX done */
ret = hif_set_rx_done();
} else {
ret = M2M_ERR_FAIL;
M2M_ERR(" hif_receive: Invalid argument\n");
}
goto ERR1;
}
if (u16Sz > gstrHifCxt.u32RxSize) {
ret = M2M_ERR_FAIL;
M2M_ERR("APP Requested Size is larger than the recived buffer size <%u><%lu>\n", u16Sz, gstrHifCxt.u32RxSize);
goto ERR1;
}
if ((u32Addr < gstrHifCxt.u32RxAddr) || ((u32Addr + u16Sz) > (gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize))) {
ret = M2M_ERR_FAIL;
M2M_ERR("APP Requested Address beyond the recived buffer address and length\n");
goto ERR1;
}
/* Receive the payload */
ret = nm_read_block(u32Addr, pu8Buf, u16Sz);
if (ret != M2M_SUCCESS)
goto ERR1;
/* check if this is the last packet */
if ((((gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize) - (u32Addr + u16Sz)) <= 0) || isDone) {
/* set RX done */
ret = hif_set_rx_done();
}
ERR1:
return ret;
}
/**
* @fn hif_register_cb
* @brief To set Callback function for every compantent Component
* @param [in] u8Grp
* Group to which the Callback function should be set.
* @param [in] fn
* function to be set
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
sint8 hif_register_cb(uint8 u8Grp, tpfHifCallBack fn)
{
sint8 ret = M2M_SUCCESS;
switch (u8Grp) {
case M2M_REQ_GROUP_IP:
gstrHifCxt.pfIpCb = fn;
break;
case M2M_REQ_GROUP_WIFI:
gstrHifCxt.pfWifiCb = fn;
break;
case M2M_REQ_GROUP_OTA:
gstrHifCxt.pfOtaCb = fn;
break;
case M2M_REQ_GROUP_HIF:
gstrHifCxt.pfHifCb = fn;
break;
case M2M_REQ_GROUP_CRYPTO:
gstrHifCxt.pfCryptoCb = fn;
break;
case M2M_REQ_GROUP_SIGMA:
gstrHifCxt.pfSigmaCb = fn;
break;
case M2M_REQ_GROUP_SSL:
gstrHifCxt.pfSslCb = fn;
break;
default:
M2M_ERR("GRp ? %d\n", u8Grp);
ret = M2M_ERR_FAIL;
break;
}
return ret;
}
#endif

View File

@ -0,0 +1,255 @@
/**
*
* \file
*
* \brief This module contains M2M host interface APIs implementation.
*
* 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_HIF_
#define _M2M_HIF_
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
/*!< Include depends on UNO Board is used or not*/
#ifdef ENABLE_UNO_BOARD
#include "m2m_uno_hif.h"
#endif
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define M2M_HIF_MAX_PACKET_SIZE (1600 - 4)
/*!< Maximum size of the buffer could be transferred between Host and Firmware.
*/
#define M2M_HIF_HDR_OFFSET (sizeof(tstrHifHdr) + 4)
/**
* @struct tstrHifHdr
* @brief Structure to hold HIF header
*/
typedef struct {
uint8 u8Gid; /*!< Group ID */
uint8 u8Opcode; /*!< OP code */
uint16 u16Length; /*!< Payload length */
} tstrHifHdr;
#ifdef __cplusplus
extern "C" {
#endif
/*!
@typedef typedef void (*tpfHifCallBack)(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr);
@brief used to point to Wi-Fi call back function depend on Arduino project or other projects.
@param [in] u8OpCode
HIF Opcode type.
@param [in] u16DataSize
HIF data length.
@param [in] u32Addr
HIF address.
@param [in] grp
HIF group type.
*/
typedef void (*tpfHifCallBack)(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr);
/**
* @fn NMI_API sint8 hif_init(void * arg);
* @brief
To initialize HIF layer.
* @param [in] arg
* Pointer to the arguments.
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_init(void *arg);
/**
* @fn NMI_API sint8 hif_deinit(void * arg);
* @brief
To Deinitialize HIF layer.
* @param [in] arg
* Pointer to the arguments.
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_deinit(void *arg);
/**
* @fn NMI_API sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
* @brief Send packet using host interface.
* @param [in] u8Gid
* Group ID.
* @param [in] u8Opcode
* Operation ID.
* @param [in] pu8CtrlBuf
* Pointer to the Control buffer.
* @param [in] u16CtrlBufSize
Control buffer size.
* @param [in] u16DataOffset
Packet Data offset.
* @param [in] pu8DataBuf
* Packet buffer Allocated by the caller.
* @param [in] u16DataSize
Packet buffer size (including the HIF header).
* @return The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_send(uint8 u8Gid, uint8 u8Opcode, uint8 *pu8CtrlBuf, uint16 u16CtrlBufSize, uint8 *pu8DataBuf,
uint16 u16DataSize, uint16 u16DataOffset);
/*
* @fn hif_receive
* @brief Host interface interrupt serviece routine
* @param [in] u32Addr
* Receive start address
* @param [out] pu8Buf
* Pointer to receive buffer. Allocated by the caller
* @param [in] u16Sz
* Receive buffer size
* @param [in] isDone
* If you don't need any more packets send True otherwise send false
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_receive(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz, uint8 isDone);
/**
* @fn hif_register_cb
* @brief
To set Callback function for every Component.
* @param [in] u8Grp
* Group to which the Callback function should be set.
* @param [in] fn
* function to be set to the specified group.
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_register_cb(uint8 u8Grp, tpfHifCallBack fn);
/**
* @fn NMI_API sint8 hif_chip_sleep(void);
* @brief
To make the chip sleep.
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_chip_sleep(void);
/**
* @fn NMI_API sint8 hif_chip_sleep_sc(void);
* @brief
To clear the chip count only but keep the chip awake
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_chip_sleep_sc(void);
/**
* @fn NMI_API sint8 hif_chip_wake(void);
* @brief
To Wakeup the chip.
* @return
The function shall return ZERO for successful operation and a negative value otherwise.
*/
NMI_API sint8 hif_chip_wake(void);
/*!
@fn \
NMI_API void hif_set_sleep_mode(uint8 u8Pstype);
@brief
Set the sleep mode of the HIF layer.
@param [in] u8Pstype
Sleep mode.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API void hif_set_sleep_mode(uint8 u8Pstype);
/*!
@fn \
NMI_API uint8 hif_get_sleep_mode(void);
@brief
Get the sleep mode of the HIF layer.
@return
The function SHALL return the sleep mode of the HIF layer.
*/
NMI_API uint8 hif_get_sleep_mode(void);
#ifdef CORTUS_APP
/**
* @fn hif_Resp_handler(uint8 *pu8Buffer, uint16 u16BufferSize)
* @brief
Response handler for HIF layer.
* @param [in] pu8Buffer
Pointer to the buffer.
* @param [in] u16BufferSize
Buffer size.
* @return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 hif_Resp_handler(uint8 *pu8Buffer, uint16 u16BufferSize);
#endif
/**
* @fn hif_yield(void)
* @brief
Yields control from interrupt event handler.
*/
NMI_API void hif_yield(void);
/**
* @fn hif_handle_isr(void)
* @brief
Handle interrupt received from NMC1500 firmware.
* @return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 hif_handle_isr(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,395 @@
/**
*
* \file
*
* \brief NMC1500 IoT OTA 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
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "common/include/nm_common.h"
#include "driver/include/m2m_types.h"
#include "driver/include/m2m_ota.h"
#include "driver/source/m2m_hif.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static tpfOtaUpdateCb gpfOtaUpdateCb = NULL;
static tpfOtaNotifCb gpfOtaNotifCb = NULL;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/**
* @fn m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
* @brief WiFi call back function
* @param [in] u8OpCode
* HIF Opcode type.
* @param [in] u16DataSize
* HIF data length.
* @param [in] u32Addr
* HIF address.
* @param [in] grp
* HIF group type.
* @author
* @date
* @version 1.0
*/
static void m2m_ota_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
sint8 ret = M2M_SUCCESS;
if (u8OpCode == M2M_OTA_RESP_NOTIF_UPDATE_INFO) {
tstrOtaUpdateInfo strOtaUpdateInfo;
m2m_memset((uint8 *)&strOtaUpdateInfo, 0, sizeof(tstrOtaUpdateInfo));
ret = hif_receive(u32Addr, (uint8 *)&strOtaUpdateInfo, sizeof(tstrOtaUpdateInfo), 0);
if (ret == M2M_SUCCESS) {
if (gpfOtaNotifCb)
gpfOtaNotifCb(&strOtaUpdateInfo);
}
} else if (u8OpCode == M2M_OTA_RESP_UPDATE_STATUS) {
tstrOtaUpdateStatusResp strOtaUpdateStatusResp;
m2m_memset((uint8 *)&strOtaUpdateStatusResp, 0, sizeof(tstrOtaUpdateStatusResp));
ret = hif_receive(u32Addr, (uint8 *)&strOtaUpdateStatusResp, sizeof(tstrOtaUpdateStatusResp), 0);
if (ret == M2M_SUCCESS) {
if (gpfOtaUpdateCb)
gpfOtaUpdateCb(strOtaUpdateStatusResp.u8OtaUpdateStatusType, strOtaUpdateStatusResp.u8OtaUpdateStatus);
}
} else {
M2M_ERR("Invaild OTA resp %d ?\n", u8OpCode);
}
}
/*!
@fn \
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb);
@brief
Initialize the OTA layer.
@param [in] pfOtaUpdateCb
OTA Update callback function
@param [in] pfOtaNotifCb
OTA notify callback function
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_init(tpfOtaUpdateCb pfOtaUpdateCb, tpfOtaNotifCb pfOtaNotifCb)
{
sint8 ret = M2M_SUCCESS;
if (pfOtaUpdateCb) {
gpfOtaUpdateCb = pfOtaUpdateCb;
} else {
M2M_ERR("Invaild Ota update cb\n");
}
if (pfOtaNotifCb) {
gpfOtaNotifCb = pfOtaNotifCb;
} else {
M2M_ERR("Invaild Ota notify cb\n");
}
hif_register_cb(M2M_REQ_GROUP_OTA, m2m_ota_cb);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_set_url(uint8 * u8Url);
@brief
Set the OTA url
@param [in] u8Url
The url server address
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_set_url(uint8 *u8Url)
{
sint8 ret = M2M_SUCCESS;
uint16 u16UrlSize = m2m_strlen(u8Url) + 1;
/*Todo: we may change it to data pkt but we need to give it higer priority
but the priorty is not implemnted yet in data pkt
*/
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_SET_URL, u8Url, u16UrlSize, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_check_for_update(void);
@brief
check for ota update
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_check_for_update(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period);
@brief
Schedule OTA update
@param [in] u32Period
Period in days
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_notif_sched(uint32 u32Period)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_NOTIF_CHECK_FOR_UPDATE, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_start_update(uint8 * u8DownloadUrl);
@brief
Request OTA start update using the downloaded url
@param [in] u8DownloadUrl
The download firmware url, you get it from device info
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_start_update(uint8 *u8DownloadUrl)
{
sint8 ret = M2M_SUCCESS;
uint16 u16DurlSize = m2m_strlen(u8DownloadUrl) + 1;
/*Todo: we may change it to data pkt but we need to give it higer priority
but the priorty is not implemnted yet in data pkt
*/
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_START_FW_UPDATE, u8DownloadUrl, u16DurlSize, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_start_update_crt(uint8 * u8DownloadUrl);
@brief
Request OTA start for the Cortus app image.
@param [in] u8DownloadUrl
The cortus application image url.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_start_update_crt(uint8 *u8DownloadUrl)
{
sint8 ret = M2M_SUCCESS;
uint16 u16DurlSize = m2m_strlen(u8DownloadUrl) + 1;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_START_CRT_UPDATE, u8DownloadUrl, u16DurlSize, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_rollback(void);
@brief
Request OTA Rollback image
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_rollback(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_ROLLBACK_FW, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_rollback_crt(void);
@brief
Request Cortus application OTA Rollback image
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_rollback_crt(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_ROLLBACK_CRT, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_abort(void);
@brief
Request OTA Abort
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_abort(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_ABORT, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_switch_firmware(void);
@brief
Switch to the upgraded Firmware
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_switch_firmware(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_SWITCH_FIRMWARE, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_switch_crt(void);
@brief
Switch to the upgraded cortus application.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_switch_crt(void)
{
sint8 ret = M2M_SUCCESS;
ret = hif_send(M2M_REQ_GROUP_OTA, M2M_OTA_REQ_SWITCH_CRT_IMG, NULL, 0, NULL, 0, 0);
return ret;
}
/*!
@fn \
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev);
@brief
Get the OTA Firmware version.
@return
The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev *pstrRev)
{
sint8 ret = M2M_SUCCESS;
ret = hif_chip_wake();
if (ret == M2M_SUCCESS) {
ret = nm_get_ota_firmware_info(pstrRev);
hif_chip_sleep();
}
return ret;
}
#if 0
#define M2M_OTA_FILE "../../../m2m_ota.dat"
NMI_API sint8 m2m_ota_test(void)
{
uint32 page = 0;
uint8 buffer[1500];
uint32 u32Sz = 0;
sint8 ret = M2M_SUCCESS;
FILE *fp =NULL;
fp = fopen(M2M_OTA_FILE,"rb");
if(fp)
{
fseek(fp, 0L, SEEK_END);
u32Sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
while(u32Sz > 0)
{
{
page = (rand()%1400);
if((page<100)||(page>1400)) page = 1400;
}
if(u32Sz>page)
{
u32Sz-=page;
}
else
{
page = u32Sz;
u32Sz = 0;
}
printf("page %d\n", (int)page);
fread(buffer,page,1,fp);
ret = hif_send(M2M_REQ_GROUP_OTA,M2M_OTA_REQ_TEST|M2M_REQ_DATA_PKT,NULL,0,(uint8*)&buffer,page,0);
if(ret != M2M_SUCCESS)
{
M2M_ERR("\n");
}
nm_bsp_sleep(1);
}
}
else
{
M2M_ERR("nO err\n");
}
return ret;
}
#endif

View File

@ -0,0 +1,169 @@
/**
*
* \file
*
* \brief NMC1500 Peripherials Application Interface.
*
* 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
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "driver/include/m2m_periph.h"
#include "driver/source/nmasic.h"
#include "m2m_hif.h"
#ifdef CONF_PERIPH
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#define GPIO_OP_DIR 0
#define GPIO_OP_SET 1
#define GPIO_OP_GET 2
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
STATIC FUNCTIONS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static sint8 get_gpio_idx(uint8 u8GpioNum)
{
if (u8GpioNum >= M2M_PERIPH_GPIO_MAX)
return -1;
if (u8GpioNum == M2M_PERIPH_GPIO15) {
return 15;
} else if (u8GpioNum == M2M_PERIPH_GPIO16) {
return 16;
} else if (u8GpioNum == M2M_PERIPH_GPIO18) {
return 18;
} else if (u8GpioNum == M2M_PERIPH_GPIO3) {
return 3;
} else if (u8GpioNum == M2M_PERIPH_GPIO4) {
return 4;
} else if (u8GpioNum == M2M_PERIPH_GPIO5) {
return 5;
} else if (u8GpioNum == M2M_PERIPH_GPIO6) {
return 6;
} else {
return -2;
}
}
/*
* GPIO read/write skeleton with wakeup/sleep capability.
*/
static sint8 gpio_ioctl(uint8 op, uint8 u8GpioNum, uint8 u8InVal, uint8 *pu8OutVal)
{
sint8 ret, gpio;
ret = hif_chip_wake();
if (ret != M2M_SUCCESS)
goto _EXIT;
gpio = get_gpio_idx(u8GpioNum);
if (gpio < 0)
goto _EXIT1;
if (op == GPIO_OP_DIR) {
ret = set_gpio_dir((uint8)gpio, u8InVal);
} else if (op == GPIO_OP_SET) {
ret = set_gpio_val((uint8)gpio, u8InVal);
} else if (op == GPIO_OP_GET) {
ret = get_gpio_val((uint8)gpio, pu8OutVal);
}
if (ret != M2M_SUCCESS)
goto _EXIT1;
_EXIT1:
ret = hif_chip_sleep();
_EXIT:
return ret;
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION IMPLEMENTATION
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
sint8 m2m_periph_init(tstrPerphInitParam *param)
{
return M2M_SUCCESS;
}
sint8 m2m_periph_gpio_set_dir(uint8 u8GpioNum, uint8 u8GpioDir)
{
return gpio_ioctl(GPIO_OP_DIR, u8GpioNum, u8GpioDir, NULL);
}
sint8 m2m_periph_gpio_set_val(uint8 u8GpioNum, uint8 u8GpioVal)
{
return gpio_ioctl(GPIO_OP_SET, u8GpioNum, u8GpioVal, NULL);
}
sint8 m2m_periph_gpio_get_val(uint8 u8GpioNum, uint8 *pu8GpioVal)
{
return gpio_ioctl(GPIO_OP_GET, u8GpioNum, 0, pu8GpioVal);
}
sint8 m2m_periph_gpio_pullup_ctrl(uint8 u8GpioNum, uint8 u8PullupEn)
{
/* TBD */
return M2M_SUCCESS;
}
sint8 m2m_periph_i2c_master_init(tstrI2cMasterInitParam *param)
{
/* TBD */
return M2M_SUCCESS;
}
sint8 m2m_periph_i2c_master_write(uint8 u8SlaveAddr, uint8 *pu8Buf, uint16 u16BufLen, uint8 flags)
{
/* TBD */
return M2M_SUCCESS;
}
sint8 m2m_periph_i2c_master_read(uint8 u8SlaveAddr, uint8 *pu8Buf, uint16 u16BufLen, uint16 *pu16ReadLen, uint8 flags)
{
/* TBD */
return M2M_SUCCESS;
}
sint8 m2m_periph_pullup_ctrl(uint32 pinmask, uint8 enable)
{
return pullup_ctrl(pinmask, enable);
}
#endif /* CONF_PERIPH */

View File

@ -0,0 +1,310 @@
/**
*
* \file
*
* \brief This module contains M2M Wi-Fi APIs implementation.
*
* Copyright (c) 2017-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
*
*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#include "driver/include/m2m_ssl.h"
#include "driver/source/m2m_hif.h"
#include "driver/source/nmasic.h"
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static tpfAppSSLCb gpfAppSSLCb = NULL;
static uint32 gu32HIFAddr = 0;
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
@fn \ m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
@brief SSL callback function
@param [in] u8OpCode
HIF Opcode type.
@param [in] u16DataSize
HIF data length.
@param [in] u32Addr
HIF address.
*/
static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
{
sint8 s8tmp = M2M_SUCCESS;
switch (u8OpCode) {
case M2M_SSL_REQ_ECC: {
tstrEccReqInfo strEccREQ;
s8tmp = hif_receive(u32Addr, (uint8 *)&strEccREQ, sizeof(tstrEccReqInfo), 0);
if (s8tmp == M2M_SUCCESS) {
if (gpfAppSSLCb) {
gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo);
gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ);
}
}
} break;
case M2M_SSL_RESP_SET_CS_LIST: {
tstrSslSetActiveCsList strCsList;
s8tmp = hif_receive(u32Addr, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), 0);
if (s8tmp == M2M_SUCCESS) {
if (gpfAppSSLCb)
gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList);
}
} break;
}
if (s8tmp != M2M_SUCCESS) {
M2M_ERR("Error receiving SSL from the HIF\n");
}
}
/*!
@fn \ m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
@brief Sends ECC responses to the WINC
@param [in] strECCResp
ECC Response struct.
@param [in] pu8RspDataBuffe
Pointer of the response data to be sent.
@param [in] u16RspDataSz
Response data size.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo *strECCResp, uint8 *pu8RspDataBuff, uint16 u16RspDataSz)
{
sint8 s8Ret = M2M_SUCCESS;
s8Ret = hif_send(M2M_REQ_GROUP_SSL,
(M2M_SSL_RESP_ECC | M2M_REQ_DATA_PKT),
(uint8 *)strECCResp,
sizeof(tstrEccReqInfo),
pu8RspDataBuff,
u16RspDataSz,
sizeof(tstrEccReqInfo));
return s8Ret;
}
/*!
@fn \ m2m_ssl_send_certs_to_winc(uint8* sector_buffer, uint32 sector_size)
@brief Sends certificates to the WINC
@param [in] pu8Buffer
Pointer to the certificates.
@param [in] u32BufferSz
Size of the certificates.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz)
{
sint8 s8Ret = M2M_SUCCESS;
s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_IND_CERTS_ECC | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, u32BufferSz, 0);
return s8Ret;
}
/*!
@fn \ m2m_ssl_retrieve_cert(uint32 u32ReadAddr, uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig,
tstrECPoint* pu8Key)
@brief Retrieve the certificate to be verified from the WINC
@param [in] pu16CurveType
Pointer to the certificate curve type.
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] pu8Sig
Pointer to the certificate signature.
@param [in] pu8Key
Pointer to the certificate Key.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_retrieve_cert(uint16 *pu16CurveType, uint8 *pu8Hash, uint8 *pu8Sig, tstrECPoint *pu8Key)
{
uint8 bSetRxDone = 1;
uint16 u16HashSz, u16SigSz, u16KeySz;
sint8 s8Ret = M2M_SUCCESS;
if (gu32HIFAddr == 0)
return M2M_ERR_FAIL;
if (hif_receive(gu32HIFAddr, (uint8 *)pu16CurveType, 2, 0) != M2M_SUCCESS)
goto __ERR;
gu32HIFAddr += 2;
if (hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS)
goto __ERR;
gu32HIFAddr += 2;
if (hif_receive(gu32HIFAddr, (uint8 *)&u16HashSz, 2, 0) != M2M_SUCCESS)
goto __ERR;
gu32HIFAddr += 2;
if (hif_receive(gu32HIFAddr, (uint8 *)&u16SigSz, 2, 0) != M2M_SUCCESS)
goto __ERR;
gu32HIFAddr += 2;
(*pu16CurveType) = _htons((*pu16CurveType));
pu8Key->u16Size = _htons(u16KeySz);
u16HashSz = _htons(u16HashSz);
u16SigSz = _htons(u16SigSz);
if (hif_receive(gu32HIFAddr, pu8Key->X, pu8Key->u16Size * 2, 0) != M2M_SUCCESS)
goto __ERR;
gu32HIFAddr += (pu8Key->u16Size * 2);
if (hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS)
goto __ERR;
gu32HIFAddr += u16HashSz;
if (hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS)
goto __ERR;
gu32HIFAddr += u16SigSz;
bSetRxDone = 0;
__ERR:
if (bSetRxDone) {
s8Ret = M2M_ERR_FAIL;
hif_receive(0, NULL, 0, 1);
}
return s8Ret;
}
/*!
@fn \ m2m_ssl_retrieve_hash(uint32 u32ReadAddr, uint8* pu8Hash, uint16 u16HashSz)
@brief Retrieve the certificate hash
@param [in] pu8Hash
Pointer to the certificate hash.
@param [in] u16HashSz
Hash size.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_retrieve_hash(uint8 *pu8Hash, uint16 u16HashSz)
{
uint8 bSetRxDone = 1;
sint8 s8Ret = M2M_SUCCESS;
if (gu32HIFAddr == 0)
return M2M_ERR_FAIL;
if (hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS)
goto __ERR;
bSetRxDone = 0;
__ERR:
if (bSetRxDone) {
s8Ret = M2M_ERR_FAIL;
hif_receive(0, NULL, 0, 1);
}
return s8Ret;
}
/*!
@fn \ m2m_ssl_stop_processing_certs(void)
@brief Stops receiving from the HIF
*/
NMI_API void m2m_ssl_stop_processing_certs(void)
{
hif_receive(0, NULL, 0, 1);
}
/*!
@fn \ m2m_ssl_ecc_process_done(void)
@brief Stops receiving from the HIF
*/
NMI_API void m2m_ssl_ecc_process_done(void)
{
gu32HIFAddr = 0;
}
/*!
@fn \
m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the
form of a bitmap containing the required ciphers to be on. There is no need to call this function if the application
will not change the default ciphersuites.
@param [in] u32SslCsBMP
Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
@ref SSLCipherSuiteID.
The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC
ciphersuites. The caller can override the default with any desired combination, except for combinations involving both
RSA and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC ciphersuites. If u32SslCsBMP does not
contain any ciphersuites supported by firmware, then the current active list will not be changed.
@return
- [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)
- [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
*/
sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
{
sint8 s8Ret = M2M_SUCCESS;
tstrSslSetActiveCsList strCsList;
strCsList.u32CsBMP = u32SslCsBMP;
s8Ret = hif_send(
M2M_REQ_GROUP_SSL, M2M_SSL_REQ_SET_CS_LIST, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), NULL, 0, 0);
return s8Ret;
}
/*!
@fn \ m2m_ssl_init(tpfAppSslCb pfAppSslCb);
@brief Initializes the SSL layer.
@param [in] pfAppSslCb
Application SSL callback function.
@return The function SHALL return 0 for success and a negative value otherwise.
*/
NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
{
sint8 s8Ret = M2M_SUCCESS;
gpfAppSSLCb = pfAppSSLCb;
gu32HIFAddr = 0;
s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL, m2m_ssl_cb);
if (s8Ret != M2M_SUCCESS) {
M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
}
return s8Ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,679 @@
/**
*
* \file
*
* \brief This module contains NMC1500 ASIC specific internal APIs.
*
* 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
*
*/
#include "common/include/nm_common.h"
#include "driver/source/nmbus.h"
#include "bsp/include/nm_bsp.h"
#include "driver/source/nmasic.h"
#include "driver/include/m2m_types.h"
#define NMI_GLB_RESET_0 (NMI_PERIPH_REG_BASE + 0x400)
#define NMI_INTR_REG_BASE (NMI_PERIPH_REG_BASE + 0xa00)
#define NMI_PIN_MUX_0 (NMI_PERIPH_REG_BASE + 0x408)
#define NMI_INTR_ENABLE (NMI_INTR_REG_BASE)
#define GET_UINT32(X, Y) (X[0 + Y] + ((uint32)X[1 + Y] << 8) + ((uint32)X[2 + Y] << 16) + ((uint32)X[3 + Y] << 24))
/*SPI and I2C only*/
#define CORT_HOST_COMM (0x10)
#define HOST_CORT_COMM (0x0b)
#define WAKE_CLK_REG (0x1)
#define CLOCKS_EN_REG (0xf)
#define TIMEOUT (0xfffffffful)
#define WAKUP_TRAILS_TIMEOUT (4)
sint8 chip_apply_conf(uint32 u32Conf)
{
sint8 ret = M2M_SUCCESS;
uint32 val32 = u32Conf;
#if (defined __ENABLE_PMU__) || (defined CONF_WINC_INT_PMU)
val32 |= rHAVE_USE_PMU_BIT;
#endif
#ifdef __ENABLE_SLEEP_CLK_SRC_RTC__
val32 |= rHAVE_SLEEP_CLK_SRC_RTC_BIT;
#elif defined __ENABLE_SLEEP_CLK_SRC_XO__
val32 |= rHAVE_SLEEP_CLK_SRC_XO_BIT;
#endif
#ifdef __ENABLE_EXT_PA_INV_TX_RX__
val32 |= rHAVE_EXT_PA_INV_TX_RX;
#endif
#ifdef __ENABLE_LEGACY_RF_SETTINGS__
val32 |= rHAVE_LEGACY_RF_SETTINGS;
#endif
#ifdef __DISABLE_FIRMWARE_LOGS__
val32 |= rHAVE_LOGS_DISABLED_BIT;
#endif
#if defined CONF_WINC_XO_XTALGM2_DIS
val32 |= rHAVE_XO_XTALGM2_DIS_BIT;
#endif
val32 |= rHAVE_RESERVED1_BIT;
do {
nm_write_reg(rNMI_GP_REG_1, val32);
if (val32 != 0) {
uint32 reg = 0;
ret = nm_read_reg_with_ret(rNMI_GP_REG_1, &reg);
if (ret == M2M_SUCCESS) {
if (reg == val32)
break;
}
} else {
break;
}
} while (1);
return M2M_SUCCESS;
}
void chip_idle(void)
{
uint32 reg = 0;
nm_read_reg_with_ret(WAKE_CLK_REG, &reg);
if (reg & NBIT1) {
reg &= ~NBIT1;
nm_write_reg(WAKE_CLK_REG, reg);
}
}
sint8 enable_interrupts(void)
{
uint32 reg = 0;
sint8 ret = M2M_SUCCESS;
/**
interrupt pin mux select
**/
ret = nm_read_reg_with_ret(NMI_PIN_MUX_0, &reg);
if (M2M_SUCCESS != ret)
goto ERR1;
reg |= ((uint32)1 << 8);
ret = nm_write_reg(NMI_PIN_MUX_0, reg);
if (M2M_SUCCESS != ret)
goto ERR1;
/**
interrupt enable
**/
ret = nm_read_reg_with_ret(NMI_INTR_ENABLE, &reg);
if (M2M_SUCCESS != ret)
goto ERR1;
reg |= ((uint32)1 << 16);
ret = nm_write_reg(NMI_INTR_ENABLE, reg);
if (M2M_SUCCESS != ret)
goto ERR1;
ERR1:
return ret;
}
sint8 cpu_start(void)
{
uint32 reg = 0;
sint8 ret;
/**
reset regs
*/
ret = nm_write_reg(BOOTROM_REG, 0);
ret += nm_write_reg(NMI_STATE_REG, 0);
ret += nm_write_reg(NMI_REV_REG, 0);
/**
Go...
**/
ret += nm_read_reg_with_ret(0x1118, &reg);
reg |= (1 << 0);
ret += nm_write_reg(0x1118, reg);
ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
if ((reg & (1ul << 10)) == (1ul << 10)) {
reg &= ~(1ul << 10);
ret += nm_write_reg(NMI_GLB_RESET_0, reg);
}
reg |= (1ul << 10);
ret += nm_write_reg(NMI_GLB_RESET_0, reg);
nm_bsp_sleep(1);
return ret;
}
uint32 nmi_get_chipid(void)
{
static uint32 chipid = 0;
if (chipid == 0) {
uint32 rfrevid;
if ((nm_read_reg_with_ret(0x1000, &chipid)) != M2M_SUCCESS) {
chipid = 0;
return 0;
}
// if((ret = nm_read_reg_with_ret(0x11fc, &revid)) != M2M_SUCCESS) {
// return 0;
//}
if ((nm_read_reg_with_ret(0x13f4, &rfrevid)) != M2M_SUCCESS) {
chipid = 0;
return 0;
}
if (chipid == 0x1002a0) {
if (rfrevid == 0x1) { /* 1002A0 */
} else /* if (rfrevid == 0x2) */ { /* 1002A1 */
chipid = 0x1002a1;
}
} else if (chipid == 0x1002b0) {
if (rfrevid == 3) { /* 1002B0 */
} else if (rfrevid == 4) { /* 1002B1 */
chipid = 0x1002b1;
} else /* if(rfrevid == 5) */ { /* 1002B2 */
chipid = 0x1002b2;
}
} else if (chipid == 0x1000F0) {
if ((nm_read_reg_with_ret(0x3B0000, &chipid)) != M2M_SUCCESS) {
chipid = 0;
return 0;
}
} else {
}
//#define PROBE_FLASH
#ifdef PROBE_FLASH
if (chipid) {
UWORD32 flashid;
flashid = probe_spi_flash();
if (flashid == 0x1230ef) {
chipid &= ~(0x0f0000);
chipid |= 0x050000;
}
if (flashid == 0xc21320c2) {
chipid &= ~(0x0f0000);
chipid |= 0x050000;
}
}
#else
/*M2M is by default have SPI flash*/
chipid &= ~(0x0f0000);
chipid |= 0x050000;
#endif /* PROBE_FLASH */
}
return chipid;
}
uint32 nmi_get_rfrevid(void)
{
uint32 rfrevid;
if ((nm_read_reg_with_ret(0x13f4, &rfrevid)) != M2M_SUCCESS) {
rfrevid = 0;
return 0;
}
return rfrevid;
}
void restore_pmu_settings_after_global_reset(void)
{
/*
* Must restore PMU register value after
* global reset if PMU toggle is done at
* least once since the last hard reset.
*/
if (REV(nmi_get_chipid()) >= REV_2B0) {
nm_write_reg(0x1e48, 0xb78469ce);
}
}
void nmi_update_pll(void)
{
uint32 pll;
pll = nm_read_reg(0x1428);
pll &= ~0x1ul;
nm_write_reg(0x1428, pll);
pll |= 0x1ul;
nm_write_reg(0x1428, pll);
}
void nmi_set_sys_clk_src_to_xo(void)
{
uint32 val32;
/* Switch system clock source to XO. This will take effect after nmi_update_pll(). */
val32 = nm_read_reg(0x141c);
val32 |= (1 << 2);
nm_write_reg(0x141c, val32);
/* Do PLL update */
nmi_update_pll();
}
sint8 chip_sleep(void)
{
uint32 reg;
sint8 ret = M2M_SUCCESS;
while (1) {
ret = nm_read_reg_with_ret(CORT_HOST_COMM, &reg);
if (ret != M2M_SUCCESS)
goto ERR1;
if ((reg & NBIT0) == 0)
break;
}
/* Clear bit 1 */
ret = nm_read_reg_with_ret(WAKE_CLK_REG, &reg);
if (ret != M2M_SUCCESS)
goto ERR1;
if (reg & NBIT1) {
reg &= ~NBIT1;
ret = nm_write_reg(WAKE_CLK_REG, reg);
if (ret != M2M_SUCCESS)
goto ERR1;
}
ret = nm_read_reg_with_ret(HOST_CORT_COMM, &reg);
if (ret != M2M_SUCCESS)
goto ERR1;
if (reg & NBIT0) {
reg &= ~NBIT0;
ret = nm_write_reg(HOST_CORT_COMM, reg);
if (ret != M2M_SUCCESS)
goto ERR1;
}
ERR1:
return ret;
}
sint8 chip_wake(void)
{
sint8 ret = M2M_SUCCESS;
uint32 reg = 0, clk_status_reg = 0, trials = 0;
ret = nm_read_reg_with_ret(HOST_CORT_COMM, &reg);
if (ret != M2M_SUCCESS)
goto _WAKE_EXIT;
if (!(reg & NBIT0)) {
/*USE bit 0 to indicate host wakeup*/
ret = nm_write_reg(HOST_CORT_COMM, reg | NBIT0);
if (ret != M2M_SUCCESS)
goto _WAKE_EXIT;
}
ret = nm_read_reg_with_ret(WAKE_CLK_REG, &reg);
if (ret != M2M_SUCCESS)
goto _WAKE_EXIT;
/* Set bit 1 */
if (!(reg & NBIT1)) {
ret = nm_write_reg(WAKE_CLK_REG, reg | NBIT1);
if (ret != M2M_SUCCESS)
goto _WAKE_EXIT;
}
do {
ret = nm_read_reg_with_ret(CLOCKS_EN_REG, &clk_status_reg);
if (ret != M2M_SUCCESS) {
M2M_ERR("Bus error (5).%d %x\n", ret, clk_status_reg);
goto _WAKE_EXIT;
}
if (clk_status_reg & NBIT2) {
break;
}
nm_bsp_sleep(2);
trials++;
if (trials > WAKUP_TRAILS_TIMEOUT) {
M2M_ERR("Failed to wakup the chip\n");
ret = M2M_ERR_TIME_OUT;
goto _WAKE_EXIT;
}
} while (1);
/*workaround sometimes spi fail to read clock regs after reading/writing clockless registers*/
nm_bus_reset();
_WAKE_EXIT:
return ret;
}
sint8 cpu_halt(void)
{
sint8 ret;
uint32 reg = 0;
ret = nm_read_reg_with_ret(0x1118, &reg);
reg |= (1 << 0);
ret += nm_write_reg(0x1118, reg);
ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
if ((reg & (1ul << 10)) == (1ul << 10)) {
reg &= ~(1ul << 10);
ret += nm_write_reg(NMI_GLB_RESET_0, reg);
ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
}
return ret;
}
sint8 chip_reset_and_cpu_halt(void)
{
sint8 ret = M2M_SUCCESS;
/*Wakeup needed only for I2C interface*/
ret = chip_wake();
if (ret != M2M_SUCCESS)
goto ERR1;
/*Reset and CPU halt need for no wait board only*/
ret = chip_reset();
if (ret != M2M_SUCCESS)
goto ERR1;
ret = cpu_halt();
if (ret != M2M_SUCCESS)
goto ERR1;
ERR1:
return ret;
}
sint8 chip_reset(void)
{
sint8 ret = M2M_SUCCESS;
ret = nm_write_reg(NMI_GLB_RESET_0, 0);
nm_bsp_sleep(50);
return ret;
}
sint8 wait_for_bootrom(uint8 arg)
{
sint8 ret = M2M_SUCCESS;
uint32 reg = 0, cnt = 0;
uint32 u32GpReg1 = 0;
uint32 u32DriverVerInfo = M2M_MAKE_VERSION_INFO(M2M_RELEASE_VERSION_MAJOR_NO,
M2M_RELEASE_VERSION_MINOR_NO,
M2M_RELEASE_VERSION_PATCH_NO,
M2M_MIN_REQ_DRV_VERSION_MAJOR_NO,
M2M_MIN_REQ_DRV_VERSION_MINOR_NO,
M2M_MIN_REQ_DRV_VERSION_PATCH_NO);
reg = 0;
while (1) {
reg = nm_read_reg(0x1014); /* wait for efuse loading done */
if (reg & 0x80000000) {
break;
}
nm_bsp_sleep(1); /* TODO: Why bus error if this delay is not here. */
}
reg = nm_read_reg(M2M_WAIT_FOR_HOST_REG);
reg &= 0x1;
/* check if waiting for the host will be skipped or not */
if (reg == 0) {
reg = 0;
while (reg != M2M_FINISH_BOOT_ROM) {
nm_bsp_sleep(1);
reg = nm_read_reg(BOOTROM_REG);
if (++cnt > TIMEOUT) {
M2M_DBG("failed to load firmware from flash.\n");
ret = M2M_ERR_INIT;
goto ERR2;
}
}
}
if (M2M_WIFI_MODE_ATE_HIGH == arg) {
nm_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE);
nm_write_reg(NMI_STATE_REG, NBIT20);
} else if (M2M_WIFI_MODE_ATE_LOW == arg) {
nm_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE);
nm_write_reg(NMI_STATE_REG, 0);
} else if (M2M_WIFI_MODE_ETHERNET == arg) {
u32GpReg1 = rHAVE_ETHERNET_MODE_BIT;
nm_write_reg(NMI_STATE_REG, u32DriverVerInfo);
} else {
/*bypass this step*/
nm_write_reg(NMI_STATE_REG, u32DriverVerInfo);
}
if (REV(nmi_get_chipid()) >= REV_3A0) {
chip_apply_conf(u32GpReg1 | rHAVE_USE_PMU_BIT);
} else {
chip_apply_conf(u32GpReg1);
}
M2M_INFO("DriverVerInfo: 0x%08lx\n", u32DriverVerInfo);
nm_write_reg(BOOTROM_REG, M2M_START_FIRMWARE);
#ifdef __ROM_TEST__
rom_test();
#endif /* __ROM_TEST__ */
ERR2:
return ret;
}
sint8 wait_for_firmware_start(uint8 arg)
{
sint8 ret = M2M_SUCCESS;
uint32 reg = 0, cnt = 0;
uint32 u32Timeout = TIMEOUT;
volatile uint32 regAddress = NMI_STATE_REG;
volatile uint32 checkValue = M2M_FINISH_INIT_STATE;
if ((M2M_WIFI_MODE_ATE_HIGH == arg) || (M2M_WIFI_MODE_ATE_LOW == arg)) {
regAddress = NMI_REV_REG;
checkValue = M2M_ATE_FW_IS_UP_VALUE;
} else {
/*bypass this step*/
}
while (checkValue != reg) {
nm_bsp_sleep(2); /* TODO: Why bus error if this delay is not here. */
M2M_DBG("%x %x %x\n",
(unsigned int)nm_read_reg(0x108c),
(unsigned int)nm_read_reg(0x108c),
(unsigned int)nm_read_reg(0x14A0));
reg = nm_read_reg(regAddress);
if (++cnt >= u32Timeout) {
M2M_DBG("Time out for wait firmware Run\n");
ret = M2M_ERR_INIT;
goto ERR;
}
}
if (M2M_FINISH_INIT_STATE == checkValue) {
nm_write_reg(NMI_STATE_REG, 0);
}
ERR:
return ret;
}
sint8 chip_deinit(void)
{
uint32 reg = 0;
sint8 ret;
/**
stop the firmware, need a re-download
**/
ret = nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
if (ret != M2M_SUCCESS) {
M2M_ERR("failed to de-initialize\n");
goto ERR1;
}
reg &= ~(1 << 10);
ret = nm_write_reg(NMI_GLB_RESET_0, reg);
if (ret != M2M_SUCCESS) {
M2M_ERR("failed to de-initialize\n");
goto ERR1;
}
ERR1:
return ret;
}
#ifdef CONF_PERIPH
sint8 set_gpio_dir(uint8 gpio, uint8 dir)
{
uint32 val32;
sint8 ret;
ret = nm_read_reg_with_ret(0x20108, &val32);
if (ret != M2M_SUCCESS)
goto _EXIT;
if (dir) {
val32 |= (1ul << gpio);
} else {
val32 &= ~(1ul << gpio);
}
ret = nm_write_reg(0x20108, val32);
_EXIT:
return ret;
}
sint8 set_gpio_val(uint8 gpio, uint8 val)
{
uint32 val32;
sint8 ret;
ret = nm_read_reg_with_ret(0x20100, &val32);
if (ret != M2M_SUCCESS)
goto _EXIT;
if (val) {
val32 |= (1ul << gpio);
} else {
val32 &= ~(1ul << gpio);
}
ret = nm_write_reg(0x20100, val32);
_EXIT:
return ret;
}
sint8 get_gpio_val(uint8 gpio, uint8 *val)
{
uint32 val32;
sint8 ret;
ret = nm_read_reg_with_ret(0x20104, &val32);
if (ret != M2M_SUCCESS)
goto _EXIT;
*val = (uint8)((val32 >> gpio) & 0x01);
_EXIT:
return ret;
}
sint8 pullup_ctrl(uint32 pinmask, uint8 enable)
{
sint8 s8Ret;
uint32 val32;
s8Ret = nm_read_reg_with_ret(0x142c, &val32);
if (s8Ret != M2M_SUCCESS) {
M2M_ERR("[pullup_ctrl]: failed to read\n");
goto _EXIT;
}
if (enable) {
val32 &= ~pinmask;
} else {
val32 |= pinmask;
}
s8Ret = nm_write_reg(0x142c, val32);
if (s8Ret != M2M_SUCCESS) {
M2M_ERR("[pullup_ctrl]: failed to write\n");
goto _EXIT;
}
_EXIT:
return s8Ret;
}
#endif /* CONF_PERIPH */
sint8 nmi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 *pu8IsValid)
{
sint8 ret;
uint32 u32RegValue;
uint8 mac[6];
tstrGpRegs strgp = {0};
ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &u32RegValue);
if (ret != M2M_SUCCESS)
goto _EXIT_ERR;
ret = nm_read_block(u32RegValue | 0x30000, (uint8 *)&strgp, sizeof(tstrGpRegs));
if (ret != M2M_SUCCESS)
goto _EXIT_ERR;
u32RegValue = strgp.u32Mac_efuse_mib;
if (!EFUSED_MAC(u32RegValue)) {
M2M_DBG("Default MAC\n");
m2m_memset(pu8MacAddr, 0, 6);
goto _EXIT_ERR;
}
M2M_DBG("OTP MAC\n");
u32RegValue >>= 16;
ret = nm_read_block(u32RegValue | 0x30000, mac, 6);
m2m_memcpy(pu8MacAddr, mac, 6);
if (pu8IsValid)
*pu8IsValid = 1;
return ret;
_EXIT_ERR:
if (pu8IsValid)
*pu8IsValid = 0;
return ret;
}
sint8 nmi_get_mac_address(uint8 *pu8MacAddr)
{
sint8 ret;
uint32 u32RegValue;
uint8 mac[6];
tstrGpRegs strgp = {0};
ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &u32RegValue);
if (ret != M2M_SUCCESS)
goto _EXIT_ERR;
ret = nm_read_block(u32RegValue | 0x30000, (uint8 *)&strgp, sizeof(tstrGpRegs));
if (ret != M2M_SUCCESS)
goto _EXIT_ERR;
u32RegValue = strgp.u32Mac_efuse_mib;
u32RegValue &= 0x0000ffff;
ret = nm_read_block(u32RegValue | 0x30000, mac, 6);
m2m_memcpy(pu8MacAddr, mac, 6);
return ret;
_EXIT_ERR:
return ret;
}

View File

@ -0,0 +1,218 @@
/**
*
* \file
*
* \brief This module contains NMC1500 ASIC specific internal APIs.
*
* 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 _NMASIC_H_
#define _NMASIC_H_
#include "common/include/nm_common.h"
#define NMI_PERIPH_REG_BASE 0x1000
#define NMI_CHIPID (NMI_PERIPH_REG_BASE)
#define rNMI_GP_REG_0 (0x149c)
#define rNMI_GP_REG_1 (0x14A0)
#define rNMI_GP_REG_2 (0xc0008)
#define rNMI_GLB_RESET (0x1400)
#define rNMI_BOOT_RESET_MUX (0x1118)
#define NMI_STATE_REG (0x108c)
#define BOOTROM_REG (0xc000c)
#define NMI_REV_REG (0x207ac) /*Also, Used to load ATE firmware from SPI Flash and to ensure that it is running too*/
#define NMI_REV_REG_ATE (0x1048) /*Revision info register in case of ATE FW*/
#define M2M_WAIT_FOR_HOST_REG (0x207bc)
#define M2M_FINISH_INIT_STATE 0x02532636UL
#define M2M_FINISH_BOOT_ROM 0x10add09eUL
#define M2M_START_FIRMWARE 0xef522f61UL
#define M2M_START_PS_FIRMWARE 0x94992610UL
#define M2M_ATE_FW_START_VALUE (0x3C1CD57D) /*Also, Change this value in boot_firmware if it will be changed here*/
#define M2M_ATE_FW_IS_UP_VALUE \
(0xD75DC1C3) /*Also, Change this value in ATE (Burst) firmware if it will be changed here*/
#define REV_2B0 (0x2B0)
#define REV_B0 (0x2B0)
#define REV_3A0 (0x3A0)
#define GET_CHIPID() nmi_get_chipid()
#define ISNMC1000(id) ((((id)&0xfffff000) == 0x100000) ? 1 : 0)
#define ISNMC1500(id) ((((id)&0xfffff000) == 0x150000) ? 1 : 0)
#define ISNMC3000(id) ((((id)&0xfff00000) == 0x300000) ? 1 : 0)
#define REV(id) (((id)&0x00000fff))
#define EFUSED_MAC(value) (value & 0xffff0000)
#define rHAVE_SDIO_IRQ_GPIO_BIT (NBIT0)
#define rHAVE_USE_PMU_BIT (NBIT1)
#define rHAVE_SLEEP_CLK_SRC_RTC_BIT (NBIT2)
#define rHAVE_SLEEP_CLK_SRC_XO_BIT (NBIT3)
#define rHAVE_EXT_PA_INV_TX_RX (NBIT4)
#define rHAVE_LEGACY_RF_SETTINGS (NBIT5)
#define rHAVE_LOGS_DISABLED_BIT (NBIT6)
#define rHAVE_ETHERNET_MODE_BIT (NBIT7)
#define rHAVE_RESERVED1_BIT (NBIT8)
#define rHAVE_RESERVED2_BIT (NBIT9)
#define rHAVE_XO_XTALGM2_DIS_BIT (NBIT10)
typedef struct {
uint32 u32Mac_efuse_mib;
uint32 u32Firmware_Ota_rev;
} tstrGpRegs;
#ifdef __cplusplus
extern "C" {
#endif
/*
* @fn cpu_halt
* @brief
*/
sint8 cpu_halt(void);
/*
* @fn chip_sleep
* @brief
*/
sint8 chip_sleep(void);
/*
* @fn chip_wake
* @brief
*/
sint8 chip_wake(void);
/*
* @fn chip_idle
* @brief
*/
void chip_idle(void);
/*
* @fn enable_interrupts
* @brief
*/
sint8 enable_interrupts(void);
/*
* @fn cpu_start
* @brief
*/
sint8 cpu_start(void);
/*
* @fn nmi_get_chipid
* @brief
*/
uint32 nmi_get_chipid(void);
/*
* @fn nmi_get_rfrevid
* @brief
*/
uint32 nmi_get_rfrevid(void);
/*
* @fn restore_pmu_settings_after_global_reset
* @brief
*/
void restore_pmu_settings_after_global_reset(void);
/*
* @fn nmi_update_pll
* @brief
*/
void nmi_update_pll(void);
/*
* @fn nmi_set_sys_clk_src_to_xo
* @brief
*/
void nmi_set_sys_clk_src_to_xo(void);
/*
* @fn chip_reset
* @brief
*/
sint8 chip_reset(void);
/*
* @fn wait_for_bootrom
* @brief
*/
sint8 wait_for_bootrom(uint8);
/*
* @fn wait_for_firmware_start
* @brief
*/
sint8 wait_for_firmware_start(uint8);
/*
* @fn chip_deinit
* @brief
*/
sint8 chip_deinit(void);
/*
* @fn chip_reset_and_cpu_halt
* @brief
*/
sint8 chip_reset_and_cpu_halt(void);
/*
* @fn set_gpio_dir
* @brief
*/
sint8 set_gpio_dir(uint8 gpio, uint8 dir);
/*
* @fn set_gpio_val
* @brief
*/
sint8 set_gpio_val(uint8 gpio, uint8 val);
/*
* @fn get_gpio_val
* @brief
*/
sint8 get_gpio_val(uint8 gpio, uint8 *val);
/*
* @fn pullup_ctrl
* @brief
*/
sint8 pullup_ctrl(uint32 pinmask, uint8 enable);
/*
* @fn nmi_get_otp_mac_address
* @brief
*/
sint8 nmi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 *pu8IsValid);
/*
* @fn nmi_get_mac_address
* @brief
*/
sint8 nmi_get_mac_address(uint8 *pu8MacAddr);
/*
* @fn chip_apply_conf
* @brief
*/
sint8 chip_apply_conf(uint32 u32conf);
#ifdef __cplusplus
}
#endif
#endif /*_NMASIC_H_*/

View File

@ -0,0 +1,288 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus APIs implementation.
*
* 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 CORTUS_APP
#include "nmbus.h"
#include "nmi2c.h"
#include "nmspi.h"
#include "nmuart.h"
#define MAX_TRX_CFG_SZ 8
/**
* @fn nm_bus_iface_init
* @brief Initialize bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_bus_iface_init(void *pvInitVal)
{
sint8 ret = M2M_SUCCESS;
ret = nm_bus_init(pvInitVal);
return ret;
}
/**
* @fn nm_bus_iface_deinit
* @brief Deinitialize bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Samer Sarhan
* @date 07 April 2014
* @version 1.0
*/
sint8 nm_bus_iface_deinit(void)
{
sint8 ret = M2M_SUCCESS;
ret = nm_bus_deinit();
return ret;
}
/**
* @fn nm_bus_reset
* @brief reset bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @version 1.0
*/
sint8 nm_bus_reset(void)
{
sint8 ret = M2M_SUCCESS;
#ifdef CONF_WINC_USE_UART
#elif defined(CONF_WINC_USE_SPI)
return nm_spi_reset();
#elif defined(CONF_WINC_USE_I2C)
#else
#error "Plesae define bus usage"
#endif
return ret;
}
/**
* @fn nm_bus_iface_reconfigure
* @brief reconfigure bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Viswanathan Murugesan
* @date 22 Oct 2014
* @version 1.0
*/
sint8 nm_bus_iface_reconfigure(void *ptr)
{
sint8 ret = M2M_SUCCESS;
#ifdef CONF_WINC_USE_UART
ret = nm_uart_reconfigure(ptr);
#endif
return ret;
}
/*
* @fn nm_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
uint32 nm_read_reg(uint32 u32Addr)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_read_reg(u32Addr);
#elif defined(CONF_WINC_USE_SPI)
return nm_spi_read_reg(u32Addr);
#elif defined(CONF_WINC_USE_I2C)
return nm_i2c_read_reg(u32Addr);
#else
#error "Plesae define bus usage"
#endif
}
/*
* @fn nm_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_read_reg_with_ret(uint32 u32Addr, uint32 *pu32RetVal)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_read_reg_with_ret(u32Addr, pu32RetVal);
#elif defined(CONF_WINC_USE_SPI)
return nm_spi_read_reg_with_ret(u32Addr, pu32RetVal);
#elif defined(CONF_WINC_USE_I2C)
return nm_i2c_read_reg_with_ret(u32Addr, pu32RetVal);
#else
#error "Plesae define bus usage"
#endif
}
/*
* @fn nm_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_write_reg(uint32 u32Addr, uint32 u32Val)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_write_reg(u32Addr, u32Val);
#elif defined(CONF_WINC_USE_SPI)
return nm_spi_write_reg(u32Addr, u32Val);
#elif defined(CONF_WINC_USE_I2C)
return nm_i2c_write_reg(u32Addr, u32Val);
#else
#error "Plesae define bus usage"
#endif
}
static sint8 p_nm_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_read_block(u32Addr, puBuf, u16Sz);
#elif defined(CONF_WINC_USE_SPI)
return nm_spi_read_block(u32Addr, puBuf, u16Sz);
#elif defined(CONF_WINC_USE_I2C)
return nm_i2c_read_block(u32Addr, puBuf, u16Sz);
#else
#error "Plesae define bus usage"
#endif
}
/*
* @fn nm_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u32Sz
* Number of bytes to read. The buffer size must be >= u32Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_read_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz)
{
uint16 u16MaxTrxSz = egstrNmBusCapabilities.u16MaxTrxSz - MAX_TRX_CFG_SZ;
uint32 off = 0;
sint8 s8Ret = M2M_SUCCESS;
for (;;) {
if (u32Sz <= u16MaxTrxSz) {
s8Ret += p_nm_read_block(u32Addr, &puBuf[off], (uint16)u32Sz);
break;
} else {
s8Ret += p_nm_read_block(u32Addr, &puBuf[off], u16MaxTrxSz);
if (M2M_SUCCESS != s8Ret)
break;
u32Sz -= u16MaxTrxSz;
off += u16MaxTrxSz;
u32Addr += u16MaxTrxSz;
}
}
return s8Ret;
}
static sint8 p_nm_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
{
#ifdef CONF_WINC_USE_UART
return nm_uart_write_block(u32Addr, puBuf, u16Sz);
#elif defined(CONF_WINC_USE_SPI)
return nm_spi_write_block(u32Addr, puBuf, u16Sz);
#elif defined(CONF_WINC_USE_I2C)
return nm_i2c_write_block(u32Addr, puBuf, u16Sz);
#else
#error "Plesae define bus usage"
#endif
}
/**
* @fn nm_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u32Sz
* Number of bytes to write. The buffer size must be >= u32Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_write_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz)
{
uint16 u16MaxTrxSz = egstrNmBusCapabilities.u16MaxTrxSz - MAX_TRX_CFG_SZ;
uint32 off = 0;
sint8 s8Ret = M2M_SUCCESS;
for (;;) {
if (u32Sz <= u16MaxTrxSz) {
s8Ret += p_nm_write_block(u32Addr, &puBuf[off], (uint16)u32Sz);
break;
} else {
s8Ret += p_nm_write_block(u32Addr, &puBuf[off], u16MaxTrxSz);
if (M2M_SUCCESS != s8Ret)
break;
u32Sz -= u16MaxTrxSz;
off += u16MaxTrxSz;
u32Addr += u16MaxTrxSz;
}
}
return s8Ret;
}
#endif

View File

@ -0,0 +1,141 @@
/**
*
* \file
*
* \brief This module contains NMC1000 bus APIs implementation.
*
* 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 _NMBUS_H_
#define _NMBUS_H_
#include "common/include/nm_common.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @fn nm_bus_iface_init
* @brief Initialize bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_iface_init(void *);
/**
* @fn nm_bus_iface_deinit
* @brief Deinitialize bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_iface_deinit(void);
/**
* @fn nm_bus_reset
* @brief reset bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @version 1.0
*/
sint8 nm_bus_reset(void);
/**
* @fn nm_bus_iface_reconfigure
* @brief reconfigure bus interface
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_bus_iface_reconfigure(void *ptr);
/**
* @fn nm_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
*/
uint32 nm_read_reg(uint32 u32Addr);
/**
* @fn nm_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_read_reg_with_ret(uint32 u32Addr, uint32 *pu32RetVal);
/**
* @fn nm_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_write_reg(uint32 u32Addr, uint32 u32Val);
/**
* @fn nm_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u32Sz
* Number of bytes to read. The buffer size must be >= u32Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_read_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz);
/**
* @fn nm_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u32Sz
* Number of bytes to write. The buffer size must be >= u32Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_write_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz);
#ifdef __cplusplus
}
#endif
#endif /* _NMBUS_H_ */

View File

@ -0,0 +1,379 @@
/**
*
* \file
*
* \brief This module contains NMC1000 M2M driver APIs implementation.
*
* 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
*
*/
#include "common/include/nm_common.h"
#include "driver/source/nmbus.h"
#include "bsp/include/nm_bsp.h"
#include "driver/source/nmdrv.h"
#include "driver/source/nmasic.h"
#include "driver/include/m2m_types.h"
#include "spi_flash/include/spi_flash.h"
#ifdef CONF_WINC_USE_SPI
#include "driver/source/nmspi.h"
#endif
/**
* @fn nm_get_firmware_info(tstrM2mRev* M2mRev)
* @brief Get Firmware version info
* @param [out] M2mRev
* pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
* @version 1.0
*/
sint8 nm_get_firmware_info(tstrM2mRev *M2mRev)
{
uint16 curr_drv_ver, min_req_drv_ver, curr_firm_ver;
uint32 reg = 0;
sint8 ret = M2M_SUCCESS;
ret = nm_read_reg_with_ret(NMI_REV_REG, &reg);
// In case the Firmware running is ATE fw
if (M2M_ATE_FW_IS_UP_VALUE == reg) {
// Read FW info again from the register specified for ATE
ret = nm_read_reg_with_ret(NMI_REV_REG_ATE, &reg);
}
M2mRev->u8DriverMajor = M2M_GET_DRV_MAJOR(reg);
M2mRev->u8DriverMinor = M2M_GET_DRV_MINOR(reg);
M2mRev->u8DriverPatch = M2M_GET_DRV_PATCH(reg);
M2mRev->u8FirmwareMajor = M2M_GET_FW_MAJOR(reg);
M2mRev->u8FirmwareMinor = M2M_GET_FW_MINOR(reg);
M2mRev->u8FirmwarePatch = M2M_GET_FW_PATCH(reg);
M2mRev->u32Chipid = nmi_get_chipid();
M2mRev->u16FirmwareSvnNum = 0;
curr_firm_ver = M2M_MAKE_VERSION(M2mRev->u8FirmwareMajor, M2mRev->u8FirmwareMinor, M2mRev->u8FirmwarePatch);
curr_drv_ver
= M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO);
min_req_drv_ver = M2M_MAKE_VERSION(M2mRev->u8DriverMajor, M2mRev->u8DriverMinor, M2mRev->u8DriverPatch);
if (curr_drv_ver < min_req_drv_ver) {
/*The current driver version should be larger or equal
than the min driver that the current firmware support */
ret = M2M_ERR_FW_VER_MISMATCH;
}
if (curr_drv_ver > curr_firm_ver) {
/*The current driver should be equal or less than the firmware version*/
ret = M2M_ERR_FW_VER_MISMATCH;
}
return ret;
}
/**
* @fn nm_get_firmware_info(tstrM2mRev* M2mRev)
* @brief Get Firmware version info
* @param [out] M2mRev
* pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
* @version 1.0
*/
sint8 nm_get_firmware_full_info(tstrM2mRev *pstrRev)
{
uint16 curr_drv_ver, min_req_drv_ver, curr_firm_ver;
uint32 reg = 0;
sint8 ret = M2M_SUCCESS;
tstrGpRegs strgp = {0};
if (pstrRev != NULL) {
m2m_memset((uint8 *)pstrRev, 0, sizeof(tstrM2mRev));
ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &reg);
if (ret == M2M_SUCCESS) {
if (reg != 0) {
ret = nm_read_block(reg | 0x30000, (uint8 *)&strgp, sizeof(tstrGpRegs));
if (ret == M2M_SUCCESS) {
reg = strgp.u32Firmware_Ota_rev;
reg &= 0x0000ffff;
if (reg != 0) {
ret = nm_read_block(reg | 0x30000, (uint8 *)pstrRev, sizeof(tstrM2mRev));
if (ret == M2M_SUCCESS) {
curr_firm_ver = M2M_MAKE_VERSION(
pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor, pstrRev->u8FirmwarePatch);
curr_drv_ver = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO,
M2M_RELEASE_VERSION_MINOR_NO,
M2M_RELEASE_VERSION_PATCH_NO);
min_req_drv_ver = M2M_MAKE_VERSION(
pstrRev->u8DriverMajor, pstrRev->u8DriverMinor, pstrRev->u8DriverPatch);
if ((curr_firm_ver == 0) || (min_req_drv_ver == 0) || (min_req_drv_ver == 0)) {
ret = M2M_ERR_FAIL;
goto EXIT;
}
if (curr_drv_ver < min_req_drv_ver) {
/*The current driver version should be larger or equal
than the min driver that the current firmware support */
ret = M2M_ERR_FW_VER_MISMATCH;
goto EXIT;
}
if (curr_drv_ver > curr_firm_ver) {
/*The current driver should be equal or less than the firmware version*/
ret = M2M_ERR_FW_VER_MISMATCH;
goto EXIT;
}
}
} else {
ret = M2M_ERR_FAIL;
}
}
} else {
ret = M2M_ERR_FAIL;
}
}
}
EXIT:
return ret;
}
/**
* @fn nm_get_ota_firmware_info(tstrM2mRev* pstrRev)
* @brief Get Firmware version info
* @param [out] M2mRev
* pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
* @version 1.0
*/
sint8 nm_get_ota_firmware_info(tstrM2mRev *pstrRev)
{
uint16 curr_drv_ver, min_req_drv_ver, curr_firm_ver;
uint32 reg = 0;
sint8 ret;
tstrGpRegs strgp = {0};
if (pstrRev != NULL) {
m2m_memset((uint8 *)pstrRev, 0, sizeof(tstrM2mRev));
ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &reg);
if (ret == M2M_SUCCESS) {
if (reg != 0) {
ret = nm_read_block(reg | 0x30000, (uint8 *)&strgp, sizeof(tstrGpRegs));
if (ret == M2M_SUCCESS) {
reg = strgp.u32Firmware_Ota_rev;
reg >>= 16;
if (reg != 0) {
ret = nm_read_block(reg | 0x30000, (uint8 *)pstrRev, sizeof(tstrM2mRev));
if (ret == M2M_SUCCESS) {
curr_firm_ver = M2M_MAKE_VERSION(
pstrRev->u8FirmwareMajor, pstrRev->u8FirmwareMinor, pstrRev->u8FirmwarePatch);
curr_drv_ver = M2M_MAKE_VERSION(M2M_RELEASE_VERSION_MAJOR_NO,
M2M_RELEASE_VERSION_MINOR_NO,
M2M_RELEASE_VERSION_PATCH_NO);
min_req_drv_ver = M2M_MAKE_VERSION(
pstrRev->u8DriverMajor, pstrRev->u8DriverMinor, pstrRev->u8DriverPatch);
if ((curr_firm_ver == 0) || (min_req_drv_ver == 0) || (min_req_drv_ver == 0)) {
ret = M2M_ERR_FAIL;
goto EXIT;
}
if (curr_drv_ver < min_req_drv_ver) {
/*The current driver version should be larger or equal
than the min driver that the current firmware support */
ret = M2M_ERR_FW_VER_MISMATCH;
}
if (curr_drv_ver > curr_firm_ver) {
/*The current driver should be equal or less than the firmware version*/
ret = M2M_ERR_FW_VER_MISMATCH;
}
}
} else {
ret = M2M_ERR_INVALID;
}
}
} else {
ret = M2M_ERR_FAIL;
}
}
} else {
ret = M2M_ERR_INVALID_ARG;
}
EXIT:
return ret;
}
/*
* @fn nm_drv_init_download_mode
* @brief Initialize NMC1000 driver
* @return M2M_SUCCESS in case of success and Negative error code in case of failure
* @param [in] arg
* Generic argument
* @author Viswanathan Murugesan
* @date 10 Oct 2014
* @version 1.0
*/
sint8 nm_drv_init_download_mode()
{
sint8 ret = M2M_SUCCESS;
ret = nm_bus_iface_init(NULL);
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi start]: fail init bus\n");
goto ERR1;
}
/**
TODO:reset the chip and halt the cpu in case of no wait efuse is set (add the no wait effuse check)
*/
if (!ISNMC3000(GET_CHIPID())) {
/*Execuate that function only for 1500A/B, no room in 3000, but it may be needed in 3400 no wait*/
chip_reset_and_cpu_halt();
}
#ifdef CONF_WINC_USE_SPI
/* Must do this after global reset to set SPI data packet size. */
nm_spi_init();
#endif
M2M_INFO("Chip ID %lx\n", nmi_get_chipid());
/*disable all interrupt in ROM (to disable uart) in 2b0 chip*/
nm_write_reg(0x20300, 0);
ERR1:
return ret;
}
/*
* @fn nm_drv_init
* @brief Initialize NMC1000 driver
* @return M2M_SUCCESS in case of success and Negative error code in case of failure
* @param [in] arg
* Generic argument
* @author M. Abdelmawla
* @date 15 July 2012
* @version 1.0
*/
sint8 nm_drv_init(void *arg)
{
sint8 ret = M2M_SUCCESS;
uint8 u8Mode;
if (NULL != arg) {
u8Mode = *((uint8 *)arg);
if ((u8Mode < M2M_WIFI_MODE_NORMAL) || (u8Mode >= M2M_WIFI_MODE_MAX)) {
u8Mode = M2M_WIFI_MODE_NORMAL;
}
} else {
u8Mode = M2M_WIFI_MODE_NORMAL;
}
ret = nm_bus_iface_init(NULL);
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi start]: fail init bus\n");
goto ERR1;
}
#ifdef BUS_ONLY
return;
#endif
#ifdef NO_HW_CHIP_EN
ret = chip_wake();
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi start]: fail chip_wakeup\n");
goto ERR2;
}
/**
Go...
**/
ret = chip_reset();
if (M2M_SUCCESS != ret) {
goto ERR2;
}
#endif
// M2M_INFO("Chip ID %lx\n", nmi_get_chipid());
#ifdef CONF_WINC_USE_SPI
/* Must do this after global reset to set SPI data packet size. */
nm_spi_init();
#endif
ret = wait_for_bootrom(u8Mode);
if (M2M_SUCCESS != ret) {
goto ERR2;
}
ret = wait_for_firmware_start(u8Mode);
if (M2M_SUCCESS != ret) {
goto ERR2;
}
if ((M2M_WIFI_MODE_ATE_HIGH == u8Mode) || (M2M_WIFI_MODE_ATE_LOW == u8Mode)) {
goto ERR1;
} else {
/*continue running*/
}
ret = enable_interrupts();
if (M2M_SUCCESS != ret) {
M2M_ERR("failed to enable interrupts..\n");
goto ERR2;
}
return ret;
ERR2:
nm_bus_iface_deinit();
ERR1:
return ret;
}
/*
* @fn nm_drv_deinit
* @brief Deinitialize NMC1000 driver
* @author M. Abdelmawla
* @date 17 July 2012
* @version 1.0
*/
sint8 nm_drv_deinit(void *arg)
{
sint8 ret;
ret = chip_deinit();
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi stop]: chip_deinit fail\n");
goto ERR1;
}
/* Disable SPI flash to save power when the chip is off */
ret = spi_flash_enable(0);
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi stop]: SPI flash disable fail\n");
goto ERR1;
}
ret = nm_bus_iface_deinit();
if (M2M_SUCCESS != ret) {
M2M_ERR("[nmi stop]: fail init bus\n");
goto ERR1;
}
#ifdef CONF_WINC_USE_SPI
/* Must do this after global reset to set SPI data packet size. */
nm_spi_deinit();
#endif
ERR1:
return ret;
}

View File

@ -0,0 +1,136 @@
/**
*
* \file
*
* \brief This module contains NMC1500 M2M driver 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 _NMDRV_H_
#define _NMDRV_H_
#include "common/include/nm_common.h"
/**
* @struct tstrM2mRev
* @brief Structure holding firmware version parameters and build date/time
*/
typedef struct {
uint32 u32Chipid; /* HW revision which will be basically the chip ID */
uint8 u8FirmwareMajor; /* Version Major Number which represents the official release base */
uint8 u8FirmwareMinor; /* Version Minor Number which represents the engineering release base */
uint8 u8FirmwarePatch; /* Version pathc Number which represents the pathces release base */
uint8 u8DriverMajor; /* Version Major Number which represents the official release base */
uint8 u8DriverMinor; /* Version Minor Number which represents the engineering release base */
uint8 u8DriverPatch; /* Version Patch Number which represents the pathces release base */
uint8 BuildDate[sizeof(__DATE__)];
uint8 BuildTime[sizeof(__TIME__)];
uint8 _PAD8_;
uint16 u16FirmwareSvnNum;
uint16 _PAD16_[2];
} tstrM2mRev;
/**
* @struct tstrM2mBinaryHeader
* @brief Structure holding compatibility version info for firmware binaries
*/
typedef struct {
tstrM2mRev binVerInfo;
uint32 flashOffset;
uint32 payloadSize;
} tstrM2mBinaryHeader;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @fn nm_get_firmware_info(tstrM2mRev* M2mRev)
* @brief Get Firmware version info
* @param [out] M2mRev
* pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
* @version 1.0
*/
sint8 nm_get_firmware_info(tstrM2mRev *M2mRev);
/**
* @fn nm_get_firmware_full_info(tstrM2mRev* pstrRev)
* @brief Get Firmware version info
* @param [out] M2mRev
* pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
* @version 1.0
*/
sint8 nm_get_firmware_full_info(tstrM2mRev *pstrRev);
/**
* @fn nm_get_ota_firmware_info(tstrM2mRev* pstrRev)
* @brief Get Firmware version info
* @param [out] M2mRev
* pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
* @version 1.0
*/
sint8 nm_get_ota_firmware_info(tstrM2mRev *pstrRev);
/*
* @fn nm_drv_init
* @brief Initialize NMC1000 driver
* @return ZERO in case of success and Negative error code in case of failure
*/
sint8 nm_drv_init_download_mode(void);
/*
* @fn nm_drv_init
* @brief Initialize NMC1000 driver
* @return M2M_SUCCESS in case of success and Negative error code in case of failure
* @param [in] arg
* Generic argument TBD
* @return ZERO in case of success and Negative error code in case of failure
*/
sint8 nm_drv_init(void *arg);
/**
* @fn nm_drv_deinit
* @brief Deinitialize NMC1000 driver
* @author M. Abdelmawla
* @param [in] arg
* Generic argument TBD
* @return ZERO in case of success and Negative error code in case of failure
*/
sint8 nm_drv_deinit(void *arg);
#ifdef __cplusplus
}
#endif
#endif /*_NMDRV_H_*/

View File

@ -0,0 +1,258 @@
/**
*
* \file
*
* \brief This module contains NMC1000 I2C protocol bus 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 "common/include/nm_common.h"
#ifdef CONF_WINC_USE_I2C
#include "nmi2c.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
/*
* @fn nm_i2c_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_i2c_read_reg_with_ret(uint32 u32Addr, uint32 *pu32RetVal)
{
uint8 b[6];
uint8 rsz;
tstrNmI2cDefault strI2c;
sint8 s8Ret = M2M_SUCCESS;
if (u32Addr < 0xff) { /* clockless i2c */
b[0] = 0x09;
b[1] = (uint8)(u32Addr);
rsz = 1;
strI2c.u16Sz = 2;
} else {
b[0] = 0x80;
b[1] = (uint8)(u32Addr >> 24);
b[2] = (uint8)(u32Addr >> 16);
b[3] = (uint8)(u32Addr >> 8);
b[4] = (uint8)(u32Addr);
b[5] = 0x04;
rsz = 4;
strI2c.u16Sz = 6;
}
strI2c.pu8Buf = b;
if (M2M_SUCCESS == nm_bus_ioctl(NM_BUS_IOCTL_W, &strI2c)) {
strI2c.u16Sz = rsz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strI2c)) {
// M2M_ERR("read error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
} else {
M2M_ERR("failed to send cfg bytes\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
if (rsz == 1) {
*pu32RetVal = b[0];
} else {
*pu32RetVal = b[0] | ((uint32)b[1] << 8) | ((uint32)b[2] << 16) | ((uint32)b[3] << 24);
}
return s8Ret;
}
/*
* @fn nm_i2c_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
uint32 nm_i2c_read_reg(uint32 u32Addr)
{
uint32 val;
nm_i2c_read_reg_with_ret(u32Addr, &val);
return val;
}
/*
* @fn nm_i2c_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_i2c_write_reg(uint32 u32Addr, uint32 u32Val)
{
tstrNmI2cDefault strI2c;
uint8 b[16];
sint8 s8Ret = M2M_SUCCESS;
if (u32Addr < 0xff) { /* clockless i2c */
b[0] = 0x19;
b[1] = (uint8)(u32Addr);
b[2] = (uint8)(u32Val);
strI2c.u16Sz = 3;
} else {
b[0] = 0x90;
b[1] = (uint8)(u32Addr >> 24);
b[2] = (uint8)(u32Addr >> 16);
b[3] = (uint8)(u32Addr >> 8);
b[4] = (uint8)u32Addr;
b[5] = 0x04;
b[6] = (uint8)u32Val;
b[7] = (uint8)(u32Val >> 8);
b[8] = (uint8)(u32Val >> 16);
b[9] = (uint8)(u32Val >> 24);
strI2c.u16Sz = 10;
}
strI2c.pu8Buf = b;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strI2c)) {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
return s8Ret;
}
/*
* @fn nm_i2c_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_i2c_read_block(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz)
{
tstrNmI2cDefault strI2c;
uint8 au8Buf[7];
sint8 s8Ret = M2M_SUCCESS;
au8Buf[0] = 0x02;
au8Buf[1] = (uint8)(u32Addr >> 24);
au8Buf[2] = (uint8)(u32Addr >> 16);
au8Buf[3] = (uint8)(u32Addr >> 8);
au8Buf[4] = (uint8)(u32Addr >> 0);
au8Buf[5] = (uint8)(u16Sz >> 8);
au8Buf[6] = (uint8)(u16Sz);
strI2c.pu8Buf = au8Buf;
strI2c.u16Sz = sizeof(au8Buf);
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strI2c)) {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
} else {
strI2c.pu8Buf = pu8Buf;
strI2c.u16Sz = u16Sz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strI2c)) {
M2M_ERR("read error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
return s8Ret;
}
/*
* @fn nm_i2c_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author M. Abdelmawla
* @date 11 July 2012
* @version 1.0
*/
sint8 nm_i2c_write_block(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz)
{
uint8 au8Buf[7];
tstrNmI2cSpecial strI2c;
sint8 s8Ret = M2M_SUCCESS;
au8Buf[0] = 0x12;
au8Buf[1] = (uint8)(u32Addr >> 24);
au8Buf[2] = (uint8)(u32Addr >> 16);
au8Buf[3] = (uint8)(u32Addr >> 8);
au8Buf[4] = (uint8)(u32Addr);
au8Buf[5] = (uint8)(u16Sz >> 8);
au8Buf[6] = (uint8)(u16Sz);
strI2c.pu8Buf1 = au8Buf;
strI2c.pu8Buf2 = pu8Buf;
strI2c.u16Sz1 = sizeof(au8Buf);
strI2c.u16Sz2 = u16Sz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W_SPECIAL, &strI2c)) {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
return s8Ret;
}
#endif
/* EOF */

View File

@ -0,0 +1,104 @@
/**
*
* \file
*
* \brief This module contains NMC1000 I2C protocol bus 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
*
*/
#ifndef _NMI2C_H_
#define _NMI2C_H_
#include "common/include/nm_common.h"
/**
* @fn nm_i2c_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
*/
uint32 nm_i2c_read_reg(uint32 u32Addr);
/**
* @fn nm_i2c_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_i2c_read_reg_with_ret(uint32 u32Addr, uint32 *pu32RetVal);
/**
* @fn nm_i2c_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_i2c_write_reg(uint32 u32Addr, uint32 u32Val);
/**
* @fn nm_i2c_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_i2c_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
/**
* @fn nm_i2c_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_i2c_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
#endif /* _NMI2C_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,132 @@
/**
*
* \file
*
* \brief This module contains NMC1000 SPI protocol bus APIs implementation.
*
* 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 _NMSPI_H_
#define _NMSPI_H_
#include "common/include/nm_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @fn nm_spi_init
* @brief Initialize the SPI
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_init(void);
/**
* @fn nm_spi_reset
* @brief reset the SPI
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_reset(void);
/**
* @fn nm_spi_deinit
* @brief DeInitialize the SPI
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_deinit(void);
/**
* @fn nm_spi_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
*/
uint32 nm_spi_read_reg(uint32 u32Addr);
/**
* @fn nm_spi_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_read_reg_with_ret(uint32 u32Addr, uint32 *pu32RetVal);
/**
* @fn nm_spi_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_write_reg(uint32 u32Addr, uint32 u32Val);
/**
* @fn nm_spi_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
/**
* @fn nm_spi_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_spi_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
#ifdef __cplusplus
}
#endif
#endif /* _NMSPI_H_ */

View File

@ -0,0 +1,471 @@
/**
*
* \file
*
* \brief This module contains NMC1000 UART protocol bus 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 "common/include/nm_common.h"
#ifdef CONF_WINC_USE_UART
#include "driver/source/nmuart.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
#define HDR_SZ 12
static uint8 get_cs(uint8 *b, uint8 sz)
{
int i;
uint8 cs = 0;
for (i = 0; i < sz; i++)
cs ^= b[i];
return cs;
}
/*
* @fn nm_uart_sync_cmd
* @brief Check COM Port
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
sint8 nm_uart_sync_cmd(void)
{
tstrNmUartDefault strUart;
sint8 s8Ret = -1;
uint8 b[HDR_SZ + 1];
uint8 rsz;
uint8 onchip = 0;
/*read reg*/
b[0] = 0x12;
rsz = 1;
strUart.pu8Buf = b;
strUart.u16Sz = 1;
if (M2M_SUCCESS == nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart)) {
strUart.u16Sz = rsz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
s8Ret = M2M_ERR_BUS_FAIL;
}
} else {
M2M_ERR("failed to send cfg bytes\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
if (b[0] == 0x5a) {
s8Ret = 0;
onchip = 1;
M2M_INFO("Built-in WINC1500 UART Found\n");
} else if (b[0] == 0x5b) {
s8Ret = 0;
onchip = 0;
M2M_INFO("WINC1500 Serial Bridge Found\n");
}
/*TODO: this should be the way we read the register since the cortus is little endian*/
/**pu32RetVal = b[0] | ((uint32)b[1] << 8) | ((uint32)b[2] << 16) | ((uint32)b[3] << 24);*/
if (s8Ret == M2M_SUCCESS)
s8Ret = (sint8)onchip;
return s8Ret;
}
sint8 nm_uart_read_reg_with_ret(uint32 u32Addr, uint32 *pu32RetVal)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
uint8 b[HDR_SZ + 1];
uint8 rsz;
/*read reg*/
b[0] = 0xa5;
b[1] = 0;
b[2] = 0;
b[3] = 0;
b[4] = 0;
b[5] = (uint8)(u32Addr & 0x000000ff);
b[6] = (uint8)((u32Addr & 0x0000ff00) >> 8);
b[7] = (uint8)((u32Addr & 0x00ff0000) >> 16);
b[8] = (uint8)((u32Addr & 0xff000000) >> 24);
b[9] = 0;
b[10] = 0;
b[11] = 0;
b[12] = 0;
b[2] = get_cs(&b[1], HDR_SZ);
rsz = 4;
strUart.pu8Buf = b;
strUart.u16Sz = sizeof(b);
if (M2M_SUCCESS == nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart)) {
if (!nm_bus_get_chip_type()) {
strUart.u16Sz = 1;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
s8Ret = M2M_ERR_BUS_FAIL;
}
if (b[0] == 0xAC) {
M2M_DBG("Successfully sent the command\n");
strUart.u16Sz = rsz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
s8Ret = M2M_ERR_BUS_FAIL;
}
} else {
s8Ret = M2M_ERR_BUS_FAIL;
}
} else {
strUart.u16Sz = rsz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
s8Ret = M2M_ERR_BUS_FAIL;
}
}
} else {
M2M_ERR("failed to send cfg bytes\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
/*TODO: this should be the way we read the register since the cortus is little endian*/
/**pu32RetVal = b[0] | ((uint32)b[1] << 8) | ((uint32)b[2] << 16) | ((uint32)b[3] << 24);*/
*pu32RetVal = ((uint32)b[0] << 24) | ((uint32)b[1] << 16) | ((uint32)b[2] << 8) | b[3];
return s8Ret;
}
/*
* @fn nm_uart_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
uint32 nm_uart_read_reg(uint32 u32Addr)
{
uint32 val;
nm_uart_read_reg_with_ret(u32Addr, &val);
return val;
}
/*
* @fn nm_uart_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
sint8 nm_uart_write_reg(uint32 u32Addr, uint32 u32Val)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
uint8 b[HDR_SZ + 1];
/*write reg*/
b[0] = 0xa5;
b[1] = 1;
b[2] = 0;
b[3] = 0;
b[4] = 0;
b[5] = (uint8)(u32Addr & 0x000000ff);
b[6] = (uint8)((u32Addr & 0x0000ff00) >> 8);
b[7] = (uint8)((u32Addr & 0x00ff0000) >> 16);
b[8] = (uint8)((u32Addr & 0xff000000) >> 24);
b[9] = (uint8)(u32Val & 0x000000ff);
b[10] = (uint8)((u32Val & 0x0000ff00) >> 8);
b[11] = (uint8)((u32Val & 0x00ff0000) >> 16);
b[12] = (uint8)((u32Val & 0xff000000) >> 24);
b[2] = get_cs(&b[1], HDR_SZ);
get_cs(&b[1], HDR_SZ);
strUart.pu8Buf = b;
strUart.u16Sz = sizeof(b);
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart)) {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
} else {
if (!nm_bus_get_chip_type()) {
// check for the ack from the SAMD21 for the packet reception.
strUart.u16Sz = 1;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
s8Ret = M2M_ERR_BUS_FAIL;
}
if (b[0] == 0xAC) {
M2M_DBG("Successfully sent the reg write command\n");
} else {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
return s8Ret;
}
/**
* @fn nm_uart_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
sint8 nm_uart_read_block(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
uint8 au8Buf[HDR_SZ + 1];
au8Buf[0] = 0xa5;
au8Buf[1] = 2;
au8Buf[2] = 0;
au8Buf[3] = (uint8)(u16Sz & 0x00ff);
au8Buf[4] = (uint8)((u16Sz & 0xff00) >> 8);
au8Buf[5] = (uint8)(u32Addr & 0x000000ff);
au8Buf[6] = (uint8)((u32Addr & 0x0000ff00) >> 8);
au8Buf[7] = (uint8)((u32Addr & 0x00ff0000) >> 16);
au8Buf[8] = (uint8)((u32Addr & 0xff000000) >> 24);
au8Buf[9] = 0;
au8Buf[10] = 0;
au8Buf[11] = 0;
au8Buf[12] = 0;
au8Buf[2] = get_cs(&au8Buf[1], HDR_SZ);
strUart.pu8Buf = au8Buf;
strUart.u16Sz = sizeof(au8Buf);
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart)) {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
} else {
if (!nm_bus_get_chip_type()) {
// check for the ack from the SAMD21 for the packet reception.
strUart.u16Sz = 1;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
s8Ret = M2M_ERR_BUS_FAIL;
}
if (au8Buf[0] == 0xAC) {
M2M_DBG("Successfully sent the block read command\n");
strUart.pu8Buf = pu8Buf;
strUart.u16Sz = u16Sz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
M2M_ERR("read error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
} else {
M2M_ERR("write error (Error sending the block read command)\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
} else {
strUart.pu8Buf = pu8Buf;
strUart.u16Sz = u16Sz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
M2M_ERR("read error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
return s8Ret;
}
/**
* @fn nm_uart_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Dina El Sissy
* @date 13 AUG 2012
* @version 1.0
*/
sint8 nm_uart_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
static uint8 au8Buf[HDR_SZ + 1];
au8Buf[0] = 0xa5;
au8Buf[1] = 3;
au8Buf[2] = 0;
au8Buf[3] = (uint8)(u16Sz & 0x00ff);
au8Buf[4] = (uint8)((u16Sz & 0xff00) >> 8);
au8Buf[5] = (uint8)(u32Addr & 0x000000ff);
au8Buf[6] = (uint8)((u32Addr & 0x0000ff00) >> 8);
au8Buf[7] = (uint8)((u32Addr & 0x00ff0000) >> 16);
au8Buf[8] = (uint8)((u32Addr & 0xff000000) >> 24);
au8Buf[9] = 0;
au8Buf[10] = 0;
au8Buf[11] = 0;
au8Buf[12] = 0;
au8Buf[2] = get_cs(&au8Buf[1], HDR_SZ);
strUart.pu8Buf = au8Buf;
strUart.u16Sz = sizeof(au8Buf);
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart)) {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
} else {
if (!nm_bus_get_chip_type()) {
// check for the ack from the SAMD21 for the packet reception.
strUart.u16Sz = 1;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
s8Ret = M2M_ERR_BUS_FAIL;
}
if (au8Buf[0] == 0xAC) {
M2M_DBG("Successfully sent the block Write command\n");
strUart.pu8Buf = puBuf;
strUart.u16Sz = u16Sz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart)) {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
} else {
// check for the ack from the SAMD21 for the payload reception.
strUart.pu8Buf = au8Buf;
strUart.u16Sz = 1;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
s8Ret = M2M_ERR_BUS_FAIL;
}
if (au8Buf[0] == 0xAC) {
M2M_DBG("Successfully sent the data payload\n");
} else {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
} else {
M2M_ERR("write error (Error sending the block write command)\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
} else {
strUart.pu8Buf = puBuf;
strUart.u16Sz = u16Sz;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart)) {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
return s8Ret;
}
/**
* @fn nm_uart_reconfigure
* @brief Reconfigures the UART interface
* @param [in] ptr
* Pointer to a DWORD containing baudrate at this moment.
* @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
* @author Viswanathan Murugesan
* @date 22 OCT 2014
* @version 1.0
*/
sint8 nm_uart_reconfigure(void *ptr)
{
tstrNmUartDefault strUart;
sint8 s8Ret = M2M_SUCCESS;
uint8 b[HDR_SZ + 1];
/*write reg*/
b[0] = 0xa5;
b[1] = 5;
b[2] = 0;
b[3] = 0;
b[4] = 0;
b[5] = 0;
b[6] = 0;
b[7] = 0;
b[8] = 0;
b[9] = (uint8)((*(unsigned long *)ptr) & 0x000000ff);
b[10] = (uint8)(((*(unsigned long *)ptr) & 0x0000ff00) >> 8);
b[11] = (uint8)(((*(unsigned long *)ptr) & 0x00ff0000) >> 16);
b[12] = (uint8)(((*(unsigned long *)ptr) & 0xff000000) >> 24);
b[2] = get_cs(&b[1], HDR_SZ);
get_cs(&b[1], HDR_SZ);
strUart.pu8Buf = b;
strUart.u16Sz = sizeof(b);
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strUart)) {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
} else {
if (!nm_bus_get_chip_type()) {
// check for the ack from the SAMD21 for the packet reception.
strUart.u16Sz = 1;
if (M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strUart)) {
s8Ret = M2M_ERR_BUS_FAIL;
}
if (b[0] == 0xAC) {
M2M_DBG("Successfully sent the UART reconfigure command\n");
} else {
M2M_ERR("write error\n");
s8Ret = M2M_ERR_BUS_FAIL;
}
}
}
return s8Ret;
}
#endif
/* EOF */

View File

@ -0,0 +1,118 @@
/**
*
* \file
*
* \brief This module contains NMC1000 UART protocol bus 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
*
*/
#ifndef _NMUART_H_
#define _NMUART_H_
#include "common/include/nm_common.h"
/*
* @fn nm_uart_sync_cmd
* @brief Check COM Port
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_sync_cmd(void);
/**
* @fn nm_uart_read_reg
* @brief Read register
* @param [in] u32Addr
* Register address
* @return Register value
*/
uint32 nm_uart_read_reg(uint32 u32Addr);
/**
* @fn nm_uart_read_reg_with_ret
* @brief Read register with error code return
* @param [in] u32Addr
* Register address
* @param [out] pu32RetVal
* Pointer to u32 variable used to return the read value
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_read_reg_with_ret(uint32 u32Addr, uint32 *pu32RetVal);
/**
* @fn nm_uart_write_reg
* @brief write register
* @param [in] u32Addr
* Register address
* @param [in] u32Val
* Value to be written to the register
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_write_reg(uint32 u32Addr, uint32 u32Val);
/**
* @fn nm_uart_read_block
* @brief Read block of data
* @param [in] u32Addr
* Start address
* @param [out] puBuf
* Pointer to a buffer used to return the read data
* @param [in] u16Sz
* Number of bytes to read. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_read_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
/**
* @fn nm_uart_write_block
* @brief Write block of data
* @param [in] u32Addr
* Start address
* @param [in] puBuf
* Pointer to the buffer holding the data to be written
* @param [in] u16Sz
* Number of bytes to write. The buffer size must be >= u16Sz
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_write_block(uint32 u32Addr, uint8 *puBuf, uint16 u16Sz);
/**
* @fn nm_uart_reconfigure
* @brief Reconfigures the UART interface
* @param [in] ptr
* Pointer to a DWORD containing baudrate at this moment.
* @return ZERO in case of success and M2M_ERR_BUS_FAIL in case of failure
*/
sint8 nm_uart_reconfigure(void *ptr);
#endif /* _NMI2C_H_ */

View File

@ -0,0 +1,71 @@
/**
*
* \file
*
* \brief WINC Peripherals Application Interface.
*
* Copyright (c) 2017-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 __PROGRAMMER_H__
#define __PROGRAMMER_H__
/**
* Include
*/
#include "spi_flash/include/spi_flash_map.h"
#include "spi_flash/include/spi_flash.h"
#define ROOT_CERT_SIZE M2M_TLS_ROOTCER_FLASH_SIZE
#define programmer_get_flash_size() (((spi_flash_get_size() * 1024) / 8) * 1024)
#define programmer_write(pu8Buf, u32Offset, u32Sz) spi_flash_write(pu8Buf, u32Offset, u32Sz)
#define programmer_erase(u32Offset, u32Sz) spi_flash_erase(u32Offset, u32Sz)
#define programmer_eraseall() programmer_erase(0, programmer_get_flash_size())
#define programmer_read(pu8Buf, u32Offset, u32Sz) spi_flash_read(pu8Buf, u32Offset, u32Sz)
#define programmer_write_root_cert(buff) \
programmer_write((uint8 *)buff, M2M_TLS_ROOTCER_FLASH_OFFSET, M2M_TLS_ROOTCER_FLASH_SIZE)
#define programmer_read_root_cert(buff) \
programmer_read((uint8 *)buff, M2M_TLS_ROOTCER_FLASH_OFFSET, M2M_TLS_ROOTCER_FLASH_SIZE)
#define programmer_erase_root_cert() programmer_erase(M2M_TLS_ROOTCER_FLASH_OFFSET, M2M_TLS_ROOTCER_FLASH_SIZE)
#define programmer_write_tls_cert_store(buff) \
programmer_write((uint8 *)buff, M2M_TLS_SERVER_FLASH_OFFSET, M2M_TLS_SERVER_FLASH_SIZE)
#define programmer_read_tls_cert_store(buff) \
programmer_read((uint8 *)buff, M2M_TLS_SERVER_FLASH_OFFSET, M2M_TLS_SERVER_FLASH_SIZE)
#define programmer_erase_tls_cert_store() programmer_erase(M2M_TLS_SERVER_FLASH_OFFSET, M2M_TLS_SERVER_FLASH_SIZE)
#endif /* __PROGRAMMER_H__ */

View File

@ -0,0 +1,65 @@
/**
*
* \file
*
* \brief Programmer APIs.
*
* Copyright (c) 2017-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 FIRMWARE_PROGRAMMER_APIS_H_INCLUDED
#define FIRMWARE_PROGRAMMER_APIS_H_INCLUDED
/**
* Include
*/
#include "common/include/nm_common.h"
#include "programmer/programmer.h"
#include "spi_flash/include/spi_flash_map.h"
#define programmer_write_cert_image(buff) \
programmer_write((uint8 *)buff, M2M_TLS_FLASH_ROOTCERT_CACHE_OFFSET, M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE)
#define programmer_read_cert_image(buff) \
programmer_read((uint8 *)buff, M2M_TLS_FLASH_ROOTCERT_CACHE_OFFSET, M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE)
#define programmer_erase_cert_image() \
programmer_erase(M2M_TLS_FLASH_ROOTCERT_CACHE_OFFSET, M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE)
#define programmer_write_firmware_image(buff, offSet, sz) programmer_write((uint8 *)buff, offSet, sz)
#define programmer_read_firmware_image(buff, offSet, sz) programmer_read((uint8 *)buff, offSet, sz)
//#define programmer_erase_firmware_image() programmer_eraseall()
#define programmer_erase_all() programmer_erase(0, programmer_get_flash_size())
#endif /* __FIRMWARE_PROGRAMMER_APIS__ */

View File

@ -0,0 +1,416 @@
/**
*
* \file
*
* \brief BSD compatible socket interface internal types.
*
* Copyright (c) 2014 - 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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_SOCKET_HOST_IF_H__
#define __M2M_SOCKET_HOST_IF_H__
#ifdef __cplusplus
extern "C" {
#endif
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#ifndef _BOOT_
#ifndef _FIRMWARE_
#include "socket/include/socket.h"
#else
#include "m2m_types.h"
#endif
#endif
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*
* HOSTNAME_MAX_SIZE is defined here and also in host_drv/socket/include/socket.h
* The two definitions must match.
*/
#ifdef _FIRMWARE_
#define HOSTNAME_MAX_SIZE (64)
#endif
#define SSL_MAX_OPT_LEN HOSTNAME_MAX_SIZE
#define SOCKET_CMD_INVALID 0x00
/*!<
Invlaid Socket command value.
*/
#define SOCKET_CMD_BIND 0x41
/*!<
Socket Binding command value.
*/
#define SOCKET_CMD_LISTEN 0x42
/*!<
Socket Listening command value.
*/
#define SOCKET_CMD_ACCEPT 0x43
/*!<
Socket Accepting command value.
*/
#define SOCKET_CMD_CONNECT 0x44
/*!<
Socket Connecting command value.
*/
#define SOCKET_CMD_SEND 0x45
/*!<
Socket send command value.
*/
#define SOCKET_CMD_RECV 0x46
/*!<
Socket Recieve command value.
*/
#define SOCKET_CMD_SENDTO 0x47
/*!<
Socket sendTo command value.
*/
#define SOCKET_CMD_RECVFROM 0x48
/*!<
Socket RecieveFrom command value.
*/
#define SOCKET_CMD_CLOSE 0x49
/*!<
Socket Close command value.
*/
#define SOCKET_CMD_DNS_RESOLVE 0x4A
/*!<
Socket DNS Resolve command value.
*/
#define SOCKET_CMD_SSL_CONNECT 0x4B
/*!<
SSL-Socket Connect command value.
*/
#define SOCKET_CMD_SSL_SEND 0x4C
/*!<
SSL-Socket Send command value.
*/
#define SOCKET_CMD_SSL_RECV 0x4D
/*!<
SSL-Socket Recieve command value.
*/
#define SOCKET_CMD_SSL_CLOSE 0x4E
/*!<
SSL-Socket Close command value.
*/
#define SOCKET_CMD_SET_SOCKET_OPTION 0x4F
/*!<
Set Socket Option command value.
*/
#define SOCKET_CMD_SSL_CREATE 0x50
/*!<
*/
#define SOCKET_CMD_SSL_SET_SOCK_OPT 0x51
/*!<
*/
#define SOCKET_CMD_PING 0x52
/*!<
*/
#define SOCKET_CMD_SSL_SET_CS_LIST 0x53
/*!<
Recommend instead using @ref M2M_SSL_REQ_SET_CS_LIST and
associated response @ref M2M_SSL_RESP_SET_CS_LIST
*/
#define SOCKET_CMD_SSL_BIND 0x54
/*!<
*/
#define SOCKET_CMD_SSL_EXP_CHECK 0x55
/*!<
*/
#define PING_ERR_SUCCESS 0
#define PING_ERR_DEST_UNREACH 1
#define PING_ERR_TIMEOUT 2
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*!
* @brief
*/
typedef struct {
uint16 u16Family;
uint16 u16Port;
uint32 u32IPAddr;
} tstrSockAddr;
//typedef sint8 SOCKET;
typedef tstrSockAddr tstrUIPSockAddr;
/*!
@struct \
tstrDnsReply
@brief
DNS Reply, contains hostName and HostIP.
*/
typedef struct {
char acHostName[HOSTNAME_MAX_SIZE];
uint32 u32HostIP;
} tstrDnsReply;
/*!
@brief
*/
typedef struct {
tstrSockAddr strAddr;
SOCKET sock;
uint8 u8Void;
uint16 u16SessionID;
} tstrBindCmd;
/*!
@brief
*/
typedef struct {
SOCKET sock;
sint8 s8Status;
uint16 u16SessionID;
} tstrBindReply;
/*!
* @brief
*/
typedef struct {
SOCKET sock;
uint8 u8BackLog;
uint16 u16SessionID;
} tstrListenCmd;
/*!
@struct \
tstrSocketRecvMsg
@brief Socket recv status.
It is passed to the APPSocketEventHandler with SOCKET_MSG_RECV or SOCKET_MSG_RECVFROM message type
in a response to a user call to the recv or recvfrom.
If the received data from the remote peer is larger than the USER Buffer size (given at recv call), the data is
delivered to the user in a number of consecutive chunks according to the USER Buffer size.
*/
typedef struct {
SOCKET sock;
sint8 s8Status;
uint16 u16SessionID;
} tstrListenReply;
/*!
* @brief
*/
typedef struct {
tstrSockAddr strAddr;
SOCKET sListenSock;
SOCKET sConnectedSock;
uint16 u16AppDataOffset;
/*!<
In further packet send requests the host interface should put the user application
data at this offset in the allocated shared data packet.
*/
} tstrAcceptReply;
/*!
* @brief
*/
typedef struct {
tstrSockAddr strAddr;
SOCKET sock;
uint8 u8SslFlags;
uint16 u16SessionID;
} tstrConnectCmd;
/*!
@struct \
tstrConnectReply
@brief
Connect Reply, contains sock number and error value
*/
typedef struct {
SOCKET sock;
sint8 s8Error;
uint16 u16AppDataOffset;
/*!<
In further packet send requests the host interface should put the user application
data at this offset in the allocated shared data packet.
*/
} tstrConnectReply;
/*!
@brief
*/
typedef struct {
SOCKET sock;
uint8 u8Void;
uint16 u16DataSize;
tstrSockAddr strAddr;
uint16 u16SessionID;
uint16 u16Void;
} tstrSendCmd;
/*!
@struct \
tstrSendReply
@brief
Send Reply, contains socket number and number of sent bytes.
*/
typedef struct {
SOCKET sock;
uint8 u8Void;
sint16 s16SentBytes;
uint16 u16SessionID;
uint16 u16Void;
} tstrSendReply;
/*!
* @brief
*/
typedef struct {
uint32 u32Timeoutmsec;
SOCKET sock;
uint8 u8Void;
uint16 u16SessionID;
} tstrRecvCmd;
/*!
@struct
@brief
*/
typedef struct {
tstrSockAddr strRemoteAddr;
sint16 s16RecvStatus;
uint16 u16DataOffset;
SOCKET sock;
uint8 u8Void;
uint16 u16SessionID;
} tstrRecvReply;
/*!
* @brief
*/
typedef struct {
uint32 u32OptionValue;
SOCKET sock;
uint8 u8Option;
uint16 u16SessionID;
} tstrSetSocketOptCmd;
typedef struct {
SOCKET sslSock;
uint8 __PAD24__[3];
} tstrSSLSocketCreateCmd;
/*!
* @brief
*/
typedef struct {
SOCKET sock;
uint8 u8Option;
uint16 u16SessionID;
uint32 u32OptLen;
uint8 au8OptVal[SSL_MAX_OPT_LEN];
} tstrSSLSetSockOptCmd;
/*!
*/
typedef struct {
uint32 u32DestIPAddr;
uint32 u32CmdPrivate;
uint16 u16PingCount;
uint8 u8TTL;
uint8 __PAD8__;
} tstrPingCmd;
typedef struct {
uint32 u32IPAddr;
uint32 u32CmdPrivate;
uint32 u32RTT;
uint16 u16Success;
uint16 u16Fail;
uint8 u8ErrorCode;
uint8 __PAD24__[3];
} tstrPingReply;
/*!
@struct\
tstrSslCertExpSettings
@brief SSL Certificate Expiry Validation Settings
@sa tenuSslCertExpSettings
*/
typedef struct {
uint32 u32CertExpValidationOpt;
/*!<
See @tenuSslCertExpSettings for possible values.
*/
} tstrSslCertExpSettings;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __M2M_SOCKET_HOST_IF_H__ */

Some files were not shown because too many files have changed in this diff Show More