UDR register always reads 0xFF - embedded

I have an ATTiny that is supposed to receive commands over UART. I have a simple display of eight LEDs that should show the contents of the most recent byte received. I am using an interrupt to read data as it is received. No matter what data I send UDR always reads 0xFF in the interrupt. I know the interrupt is being triggered since the display changes from 0x00 to 0xFF, but it never displays the value I sent over the serial bus.
This is how I enable UART.
UBRRH = UBRRH_VALUE;
UBRRL = UBRRL_VALUE;
#if USE_2X
UCSRA |= (1U << U2X);
#else
UCSRA &= ~(1U << U2X);
#endif
// Enable receiver and interrupt
UCSRB = (1U << RXEN) | (1U << RXCIE);
// No parity, 8 Data Bits, 1 Stop Bit
UCSRC = (1U << UCSZ1) | (1U << UCSZ0);
This is the code in the interrupt. I have tested display() and it functions correctly on its own thus implying message is always 0xFF.
ISR(USART_RXC_vect) {
uint8_t message = UDR;
display(message);
}
I am confident that my computer is sending the correct information, but I have only tested it with a pseudo-terminal to print out the sent bytes. I intend to snoop the hardware connection with an oscilloscope, but I don't believe that is the issue. Is there something that is causing UDR to always read as 0xFF?
Edit:
I have snooped the connection with an oscilloscope and have verified that the computer is sending the correct data, at the correct rate. However, the ATTiny is not operating at the correct baud rate. At 2400 baud pulses should be about 400 microseconds long, however the microcontroller is producing pulses over 3 milliseconds long. This explains why it would always read 0xFF, the computer would send nearly the entire byte when the controller thought it was receiving the start bit, when the controller tried to read the remaining data the lines would be undriven, resulting in it reading all ones. I still don't know why this is the case as I believe I am properly setting the baud rate on the controller.
Edit:
The issue has been resolved. By default the clock prescaler is set to 8, so the device was only operating at 1MHz, not 8MHz. Setting the clock prescaler to 1 solved the problem.

There can be several problems with uart communication. First check some things:
Is controller configured with the right clock?
Internal/External
Is F_CPU defined for <util/setbaud.h>?
Is BAUD defined for <util/setbaud.h>?
Are you using a controller like ATmega16 that has special register access?
If you are using an external clock (that should not be devided) is CKDIV8 disabled in FUSES or in special registers at some controllers?
Is:
Baudrate,
Paritybit,
Stopbit
setup corret on Transmitter and Receiver
Debug:
If you are using a PC for communication, create a loopback at the UART adapter and check with a terminal (TeraTerm, Putty, ...) if the messages you send are received correctly.
You also can enable the TX controller and check if loopback is working on your uC.
If it is possible try to write the received data to some leds to check if some date is received
Is GND betweend receiver and transmitter connected?
Are the voltage levels between transmitter and receiver the same?
Do transmitter and receiver have its own source? (Then do not connect VCC!)
Check if the clock on the controller is correct (switch on an led with _delay_ms() function every second)
Example Program
#define F_CPU 12000000UL
#define BAUD 9600UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/setbaud.h>
ISR(USART_RXC_vect)
{
volatile unsigned char message = UDR;
// If it is possible try to write the received data to
// LEDs (if there are some at your board)
display(message);
}
int main()
{
// To allow changes to clock prescaler it is necessary to set the
// CCP register (Datasheet page 23)!
CCP = 0xD8;
// RESET the clock prescaler from /8 to /1 !!!!
// Or it is necessary to divide F_CPU through the CLK_PRESCALER
CLKPSR = 0x00;
UBRRH = UBRRH_VALUE;
UBRRL = UBRRL_VALUE;
#if USE_2X
UCSRA |= (1<<U2X);
#else
UCSRA &= ~(1<<U2X);
#endif
// Enable receiver and interrupt
UCSRB = (1U << RXEN) | (1U << RXCIE);
// No parity, 8 Data Bits, 1 Stop Bit
// Not necessary! Mostly ATmega controller
// have 8 bit mode initialized at startup
//UCSRC = (1U << UCSZ1) | (1U << UCSZ0);
// If you are using ATmega8/16 it is necessary to do some
// special things to write to the UBRRH and UCSRC register!
// See ATmega16 datasheet at page 162
// Do not forget to enable interrupts globally!
sei();
while(1);
}
Please explain what the display() function is doing...

