Esempio n. 1
0
}

void modbus_server__on_valid_frame_received(void) {
    ++valid_frames_received;
}

void modbus_server__on_invalid_frame_received(void) {
    ++invalid_frames_received;
}


/**
 * Handle reading of holding registers.
 */
modbus_exception modbus_server__read_coils(void) {
    buffer__put_u8((PORT_REG(OUT__LEDS__PORT) & (SIGNAL_MASK(OUT__LED1) | SIGNAL_MASK(OUT__LED2) | SIGNAL_MASK(OUT__LED3))) >> OUT__LED1__PIN);
    return MODBUS_EXCEPTION__NONE;
}




/**
 * Handle writing of single coil (output LEDs/relays).
 */
modbus_exception modbus_server__write_single_coil(uint16_t address, uint8_t active) {
    if (address == 0) {
        led1__set(active);
    }
    else if (--address == 0) {
        led2__set(active);
Esempio n. 2
0
void led__toggle(void) {
    PORT_REG(SIGNAL_PORT(LED)) ^= SIGNAL_MASK(LED);
}
__attribute__((__noreturn__)) void main(void)
{

#if (FLASHEND > 0xFFFFUL)
unsigned long flash_address = 0;
#else
unsigned int  flash_address = 0;
#endif
#if SPM_PAGESIZE > 128
unsigned int  x=0, y=0;
#else
unsigned char  x=0, y=0;
#endif
unsigned char high_byte_buffer = 0, low_byte_buffer = 0, packet_resend_required = 0;
unsigned char packet_number = 0, error_counter = 0, memory_full = 0;
unsigned int received_bytes = 0, address_buffer = 0, eeprom_address = 0, crc16 = 0, crc_buffer = 0;

EXTRA_STARTUP_COMMANDS();
ENABLE_LEVEL_PIN();
UART_TIMEOUT_ENABLE();
sget_char(); // Dummy receive used as a 200 ms delay as the UART is not yet enabled.
if( ((PIN_REG(CHECK_LEVEL_PORT) & (1 << CHECK_LEVEL_PIN))) ){ EXTRA_EXIT_COMMANDS(); asm("jmp 0x0000"); }

/* Initialization commands */
// Setup the UART
_UCSRA_ = 0;
// Enable the UART to receive/transmit and enable UART pins
_UCSRB_ = ( (1 << _RXEN_)|(1 << _TXEN_) );
// Set UART to receive and transmit 8 bits per character, 1 stop bit with no parity.
_UCSRC_ = ( USEURSEL | (1 << _UCSZ1_) | (1 << _UCSZ0_) );
// Set baudrate.
_UBRRH_ = BAUDREG/256;
_UBRRL_ = BAUDREG%256;
// Turn on the pull up resistor of the UART rx pin.
DDR_REG(UART_PORT) &= (~(1<<UART_RX_PIN));
PORT_REG(UART_PORT) |= (1<<UART_RX_PIN);
// Make the UART Txd pin an output.
DDR_REG(UART_PORT) |= (1<<UART_TX_PIN);
// Enable the LED indication.
ENABLE_LED();
#if INTIALIZATION_DELAY > 0
sget_char();
#endif
/* MAIN BOOTLOADER LOOP */
while(1)
    {
       // START THE STANDARD 128 BYTE PACKET X MODEM CRC FILE DOWNLOAD
       // I tried to follow the crc X modem protocol as faithfully as i could
       LED_ON();
       flash_address = 0;
       eeprom_address = 0;
       packet_number = 0;
       error_counter = 0;
       received_bytes = 0;
       memory_to_write = 0;
       memory_full = 0;
       UART_TIMEOUT_DISABLE(); //Disable uart receive timeout.
       receive_at_command();
       sput_str("START THE X MODEM TRANSFER\r\n");
       UART_TIMEOUT_ENABLE(); //Enable the UART timeout.

       do{
            sput_char(XMODEM_NCG);
         }while(sget_char() != XMODEM_SOH);

       // DOWNLOAD AND VERIFY ONE PACKET AT A TIME UNTILL THE BUFFER IS FULL. The buffer is equal to SPM_PAGESIZE.
       /*------------------------------------------------------------------------------------------------------*/
       do{
           crc16 = 0;
#if BOOTLOADER_SAVE_CODE_SIZE == 1
           sget_char();
           sget_char();
#elif BOOTLOADER_SAVE_CODE_SIZE == 0
           packet_number++;
           packet_resend_required = 0;
           high_byte_buffer =  sget_char();     //get X modem packet number
           low_byte_buffer  =  sget_char();
           // Examine the packet number.
           if( (high_byte_buffer + low_byte_buffer) != 255 ) { packet_resend_required = (1<<2); }
           if( high_byte_buffer == (packet_number-1) ) { packet_resend_required |= (1<<1); }
           if(high_byte_buffer != packet_number) { packet_resend_required |= (1<<0); }
#endif
           // Now receive the packet data and perform the crc16 check.

           for(x = X_MODEM_PACKET_LENGTH; x > 0; x--)
             {
                x_buffer[received_bytes] = sget_char();
                crc16 = ( crc16 ^ ((unsigned int)x_buffer[received_bytes] << 8) );
                for(y = 8; y > 0; y--)
                  {
                     crc_buffer = crc16 << 1;
                     if(crc16 & 0x8000) { crc_buffer = crc_buffer ^ 0x1021; }
                     crc16 = crc_buffer;
                  }
                received_bytes++;
             }
           high_byte_buffer = sget_char();         //get X modem CRC16
           low_byte_buffer  = sget_char();
#if BOOTLOADER_SAVE_CODE_SIZE == 0
           if( (high_byte_buffer != (crc16 / 256))||(low_byte_buffer != (crc16 % 256)) ){ packet_resend_required |= (1<<3); }
           // Now we must see if the packet was received ok or if not, what went wrong.
           if(packet_resend_required > 0)
            {
               error_counter++;
               packet_number--;  // Packet number is decremented.
               received_bytes -= X_MODEM_PACKET_LENGTH;
               if( packet_resend_required >= (1<<2) )
                {
                   sput_char(XMODEM_NAK);

                 }else if(packet_resend_required >= (1<<1) )
                        {
                           sput_char(XMODEM_ACK);

                        }else{
                               goto XMODEM_FAILED;
                              } // end of "if( packet_resend_required >= (1<<2) )" statement.
#elif BOOTLOADER_SAVE_CODE_SIZE == 1
           if( (high_byte_buffer != (crc16 / 256))||(low_byte_buffer != (crc16 % 256)) )
            {
               goto XMODEM_FAILED;

#endif
            }else{  // "if(packet_resend_required > 0)" statement.
                   if(memory_to_write == 1)
                    {
                       x = 0;
                       while( received_bytes >= SPM_PAGESIZE )
                           {
                              if(flash_address <= (BOOTLOADER_MEM_START-SPM_PAGESIZE) )
                               {
                                  address_buffer = x; // Store the x_buffer position for the verification process.
                                  y=0;
                                  do{
                                       boot_page_fill_safe( y, x_buffer[x] | (x_buffer[x+1] << 8) );
                                       x+=2; //BYTE COUNTER UP TO "received_bytes"
                                       y+=2; //BYTE COUNTER UP TO SPM_PAGESIZE
                                    }while(y < SPM_PAGESIZE);
                                  boot_page_erase_safe(flash_address);      //erase one Flash page
                                  boot_page_write_safe(flash_address);      //write buffer to one Flash page
                                  boot_rww_enable_safe();
                                  y=0;
                                  do{
                                      if( pgm_read_byte(flash_address+y) != x_buffer[address_buffer+y] ){ goto XMODEM_FAILED; }
                                      y++;
                                    }while(y < SPM_PAGESIZE);
                                  flash_address += SPM_PAGESIZE;
                                  received_bytes -= SPM_PAGESIZE;

                               }else{ memory_full = 1; goto XMODEM_FAILED; }
                           }

                    }else if(memory_to_write == 2)
                           {
                             for(x=0; x < X_MODEM_PACKET_LENGTH; x++)
                               {
                                  if(eeprom_address <= E2END)
                                   {
                                      eeprom_write_byte((unsigned char*)eeprom_address, x_buffer[x]);
                                      if(eeprom_read_byte((unsigned char*)eeprom_address) != x_buffer[x]){ goto XMODEM_FAILED; }
                                      eeprom_address++;

                                   }else{ memory_full = 1;  }
                               }
                             received_bytes = 0;
                           }
                   sput_char(XMODEM_ACK);
                   //error_counter =0;
                 }// end of "if(packet_resend_required > 0){...}else{...}" statement

           if(error_counter >= 10){ goto XMODEM_FAILED; }  //Standard X modem max errors is 10, abort update.

         }while(sget_char() != XMODEM_EOT); // End of do{}while loop
/*----------------------------------------------------------------------------------------------------------*/
       // The flash or Eeprom is written so it is time to exit.
       // exit the X modem transfer.
       sput_char(XMODEM_NAK);
       if(sget_char() == XMODEM_EOT)
        {
           sput_char(XMODEM_ACK);
           error_counter = 0;
        }
       else{
             // If the transfer failed send the X modem cancel character 10 times as per X modem specifications.
XMODEM_FAILED:
               y=0;
               do{
                    sput_char(XMODEM_CAN);
                    y++;

                 }while( y<10);
               error_counter = 1;

           }

       _UCSRB_ &= (~ (1 << _RXEN_));
       UART_TIMEOUT_1S();
       sget_char();   //dummy receive. It is used as delay.
       _UCSRB_ |= (1 << _RXEN_);
       if(memory_full)
        {
           sput_str("Error memory full");

        }else if(error_counter)
               {
                  sput_str(error_message);

               }else{
                       sput_str(update_success_message);
                    }
       //(*((void(*)(void))(BOOTLOADER_MEM_START)))();

    } // END of while(1) main loop.


}