Witam,
Możecie spojrzeć na ten kod (poniżej?)
Problem jest taki że co bym nie robił zdarza się w niektórych wsadach że jakaś strona pamięci zostaje zapisana samymi 0xFF. (wgrywam wsad potem sprawdzam programatorem poprawność).
Procesor Atmega32;
4mhz (RC);
UART 9600
Możecie spojrzeć na ten kod (poniżej?)
Problem jest taki że co bym nie robił zdarza się w niektórych wsadach że jakaś strona pamięci zostaje zapisana samymi 0xFF. (wgrywam wsad potem sprawdzam programatorem poprawność).
Procesor Atmega32;
4mhz (RC);
UART 9600
////////////////////////////////////////////////////////////////////////////////
/* Dołączenie bibliotek */
////////////////////////////////////////////////////////////////////////////////
/* biblioteki avr-libc */
#include <stdint.h>
#include <avr/boot.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <util/setbaud.h>
#include "hardef.h"
#include "delay.h"
#include "lcd.h"
////////////////////////////////////////////////////////////////////////////////
/* Definicje stałych programowych i makr */
////////////////////////////////////////////////////////////////////////////////
/* czas przesyłania jednego znaku przez UART [us] */
#define UART_BYTE_TIME ( F_CPU / ( BAUD / ( 1 + 8 + 1 ) ) )
#define UART_BAUD 9600 //prędkość transmisji
#define UART_CONST (F_CPU/(16ul*UART_BAUD)-1)
/* makro zamieniające podany argument na łańcuch znaków */
#define TOSTRING( x ) STRINGIFY( x )
#define STRINGIFY( x ) #x
////////////////////////////////////////////////////////////////////////////////
/* Deklaracje funkcji statycznych */
////////////////////////////////////////////////////////////////////////////////
static void UART_TX_Byte(const uint8_t Data );
static void UART_TX_String_P(const prog_char *String_Ptr );
static uint8_t _UART_RX_Wait(uint16_t Timeout );
/* Makro przeliczające argument w milisekundach na przyjmowaną przez funkcję
* _UART_RX_Wait wielokrotność czasu przesyłania jednego znaku. */
#define UART_RX_Wait( x ) _UART_RX_Wait( ( x * 1000UL ) / UART_BYTE_TIME )
////////////////////////////////////////////////////////////////////////////////
/* Definicje funkcji */
////////////////////////////////////////////////////////////////////////////////
static void __vectors(void )
__attribute__ (( section( ".vectors" ), naked, used ));
static void __vectors(void )
{
/* skok do sekcji .init2 (konieczny ze względu na umieszczanie stałych z
* pamięci programu pomiędzy sekcjami .vectors a .init0, a więc na samym
* początku programu w przypadku wykorzystania opcji -nostartfiles */
asm (
"rjmp __init2" "\n\t"
: : );
}
static void __init2(void )
__attribute__ (( section( ".init2" ), naked, used ));
static void __init2(void )
{
/* inicjalizacja wskaźnika stosu, rejestru z zerem i rejestru flag */
asm volatile (
"out __SP_L__, %A0" "\n\t"
"out __SP_H__, %B0" "\n\t"
"clr __zero_reg__" "\n\t"
"out __SREG__, __zero_reg__" "\n\t"
: : "r"( ( uint16_t )( RAMEND ) ) );
}
#ifdef WDIF
static void __init3(void )
__attribute__ (( section( ".init3" ), naked, used ));
static void __init3(void )
{
/* wyłączenie watchdoga (w tych mikrokontrolerach, w których watchdog
* ma możliwość generowania przerwania pozostaje on też aktywny po
* resecie) */
MCUSR = 0;
_WD_CONTROL_REG = 1 << _WD_CHANGE_BIT | 1 << WDE;
_WD_CONTROL_REG = 0;
}
#endif
static void __init9(void )
__attribute__ (( section( ".init9" ), naked, used ));
static void __init9(void )
{
/* skok do funkcji main */
asm (
"rjmp main" "\n\t"
: : );
}
int main(void )
__attribute__ (( noreturn ));
int main(void )
{
//guzik
DDRD&=~(1<<3);
PORTD|=(1<<3);
//zasilanie
DDRB |= 1<<1;
PORTB &= ~(1<<1);
if ( (((PIND>>3)&0x01)==1)){
//jesli nie zostal nacisniety drugi guzik to idziemy do programu
/* skok do właściwego programu */
#ifdef __AVR_HAVE_JMP_CALL__
asm volatile (
"jmp 0" "\n\t"
: : );
#else
asm volatile (
"clr r30" "\n\t"
"clr r31" "\n\t"
"ijmp" "\n\t"
: : );
#endif
}else{
DDRB |= 1<<1;
PORTB |= 1<<1;
}
delayms8(10);
LCDinit();
LCDcls();
LCDstr("Update SW");
/* konfiguracja i włączenie interfejsu UART */
UBRRH = (unsigned char)((UART_CONST>>8));
UBRRL = (unsigned char)(UART_CONST);
UCSRA=0;
//wlanczamy odbiornik i nadajnik
//ustawiamy ramke 8n1
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
UCSRB = (1<<RXEN)|(1<<TXEN);
/* deklaracja zmiennych */
uint8_t Retries_Left, Received_Char;
uint8_t msb,lsb,upgrade,CRCodb,typodp;
uint16_t CRC;
/* wysyłanie znaku '?' do odebrania znaku 'u' lub upłynięcia czasu
* oczekiwania */
for ( Retries_Left = BOOT_WAIT * 10; Retries_Left > 0;
--Retries_Left )
{
if ( ( Received_Char = UART_RX_Wait( 100 ) ) == 'u' )
break;
UART_TX_Byte( '?' );
}
if ( Received_Char == 'u' )
{
Retries_Left = 10;
while ( 1 )
{
/* odebranie znaku */
Received_Char = UART_RX_Wait( 1500 );
if ( Received_Char == 'w' )
{
UART_TX_Byte( '&' );
msb=UART_RX_Wait( 1000 );
lsb=UART_RX_Wait( 1000 );
eeprom_write_byte(20,msb);
eeprom_write_byte(21,lsb);
typodp=0;
/* odczekanie do zakończenia operacji na pamięci EEPROM
* i Flash */
eeprom_busy_wait();
boot_spm_busy_wait();
/* kasowanie całej pamięci programu */
for ( uint32_t Page_Address = 0; Page_Address < BLS_START;
Page_Address += SPM_PAGESIZE )
{
/* skasowanie strony pamięci */
boot_page_erase( Page_Address );
boot_spm_busy_wait();
}
/* programowanie pamięci programu */
for ( uint32_t Page_Address = 0; Page_Address < BLS_START;
Page_Address += SPM_PAGESIZE )
{
/* wysłanie znaku '+' */
if(typodp==0){
UART_TX_Byte( '+' );
}else{
UART_TX_Byte( '^' );
}
/* jeśli odebrano zero lub upłynął czas oczekiwania na
* odpowiedź, to zakończenie pracy bootloadera */
if ( !UART_RX_Wait( 500 ) )
break;
/* zapełnienie bufora strony */
CRC=0;
for ( uint16_t Byte_Address = 0;
Byte_Address < SPM_PAGESIZE; Byte_Address += 2 )
{
/* przygotowanie instrukcji */
msb=UART_RX_Wait( 300 );
CRC+=msb;
uint16_t Instruction = ( uint16_t )msb;
msb=UART_RX_Wait( 300 );
CRC+=msb;
Instruction += msb<< 8;
/* zapisanie instrukcji do bufora */
boot_page_fill( Byte_Address, Instruction );
}
if ( CRCodb=UART_RX_Wait( 1000 ) ){
if(CRCodb==(CRC&0x00ff)){ //jesli odebralismy sume kontrolną i sie zgadza
/* zapisanie strony pamięci */
boot_page_write( Page_Address );
boot_spm_busy_wait();
typodp=0;
}else{
Page_Address -= SPM_PAGESIZE; //odejmujemy
typodp=1;
}
}
}
/* odblokowanie sekcji Read-While-Write */
boot_rww_enable();
/* zakończenie pracy bootloadera */
break;
}
else if ( Received_Char == 'q' || !Retries_Left-- )
{
/* jeśli odebrano znak 'q' lub upłynął czas oczekiwania na
* odpowiedź, to zakończenie pracy bootloadera */
break;
}
}
}
/* wyłączenie interfejsu UART (dzieje się to dopiero po zakończeniu
* wysyłania) i odczekanie do końca ewentualnej transmisji */
UCSRB = 0;
_delay_us( UART_BYTE_TIME );
DDRB |= 1<<1;
PORTB &= ~(1<<1);
/* nieskończona pętla (konieczna, by kompilator nie wygenerował
* niepotrzebnego kodu) */
while ( 1 )
{}
}
static void UART_TX_Byte(const uint8_t Data ){
UCSRB &= ~(1 << RXEN);
while ( !( UCSRA & 1 << UDRE ) )
{}
UDR = Data;
_delay_us( UART_BYTE_TIME );
UCSRB |= (1 << RXEN);
}
static void UART_TX_String_P(const prog_char *String_Ptr ){
uint8_t Single_Char;
while ( ( Single_Char = pgm_read_byte( String_Ptr++ ) ) )
UART_TX_Byte( Single_Char );
}
static uint8_t _UART_RX_Wait(uint16_t Timeout ){
do
{
if ( UCSRA & 1 << RXC )
return UDR;
_delay_us( UART_BYTE_TIME );
} while ( Timeout-- );
return 0;
}