Related

TM4321GH6PM - why is GPIODATA register initializing itself and how to read and write to it properly?

Context: I am following a Embedded Systems course that uses the TM4C321GHP6M microcontroller. The IDE being used is the uvision ide by keil. The purpose of the program I am running is to turn on an on-board LED using PF2 and when Switch 1, connected via PF4, is pressed the led will blink. Once switch 1 is released it LED will go back to just being ON.
// BranchingFunctionsDelays.c Lab 6
// Runs on LM4F120/TM4C123
// Use simple programming structures in C to
// toggle an LED while a button is pressed and
// turn the LED on when the button is released.
// This lab will use the hardware already built into the LaunchPad.
// Daniel Valvano, Jonathan Valvano
// January 15, 2016
// built-in connection: PF0 connected to negative logic momentary switch, SW2
// built-in connection: PF1 connected to red LED
// built-in connection: PF2 connected to blue LED
// built-in connection: PF3 connected to green LED
// built-in connection: PF4 connected to negative logic momentary switch, SW1
#include "TExaS.h"
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
#define GPIO_PORTF_DIR_R (*((volatile unsigned long *)0x40025400))
#define GPIO_PORTF_AFSEL_R (*((volatile unsigned long *)0x40025420))
#define GPIO_PORTF_PUR_R (*((volatile unsigned long *)0x40025510))
#define GPIO_PORTF_DEN_R (*((volatile unsigned long *)0x4002551C))
#define GPIO_PORTF_AMSEL_R (*((volatile unsigned long *)0x40025528))
#define GPIO_PORTF_PCTL_R (*((volatile unsigned long *)0x4002552C))
#define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108))
#define SYSCTL_RCGC2_GPIOF 0x00000020 // port F Clock Gating Control
// basic functions defined at end of startup.s
void DisableInterrupts(void); // Disable interrupts
void EnableInterrupts(void); // Enable interrupts
void Delay100ms(unsigned long time);
void init(void);
int main(void){
TExaS_Init(SW_PIN_PF4, LED_PIN_PF2); // activate grader and set system clock to 80 MHz
init();// initialization goes here
EnableInterrupts(); // enable interrupts for the grader
while(1){
unsigned long in;
Delay100ms(1);
in = GPIO_PORTF_DATA_R & 0x10; //read switch
if(in == 0x00){//if PF4 == 0 (switch is pressed)
GPIO_PORTF_DATA_R ^= 0x04; //toggle PF2
}
else{//if PF4 == 1 (switch not pressed)
GPIO_PORTF_DATA_R = 0x04; //set PF2 so LED is ON
}
}
}
void init(void){
SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF; //turn on clock for Port F
Delay100ms(1);
GPIO_PORTF_AMSEL_R = 0x00; //clear PF4 and PF2 bits in port F AMSEL to disable analog
GPIO_PORTF_PCTL_R = 0x00; //clear PF4 and PF2 bit fields in Portf PCTL to config as GPIO
GPIO_PORTF_DIR_R = 0x04; //Set port F dir reg so PF4 is in and PF2 is out
GPIO_PORTF_AFSEL_R = 0x00; //clear PF4 and PF2 bits in port F AFSEL to disable alt func
GPIO_PORTF_DEN_R = 0x14; //set PF4 and PF2 bits in Port F DEN to enable digital
GPIO_PORTF_PUR_R = 0x10; //set PF4 bit in Port F PUR to activate internal pullup
GPIO_PORTF_DATA_R = 0x04; //set PF2 bit in Port F DATA so the LED is init on
PF2 = 0x20;
}
void Delay100ms(unsigned long time){
unsigned long i = 1333333;
while(time > 0){
while(i > 0){
i--;
}
time--;
}
}
For some reason once the program goes to the init() function and steps over SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF; and then Delay100ms(1); the register GPIO_PORTF_DATA_R is initialized with value 0x011. I am not sure what is causing this. Additionally when I attempt to set GPIO_PORTF_DATA_R = 0x04 it then holds the value 0x15? This behavior is very strange and after reading through the data sheet I can see that GPIODATA is read and written to in a unconventional way. For reference please see pages 662 and 654. Would anyone be able to explain this behavior and how I could properly read and write to this register?
This line:
SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF; //turn on clock for Port F
enables the GPIOF clock. When the clock for a peripheral is not running its registers cannot be read or written. So in the debugger you do not see the register value until after the clock is enabled.
Although the reset state of GPIODATA is documented as 0x00000000, that is only true for output the default state of GPIODIR sets every GPIO pin to an input. So 0x11 simply reflects the input state of that port, and PF0 and PF4 happen to be in the logic-high state.
You would need to consult the board schematic to determine what is connected to those pins and why they might be in the high state, but you have already mentioned that PF4 is connected to SW1, and the code sets that pin as an input with internal pull-up. I am guessing that this is a Tiva LaunchPad board having:
Pressing the SW1 push-button will pull the pin low, and the PF4 pit will become zero. The internal pull-up resistor is enabled by default for PF4, so it is not floating even though you have not yet configured it at that point. PF0 GPIOPUR default is floating (per table 10-8), so unless it is configured explicitly to pull-up, its state is indeterminate when connected as on the LaunchPad to SW2.
With respect to perceived "unconventional" behaviour, all peripheral registers on any MCU behave as defined by their manufacturer documentation according to the hardware design. Hardware registers are not RAM (even when memory-mapped) and need not behave like RAM. In particular, unlike RAM, they may have deterministic reset state, and be either read-write, read-only, or write-only. Writing a bit need not modify that bit, registers may change value independently of reads or writes by code.

