Using ATtiny104 + GCC.
I have the following UART functions:
void UARTInit(void) { power_usart_enable(); UBRRH = (uint8_t)(BAUDRATE >> 8); UBRRL = (uint8_t)(BAUDRATE & 0x00FF); UCSRA |= _BV(U2X); // Double speed UCSRB = _BV(RXEN) | _BV(TXEN); // Enable RX & TX UCSRC = _BV(UCSZ1) | _BV(UCSZ0); // Character size 8-bit } void UARTSendByte(uint8_t byte) { while (!(UCSRA & _BV(UDRE))); UDR = byte; } uint8_t UARTGetByte(void) { while (!(UCSRA & _BV(RXC))); return UDR; } void UARTSendArray(uint8_t arr[], uint8_t size) { for (uint8_t i = 0; i < size; i++) UARTSendByte(arr[i]); }
I'm using them in the following function that communicates with a DFPlayer module (does not matter if you are not familiar with it):
int16_t DFPlayerSendCommand(uint8_t command, uint8_t parameter) { int16_t returnVal = -1; uint8_t tempCommand[10] = {0x7E ,0xFF ,0x06 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xEF}; int16_t checksum; tempCommand[3] = command; if (parameter < 256) tempCommand[6] = parameter; else { tempCommand[5] = (uint8_t)(parameter >> 8); tempCommand[6] = (uint8_t)parameter; } checksum = _DFPlayerChecksum(tempCommand); tempCommand[7] = (uint8_t)(checksum >> 8); tempCommand[8] = (uint8_t)checksum; UARTSendArray(tempCommand, 10); // Wait for feedback if ((command == DFPLAYER_GET_VOLUME) || (command == DFPLAYER_GET_EQ ) || (command == DFPLAYER_GET_TF_FILES )) { uint8_t tempMessage[10]; int16_t messageChecksum; for (uint8_t i = 0; i < 10; i++) tempMessage[i] = UARTGetByte; messageChecksum = (tempMessage[7] << 8) | (tempMessage[8]); // Glue --> int16_t // MSG OK? if ((tempMessage[0] == DFPLAYER_RX_START_BYTE) && (tempMessage[9] == DFPLAYER_RX_END_BYTE) && (messageChecksum == _DFPlayerChecksum(tempMessage))) { return tempMessage[6]; } } return returnVal; }
Here what happens here...
I'm inserting the command (parameter) into the command message, in the specific case I'm testing command = 3 & parameter = 1.
the parameter is inserted as well, followed by the checksum.
The array is sent out using one of the above functions.
If I comment out the rest of the function after
UARTSendArray(tempCommand, 10);
the array is sent out as should (this was verified).
If I don't, then the array will not send correctly and instead the AVR will send an endless stream of the following values: 0xFE, 0xF9, 0x7E. Not in this particular order, and it seems like 0xF9 is the dominant value. By the way 0xF9 is not a part of the checksum values, 0xFE & 0x7E are. The strange thing is that the if condition that appears right after the sent array command should not evaluate as true because those macros all have different values:
#define DFPLAYER_PLAY_FILE 0x03 #define DFPLAYER_GET_VOLUME 0x43 #define DFPLAYER_VOLUME_UP 0x04 #define DFPLAYER_VOLUME_DOWN 0x05 #define DFPLAYER_GET_EQ 0x44 #define DFPLAYER_GET_TF_FILES 0x47
And I have checked this using the simulator and indeed the code is not executed.
Any suggestions for the cause of this strange behavior?