ATMEGA128 … Changes to code

I’m working with the ATMega128 which is based on the ATMEGA323. I’ve found some items that need to be tweaked to get the demo to run. Here are the changes I had to make. Some of these are already documented but I’m including them here for completeness. Also, I’m using WinAVR. I am running my serial at 115200 baud without issue now. // ———————————————— in .FreeRTOSConfig.h #define configCPU_CLOCK_HZ    ( ( unsigned portLONG ) 16000000 ) in ./serial/serial.c #if defined(__AVR_ATmega128__)   #define UDR            UDR0   #define UCSRB            UCSR0B   #define UCSRC            UCSR0C   #define UBRRL            UBRR0L   #define UBRRH            UBRR0H   #define SIG_UART_RECV        SIG_UART0_RECV   #define SIG_UART_DATA        SIG_UART0_DATA #endif /* Calculate the baud rate register value from the equation in the data sheet. */ ulBaudRateCounter = ( (configCPU_CLOCK_HZ + (ulWantedBaud * 8)) / ( serBAUD_DIV_CONSTANT * ulWantedBaud ) – ( unsigned portLONG ) 1 ); //Note: this method of calculating baud rate setting was required for the demo to work for me. I picked it up from Pascal Stang //—————————————————– Hope this helps others. Jay

ATMEGA128 … Changes to code

Thanks – I appreciate you taking the time to provide the information. Is the baud rate calculation specific to the Mega128 class of micros, or is it generic so will also work on the 323? Regards.

ATMEGA128 … Changes to code

Richard, it’s generic. I can’t say I’ve tested it on anything other than the 128, but I got it from Pascal Stang’s AVRLib library and he says his code can be used on: #    MCU = at90s8515 #    MCU = atmega163 #    MCU = atmega323 #    MCU = atmega161 #    MCU = atmega128 Jay

ATMEGA128 … Changes to code

Although it may have been obvious to some, it wasn’t immediately obvious to me for the following: #define portTICK_RATE_MS   ( ( portTickType ) 1000 / configTICK_RATE_HZ ) In use it looks like this: vTaskDelay( ( portTickType ) 50 / portTICK_RATE_MS );    // pause 50ms or thereabouts gives you a rounded off (int) number of clock ticks based on the configTICK_RATE_HZ value in the config file. In my case, I wanted to specify the Hz my task would need to run at (i.e. 50Hz, 20Hz). #define motorPIDFrequency  ( ( portTickType ) 50 / configTICK_RATE_HZ  ) // 50hz or 20ms … vTaskDelayUntil( &xLastWakeTime, motorPIDFrequency );        // wait for the next cycle So that instead of thinking in ms for my vTaskDelayUntil, I can use the required Hz. Either way, the system converts to an (int) so there will be some "error" depending on you choice of configTICK_RATE_HZ. You want simple, chose 1000 or 1 tick every 1ms … but per the API, this is excessive for most applications. FWIW, Jay

ATMEGA128 … Changes to code

Wow, I really hosed that last post up … Should have been: #define motorPIDFrequency ( ( portTickType ) configTICK_RATE_HZ / 50 ) // 50hz or 20ms delay … vTaskDelayUntil( &xLastWakeTime, motorPIDFrequency ); // wait for the next cycle Apologies, too bad there are no edits :) Jay

ATMEGA128 … Changes to code

static void prvSetupTimerInterrupt( void ) { unsigned portLONG ulCompareMatch; unsigned portCHAR ucHighByte, ucLowByte;     /* Using 16bit timer 1 to generate the tick.  Correct fuses must be     selected for the configCPU_CLOCK_HZ clock. */     ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;     /* We only have 16 bits so have to scale to get our required tick rate. */     ulCompareMatch /= portCLOCK_PRESCALER;     /* Adjust for correct value. */     ulCompareMatch -= ( unsigned portLONG ) 1;         /* Setup compare match value for compare match A.  Interrupts are disabled     before this is called so we need not worry here. */     ucLowByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff );     ulCompareMatch >>= 8;     ucHighByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff );     #if (defined (__AVR_ATmega128__) || defined  (__AVR_ATmega323__)) #define portCOMPARE_MATCH_A_INTERRUPT_ENABLE    ( ( unsigned portCHAR ) 0x10 )     OCR1AH = ucHighByte;     OCR1AL = ucLowByte;     /* Setup clock source and compare match behaviour. */     ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64;     TCCR1B = ucLowByte;     /* Enable the interrupt – this is okay as interrupt are currently globally     disabled. */     ucLowByte = TIMSK;     ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;     TIMSK2 = ucLowByte; /*#endif(__AVR_ATmegaXXX__)*/ #elif defined (__AVR_AT90CAN128__) #define portCOMPARE_MATCH_A_INTERRUPT_ENABLE    ( ( unsigned portCHAR ) 0x02 )     OCR1AH = ucHighByte;     OCR1AL = ucLowByte;     /* Setup clock source and compare match behaviour. */     ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64;     TCCR1B = ucLowByte;     /* Enable the interrupt – this is okay as interrupt are currently globally     disabled. */     ucLowByte = TIMSK1;     ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;     TIMSK1 = ucLowByte; #else #  if !defined(__COMPILING_AVR_LIBC__) #    warning "device type not defined" #  endif #endif }