You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

156 lines
5.6 KiB
C

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h> // WatchDog
#include <stdint.h>
#include <string.h>
#include "avrIOhelper/io-helper.h"
#include "millis.h"
#include "uart.h"
#include "modbus.h"
volatile uint32_t inputEdgesBoth;
volatile uint32_t inputEdgesFalling;
volatile uint32_t inputEdgesRising;
// Timer0
// 1ms IRQ
// Used for millis() timing
void timer0_init()
{
TCCR0A = (1<<WGM01); //TIMER0 SET-UP: CTC MODE
TCCR0B = (1<<CS01)|(1<<CS00); // PS 1:64
OCR0A = 249; // 1ms reach for clear (16mz:64=>250kHz:250-=>1kHz)
TIMSK0 |= 1<<OCIE0A; //IRQ on TIMER0 output compareA
}
void timer2_init()
{
TCCR2A = (1<<WGM21); //TIMER0 SET-UP: CTC MODE
TCCR2B|=(1<<CS21); //prescaler 8
OCR2A = 200;
TIMSK2|=(1<<OCIE2A);
}
void modbusGet(void) {
if (modbusGetBusState() & (1<<ReceiveCompleted))
{
switch(rxbuffer[1]) {
case fcPresetSingleRegister:
case fcPresetMultipleRegisters:
case fcReadHoldingRegisters:
modbusExchangeRegisters((void *)outStates,0,1);
break;
case fcReadInputRegisters:
if(modbusRequestedAddress() < 100)
modbusExchangeRegisters((void *)inStates,0,nrOfInputs/16);
else if(modbusRequestedAddress() < 200){
modbusExchangeRegisters((void *)&inputEdgesBoth,100,nrOfInputs/16);
for(uint16_t i = modbusDataLocation - 100; i < modbusDataLocation-100+(modbusDataAmount*16); i++)
inputEdgesBoth &= ~(1 << i);
}
else if(modbusRequestedAddress() < 300){
modbusExchangeRegisters((void *)&inputEdgesFalling,200,nrOfInputs/16);
for(uint16_t i = modbusDataLocation - 200; i < modbusDataLocation-200+(modbusDataAmount*16); i++)
inputEdgesFalling &= ~(1 << i);
}
else if(modbusRequestedAddress() < 400){
modbusExchangeRegisters((void *)&inputEdgesRising,300,nrOfInputs/16);
for(uint16_t i = modbusDataLocation - 300; i < modbusDataLocation-300+(modbusDataAmount*16); i++)
inputEdgesRising &= ~(1 << i);
}
break;
case fcReadInputStatus:
if(modbusRequestedAddress() < 100)
modbusExchangeBits(inStates,0,nrOfInputs);
else if(modbusRequestedAddress() < 200){
modbusExchangeBits((void*)&inputEdgesBoth,100,nrOfInputs);
for(uint16_t i = modbusDataLocation - 100; i < modbusDataLocation+modbusDataAmount-100; i++)
inputEdgesBoth &= ~(1 << i);
}
else if(modbusRequestedAddress() < 300){
modbusExchangeBits((void*)&inputEdgesFalling,200,nrOfInputs);
for(uint16_t i = modbusDataLocation - 200; i < modbusDataLocation+modbusDataAmount-200; i++)
inputEdgesFalling &= ~(1 << i);
}
else if(modbusRequestedAddress() < 400){
modbusExchangeBits((void*)&inputEdgesRising,300,nrOfInputs);
for(uint16_t i = modbusDataLocation - 300; i < modbusDataLocation+modbusDataAmount-300; i++)
inputEdgesRising &= ~(1 << i);
}
break;
case fcForceMultipleCoils:
case fcForceSingleCoil:
case fcReadCoilStatus:
if(modbusRequestedAddress() < 100)
modbusExchangeBits(outStates,0,nrOfOutputs);
else if(modbusRequestedAddress() < 200)
modbusExchangeBits(outStatesBlinking,100,nrOfOutputs);
else if(modbusRequestedAddress() < 300){
uint8_t outStatesToggle[sizeof(outStates)];
memset(outStatesToggle, 0, sizeof(outStatesToggle));
modbusExchangeBits(outStatesToggle,200,nrOfOutputs);
for(uint8_t i=0; i<sizeof(outStates); i++){
outStates[i] ^= outStatesToggle[i];
}
}
break;
default:
modbusSendException(ecIllegalFunction);
break;
}
}
}
int main()
{
wdt_enable(WDTO_2S); // set up wdt reset interval 2 second
uart_init();
ioHelperIoConf();
timer0_init();// Timer0 millis engine init
modbusSetAddress(4);
modbusInit();
timer2_init();
sei();
set_Output(LED_EXTR_FEHLER, BLINK);
uint32_t timer_blink_outs = millis();
printf("moin\n");
while(1)
{
wdt_reset(); // wdt reset ~ every <2000ms
ioHelperReadPins();
ioHelperDebounce();
ioHelperEdgeDetector();
inputEdgesBoth |= inStatesBothEdges[0] | ((uint32_t)inStatesBothEdges[1]<<8) | ((uint32_t)inStatesBothEdges[2] << 16) | ((uint32_t)inStatesBothEdges[3]<<24);
inputEdgesFalling |= inStatesFallingEdge[0] | ((uint32_t)inStatesFallingEdge[1]<<8) | ((uint32_t)inStatesFallingEdge[2] << 16) | ((uint32_t)inStatesFallingEdge[3]<<24);
inputEdgesRising |= inStatesRisingEdge[0] | ((uint32_t)inStatesRisingEdge[1]<<8) | ((uint32_t)inStatesRisingEdge[2] << 16) | ((uint32_t)inStatesRisingEdge[3]<<24);
modbusGet();
// Toggle all outs which are set to blinking
if(millis() - timer_blink_outs > 500){
ioHelperBlinkOuts();
timer_blink_outs = millis();
}
ioHelperSetOuts();
}
}
ISR(TIMER2_COMPA_vect) { //this ISR is called 9765.625 times per second
modbusTickTimer();
}