SYS_TICK handler function is not getting called after enabling flags in SysTick Control and Status Register

I'm using STM32F407G-DISC1 board, SYS_TICK handler is not getting called after enabling flags in SysTick Control and Status Register which is at 0xE000E010 memory mapped location. SysTick Reload Value Register value is set to 15999.
void init_systick_timer(uint32_t tick_hz)
{
uint32_t *pSRVR = (uint32_t*)0xE000E014;
uint32_t *pSCSR = (uint32_t*)0xE000E010;
/* calculation of reload value */
uint32_t count_value = (SYSTICK_TIM_CLK/tick_hz)-1;
//Clear the value of SVR
*pSRVR &= ~(0x00FFFFFFFF);
//load the value in to SVR
*pSRVR |= count_value;
//do some settings
*pSCSR |= ( 1 << 1); //Enables SysTick exception request:
*pSCSR |= ( 1 << 2); //Indicates the clock source, processor clock source
//enable the systick
*pSCSR |= ( 1 << 0); //enables the counter
}
void SysTick_Handler(void)
{
}
I would rather recomment to do not reinvent the wheel and use standard STM provided CMSIS headers.
Your way of defining the registers is incorrect. It will not work correctly if decide to read theis values back. Compiler will simple optimize the reads from the memory out. They have to be volatile.
But abstracting from that you need to enable the interrupt in the NVIC controller. Without that the systick timer will only set the pending flag without invoking the handler.

Erasing a flash on TIVA TM4C123 Microcontroller

