#if defined( __CODEVISIONAVR__ )
#else
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#endif
#include "mbport.h"
#include "mbs.h"
#include "common/mbtypes.h"
#include "common/mbutils.h"
#include "common/mbportlayer.h"
#define DEBUG_LED_PORT ( PORTA )
#define DEBUG_LED_PIN ( PINA4 )
#define DEBUG_LED_DDR ( DDRA )
#define DEBUG_LED_0 ( 0 )
#define MBS_SERIAL_PORT ( 0 )
#define MBS_SERIAL_BAUDRATE ( 19200 )
#define MBS_PARITY ( MB_PAR_NONE )
#define MBS_SLAVE_ADDRESS ( 1 )
#define REG_INPUT_SECONDS_OFF ( 0 )
#define REG_INPUT_MINUTES_OFF ( 1 )
#define REG_INPUT_HOURS_OFF ( 2 )
#define REG_INPUT_POWER_OUT ( 3 )
#define REG_HOLDING_POWER_OUT ( 0 )
#define REG_HOLDING_VALVE_1 ( 1 )
#define REG_HOLDING_VALVE_2 ( 2 )
STATIC USHORT usRegInputValue[16];
STATIC USHORT usRegHoldingValue[3];
STATIC void vIOSetLED( UBYTE ubIdx, BOOL bTurnOn );
STATIC eMBException eMyRegInputCB( UBYTE * pubRegBuffer, USHORT usAddress, USHORT usNRegs );
STATIC eMBException eMyRegHoldingCB( UBYTE * pubRegBuffer, USHORT usAddress,
USHORT usNRegs, eMBSRegisterMode eRegMode );
STATIC eMBException eMyDiscInputCB( UBYTE * pubRegBuffer, USHORT usAddress, USHORT usNRegs );
STATIC void vSetupRTC( void );
#if defined( __CODEVISIONAVR__ )
void
main( void )
#else
int
main( void )
#endif
{
eMBErrorCode eStatus;
xMBSHandle xMBSHdl;
sei( );
do
{
vSetupRTC( );
if( MB_ENOERR !=
( eStatus =
eMBSSerialInit( &xMBSHdl, MB_RTU, MBS_SLAVE_ADDRESS,
MBS_SERIAL_PORT, MBS_SERIAL_BAUDRATE, MBS_PARITY ) ) )
{
}
else if( MB_ENOERR != ( eStatus = eMBSRegisterInputCB( xMBSHdl, eMyRegInputCB ) ) )
{
( void )eMBSClose( xMBSHdl );
}
else if( MB_ENOERR != ( eStatus = eMBSRegisterHoldingCB( xMBSHdl, eMyRegHoldingCB ) ) )
{
( void )eMBSClose( xMBSHdl );
}
else if( MB_ENOERR != ( eStatus = eMBSRegisterDiscreteCB( xMBSHdl, eMyDiscInputCB ) ) )
{
( void )eMBSClose( xMBSHdl );
}
else
{
do
{
eMBSPoll( xMBSHdl );
vIOSetLED( DEBUG_LED_0, usRegHoldingValue[REG_HOLDING_VALVE_1] > 0 ? 1 : 0 );
}
while( MB_ENOERR == eStatus );
( void )eMBSClose( xMBSHdl );
}
}
while( TRUE );
}
eMBException
eMyRegInputCB( UBYTE * pubRegBuffer, USHORT usAddress, USHORT usNRegs )
{
eMBException eException = MB_PDU_EX_ILLEGAL_DATA_ADDRESS;
STATIC const ULONG usRegsMappedAt = 0x0100;
ULONG usRegStart = usAddress;
ULONG usRegEnd = usAddress + usNRegs - 1;
USHORT usIndex;
USHORT usIndexEnd;
if( ( usNRegs > 0 ) &&
( usRegStart >= usRegsMappedAt ) && ( usRegEnd <= ( usRegsMappedAt + MB_UTILS_NARRSIZE( usRegInputValue ) ) ) )
{
usIndex = ( USHORT ) ( usRegStart - usRegsMappedAt );
usIndexEnd = ( USHORT ) ( usRegEnd - usRegsMappedAt );
for( ; usIndex <= usIndexEnd; usIndex++ )
{
*pubRegBuffer++ = ( UBYTE ) ( usRegInputValue[usIndex] >> 8 );
*pubRegBuffer++ = ( UBYTE ) ( usRegInputValue[usIndex] & 0xFF );
}
eException = MB_PDU_EX_NONE;
}
return eException;
}
eMBException
eMyRegHoldingCB( UBYTE * pubRegBuffer, USHORT usAddress, USHORT usNRegs, eMBSRegisterMode eRegMode )
{
eMBException eException = MB_PDU_EX_ILLEGAL_DATA_ADDRESS;
STATIC const ULONG usRegsMappedAt = 0x0200;
ULONG usRegStart = usAddress;
ULONG usRegEnd = usAddress + usNRegs - 1;
USHORT usIndex;
USHORT usIndexEnd;
if( ( usNRegs > 0 ) &&
( usRegStart >= usRegsMappedAt )
&& ( usRegEnd <= ( usRegsMappedAt + MB_UTILS_NARRSIZE( usRegHoldingValue ) ) ) )
{
usIndex = ( USHORT ) ( usRegStart - usRegsMappedAt );
usIndexEnd = ( USHORT ) ( usRegEnd - usRegsMappedAt );
switch ( eRegMode )
{
case MBS_REGISTER_WRITE:
for( ; usIndex <= usIndexEnd; usIndex++ )
{
usRegHoldingValue[usIndex] = ( USHORT ) * pubRegBuffer++ << 8;
usRegHoldingValue[usIndex] |= ( USHORT ) * pubRegBuffer++;
}
break;
default:
case MBS_REGISTER_READ:
for( ; usIndex <= usIndexEnd; usIndex++ )
{
*pubRegBuffer++ = ( UBYTE ) ( usRegHoldingValue[usIndex] >> 8 );
*pubRegBuffer++ = ( UBYTE ) ( usRegHoldingValue[usIndex] & 0xFF );
}
break;
}
eException = MB_PDU_EX_NONE;
}
return eException;
}
eMBException
eMyDiscInputCB( UBYTE * pubRegBuffer, USHORT usAddress, USHORT usNRegs )
{
eMBException eException = MB_PDU_EX_ILLEGAL_DATA_ADDRESS;
STATIC const ULONG usRegsMappedAt = 0x0100;
ULONG usRegStart = usAddress;
ULONG usRegEnd = usAddress + usNRegs - 1;
USHORT usIndex;
USHORT usIndexEnd;
if( ( usNRegs > 0 ) &&
( usRegStart >= usRegsMappedAt ) && ( usRegEnd <= ( usRegsMappedAt + MB_UTILS_NARRSIZE( usRegInputValue ) ) ) )
{
usIndex = ( USHORT ) ( usRegStart - usRegsMappedAt );
usIndexEnd = ( USHORT ) ( usRegEnd - usRegsMappedAt );
for( ; usIndex <= usIndexEnd; usIndex++ )
{
*pubRegBuffer++ = ( UBYTE ) ( usRegInputValue[usIndex] >> 8 );
*pubRegBuffer++ = ( UBYTE ) ( usRegInputValue[usIndex] & 0xFF );
}
eException = MB_PDU_EX_NONE;
}
return eException;
}
void
vSetupRTC( void )
{
MBP_ENTER_CRITICAL_SECTION( );
#if defined( __AVR_ATmega168__ )
TCCR0A = _BV( WGM01 );
TCCR0B = _BV( CS02 ) | _BV( CS00 );
OCR0A = ( ( F_CPU ) / ( ( ULONG ) 1024UL * 100UL ) );
TIMSK0 = _BV( OCIE0A );
#endif
MBP_EXIT_CRITICAL_SECTION( );
}
void
vIOSetLED( UBYTE ubIdx, BOOL bTurnOn )
{
STATIC BOOL bIsInitalized = FALSE;
if( !bIsInitalized )
{
DEBUG_LED_DDR |= _BV( DEBUG_LED_PIN );
DEBUG_LED_PORT |= _BV( DEBUG_LED_PIN );
bIsInitalized = TRUE;
}
switch ( ubIdx )
{
case DEBUG_LED_0:
if( bTurnOn )
{
DEBUG_LED_PORT &= ~_BV( DEBUG_LED_PIN );
}
else
{
DEBUG_LED_PORT |= _BV( DEBUG_LED_PIN );
}
break;
default:
break;
}
}
#if defined( __AVR_ATmega168__ )
SIGNAL( SIG_OUTPUT_COMPARE0A )
{
STATIC UBYTE us100MSSecCounter = 0;
STATIC UBYTE us10MSSecCounter = 0;
us10MSSecCounter++;
us100MSSecCounter++;
if( us10MSSecCounter >= 100 )
{
us10MSSecCounter = 0;
usRegInputValue[REG_INPUT_SECONDS_OFF]++;
if( usRegInputValue[REG_INPUT_SECONDS_OFF] >= 60 )
{
usRegInputValue[REG_INPUT_SECONDS_OFF] = 0;
usRegInputValue[REG_INPUT_MINUTES_OFF]++;
if( usRegInputValue[REG_INPUT_MINUTES_OFF] >= 60 )
{
usRegInputValue[REG_INPUT_MINUTES_OFF] = 0;
usRegInputValue[REG_INPUT_HOURS_OFF]++;
}
}
}
if( us100MSSecCounter >= 10 )
{
us100MSSecCounter = 0;
if( usRegHoldingValue[REG_HOLDING_POWER_OUT] != usRegInputValue[REG_INPUT_POWER_OUT] )
{
if( usRegInputValue[REG_INPUT_POWER_OUT] < usRegHoldingValue[REG_HOLDING_POWER_OUT] )
{
usRegInputValue[REG_INPUT_POWER_OUT]++;
}
else
{
usRegInputValue[REG_INPUT_POWER_OUT]--;
}
}
}
}
#endif