I have been trying to understand the following code which is writing to micro controller flash. The Microcontroller is TIVA ARM Cortex M4. I have read the Internal Memory Chapter 8 of Tiva™ TM4C123GH6PM Microcontroller Data sheet. At high level I understand Flash Memory Address (FMA), Flash Memory Data (FMD), and Flash Memory Control (FMC) and Boot Configuration (BOOTCFG).
Below are definitions for some of the variable used in the function.
#define FLASH_FMA_R (*((volatile uint32_t *)0x400FD000))
#define FLASH_FMA_OFFSET_MAX 0x0003FFFF // Address Offset max
#define FLASH_FMD_R (*((volatile uint32_t *)0x400FD004))
#define FLASH_FMC_R (*((volatile uint32_t *)0x400FD008))
#define FLASH_FMC_WRKEY 0xA4420000 // FLASH write key (KEY bit of FLASH_BOOTCFG_R set)
#define FLASH_FMC_WRKEY2 0x71D50000 // FLASH write key (KEY bit of FLASH_BOOTCFG_R cleared)
#define FLASH_FMC_MERASE 0x00000004 // Mass Erase Flash Memory
#define FLASH_FMC_ERASE 0x00000002 // Erase a Page of Flash Memory
#define FLASH_FMC_WRITE 0x00000001 // Write a Word into Flash Memory
#define FLASH_FMC2_R (*((volatile uint32_t *)0x400FD020))
#define FLASH_FMC2_WRBUF 0x00000001 // Buffered Flash Memory Write
#define FLASH_FWBN_R (*((volatile uint32_t *)0x400FD100))
#define FLASH_BOOTCFG_R (*((volatile uint32_t *)0x400FE1D0))
#define FLASH_BOOTCFG_KEY 0x00000010 // KEY Select
This function is used to erase a section of the flash. The function is called from a start address to and end address. I have not fully comprehended how this code works.
//------------Flash_Erase------------
// Erase 1 KB block of flash.
// Input: addr 1-KB aligned flash memory address to erase
// Output: 'NOERROR' if successful, 'ERROR' if fail (defined in FlashProgram.h)
// Note: disables interrupts while erasing
int Flash_Erase(uint32_t addr){
uint32_t flashkey;
if(EraseAddrValid(addr)){
DisableInterrupts(); // may be optional step
// wait for hardware idle
while(FLASH_FMC_R&(FLASH_FMC_WRITE|FLASH_FMC_ERASE|FLASH_FMC_MERASE)){
// to do later: return ERROR if this takes too long
// remember to re-enable interrupts
};
FLASH_FMA_R = addr;
if(FLASH_BOOTCFG_R&FLASH_BOOTCFG_KEY){ // by default, the key is 0xA442
flashkey = FLASH_FMC_WRKEY;
} else{ // otherwise, the key is 0x71D5
flashkey = FLASH_FMC_WRKEY2;
}
FLASH_FMC_R = (flashkey|FLASH_FMC_ERASE); // start erasing 1 KB block
while(FLASH_FMC_R&FLASH_FMC_ERASE){
// to do later: return ERROR if this takes too long
// remember to re-enable interrupts
}; // wait for completion (~3 to 4 usec)
EnableInterrupts();
return NOERROR;
}
return ERROR;
}
Questions: How does the function exit out of the two while loops? How are variables FLASH_FMC_WRITE, FLASH_FMC_ERASE, and FLASH_FMC_MERASE changed? Can '0' be written as part of the erase process?
FLASH_FMC_WRITE, FLASH_FMC_ERASE, and FLASH_FMC_MERASE are individual bits in the FLASH_FMC_R register value (a bitfield). Look in the part's reference manual (or maybe datasheet) at the description of the FLASH_FMC_R register and you will find the description of these bits and more.
The while loops repeatedly read the FLASH_FMC_R register value and exit when the specified bits are set. The flash memory controller sets these bits when it's appropriate (read the reference manual).
Erasing flash means setting all bits to 1 (all bytes to 0xFF). Writing flash means setting select bits to 0. You cannot change a bit from 0 to 1 with a write.
You need to erase to do that. This is just the way flash works.

stm32L476RG - how to execute the bootloader from firmware

I am working on a NUCLEO-L476RG board, trying to start the bootloader from my firmware code but its not working for me. here is the code that i am trying to execute :
#include "stm32l4xx.h"
#include "stm32l4xx_nucleo.h"
#include "core_cm4.h"
#include "stm32l4xx_hal_uart.h"
GPIO_InitTypeDef GPIO_InitStructure;
UART_HandleTypeDef UartHandle;
UART_InitTypeDef UART_InitStructre;
void BootLoaderInit(uint32_t BootLoaderStatus){
void (*SysMemBootJump)(void) = (void (*)(void)) (*((uint32_t *) 0x1FFF0004));
if(BootLoaderStatus == 1) {
HAL_DeInit(); // shut down running tasks
// Reset the SysTick Timer
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL =0;
__set_PRIMASK(1); // Disable interrupts
__set_MSP((uint32_t*) 0x20001000);
SysMemBootJump();
}
}
int main(void)
{
HAL_Init();
__GPIOC_CLK_ENABLE();
GPIO_InitStructure.Pin = GPIO_PIN_13;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
while (1) {
if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)) {
BootLoaderInit(1);
}
}
return 0;
}
What i hope to get after the execution of the firmware is that i can connect to the board with a UART and send commands/get responses from the bootloader. the commands i am trying to use come from here: USART protocol used in the STM32 bootloader.
I don't see and response from the board after connecting with the UART.
Here are some ideas taken from the answers to this question.
HAL_RCC_DeInit();
This is apparently needed to put the clocks back into the state after reset, as the bootloader expects them to be.
__HAL_REMAPMEMORY_SYSTEMFLASH();
Maps the system bootloader to address 0x00000000
__ASM volatile ("movs r3, #0\nldr r3, [r3, #0]\nMSR msp, r3\n" : : : "r3", "sp");
Set the stack pointer from bootloader ROM. Where does your 0x20001000 come from? If it's an arbitrary value, then the stack can clobber the bootloader's variables.
Then there is this alternate solution:
When I want to jump to the bootloader, I write a byte in one of the
backup register and then issue a soft-reset. Then, when the processor
will restart, at the very beginning of the program, it will read this
register.
Note that you need LSI or LSE clock for accessing the backup registers.
Try to avoid using __set_MSP(), as current implementation of this function does NOT allow you to change MSP if it is also the stack pointer which you currently use (and you most likely are). The reason is that this function marks "sp" as clobbered register, so it will be saved before and restored afterwards.
See here - STM32L073RZ (rev Z) IAP jump to bootloader (system memory)
Find your bootloader start address from the reference manual.
Then use the following code.
Make sure you have cleaned and disabled the interrupts before do so.
/* Jump to different address */
JumpAddress = *(__IO uint32_t*) (BootloaderAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();
Please have a look at Official STM32 AppNote as well.

Cortex M-0: Simple external interrupt

I'm trying to set up an external interrupt on my LPC812 uC. I've made the following code
#include "LPC8xx.h"
#define RLED 7 // red LED
bool pause = false;
void PININT0_IRQHandler(void)
{
pause = !pause;
}
int main(void) {
LPC_GPIO_PORT->DIR0 |= 1<<RLED; // set pin as output
LPC_GPIO_PORT->SET0 = 1<<RLED;
NVIC_EnableIRQ(PININT0_IRQn);
while (1)
{
if(!pause)
{
LPC_GPIO_PORT->CLR0 = 1<<RLED;
}
}
}
But it isn't working. Am I missing something?
I'm not familiar with NXP MCUs.
But at least place break piont inside PININT0_IRQHandler, to understand clearly that interrupt is not generated.
Also it will be nice to clear interrupt flag inside handler.
Some peripherals need interrupt permission in peripheral registers in addition to NVIC setup.
Did you setup input pin somewhere?
Your code only initialize GPIO 7 pin as output.