px-fwlib 0.10.0
Cross-platform embedded library and documentation for 8/16/32-bit microcontrollers generated with Doxygen 1.9.2
eeprom.c
1/* =============================================================================
2 ____ ___ ____ ___ _ _ ___ __ __ ___ __ __ TM
3 | _ \ |_ _| / ___| / _ \ | \ | | / _ \ | \/ | |_ _| \ \/ /
4 | |_) | | | | | | | | | | \| | | | | | | |\/| | | | \ /
5 | __/ | | | |___ | |_| | | |\ | | |_| | | | | | | | / \
6 |_| |___| \____| \___/ |_| \_| \___/ |_| |_| |___| /_/\_\
7
8 Copyright (c) 2006-2014 Pieter Conradie <https://piconomix.com>
9
10 License: MIT
11 https://github.com/piconomix/px-fwlib/blob/master/LICENSE.md
12
13============================================================================= */
14
15/**
16 * @ingroup AVR_TUTORIALS
17 * @defgroup AVR_TUT09_EEPROM 09_eeprom
18 *
19 * How to write to and read from EEPROM.
20 *
21 * File(s):
22 * - arch/avr/tutorials/09_eeprom/eeprom.c
23 *
24 * 0xAB is written to EEPROM address 0x000C, read back and reported
25 * over UART at 115200 BAUD, 8 Data Bits, No Parity and 1 Stop Bit.
26 *
27 * @tip_s
28 * [<avr/eeprom.h>](https://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html)
29 * can also be used. It is not neccessary to use an explicit EEPROM address.
30 * The compiler will allocate a unique address if the EEMEM prefix is used.
31 * For example:
32 * @tip_e
33 *
34 * @code{.c}
35 * #include <stdint.h>
36 * #include <avr/eeprom.h>
37 *
38 * EEMEM uint16_t ee_setting;
39 *
40 * int main(void)
41 * {
42 * uint16_t value;
43 *
44 * // Load value from EEPROM
45 * value = eeprom_read_word(&ee_setting);
46 * // Modify value
47 * value += 1;
48 * // Commit new value to EEPROM
49 * eeprom_write_word(&ee_setting, value);
50 * eeprom_busy_wait();
51 * }
52 * @endcode
53 */
54
55#include <stdint.h>
56#include <stdbool.h>
57#include <stdio.h>
58#include <avr/io.h>
59#include <avr/interrupt.h>
60#include <avr/pgmspace.h>
61
62#include "px_board.h"
63
64// Macro to send strings stored in program memory space
65#define PRINTF_P(format, ...) printf_P(PSTR(format), ## __VA_ARGS__)
66// Define baud rate
67#define UART0_BAUD 115200ul
68#define UART0_UBBR_VAL ((F_CPU / (UART0_BAUD * 16)) - 1)
69
70void uart_init(void)
71{
72 // Set baud rate
73 UBRR0 = UART0_UBBR_VAL;
74 // Set frame format to 8 data bits, no parity, 1 stop bit
75 UCSR0C = (0 << USBS0) | (1 << UCSZ01) | (1 << UCSZ00);
76 // Enable receiver and transmitter
77 UCSR0B = (1 << RXEN0) | (1 << TXEN0);
78}
79
80int uart_putchar(char data, FILE *stream)
81{
82 // Recursive function to prepend a carriage return before a line feed
83 if(data == '\n')
84 {
85 uart_putchar('\r', stream);
86 }
87 // Wait until data register is empty
88 while((UCSR0A & (1 << UDRE0)) == 0) {;}
89 // Load transmit register with new data
90 UDR0 = data;
91
92 return 0;
93}
94
95// Declare stream object in data memory (not heap memory)
96FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
97
98uint8_t ee_read_byte(uint16_t adr)
99{
100 // Set address
101 EEAR = adr;
102 // Start read operation
103 EECR |= (1 << EERE);
104 // Return data
105 return EEDR;
106}
107
108void ee_write_byte(uint16_t adr, uint8_t data)
109{
110 uint8_t sreg;
111
112 // Select EEPROM Programming mode: Erase and Write in one operation (Atomic Operation)
113 EECR &= ~((1 << EEPM1) | (1 << EEPM0));
114 // Set address
115 EEAR = adr;
116 // Set data to write
117 EEDR = data;
118 // Save status of global interrupts
119 sreg = SREG;
120 // Disable interrupts
121 cli();
122 // Start write operation
123 EECR |= (1 << EEMPE);
124 EECR |= (1 << EEPE);
125 // Restore status of global interrupts
126 SREG = sreg;
127 // Wait until write operation has finished
128 while(EECR & (1 << EEPE)) {;}
129}
130int main(void)
131{
132 uint8_t data;
133
134 // Initialise board
136 // Initialise UART
137 uart_init();
138 // Direct stdout stream to uart_stream
139 stdout = &uart_stream;
140
141 PRINTF_P("\nEEPROM Tutorial\n");
142
143 // Write a byte to EEPROM
144 ee_write_byte(0x000C, 0xAB);
145 // Read a byte from EEPROM
146 data = ee_read_byte(0x000C);
147
148 PRINTF_P("EEPROM value at adr 0x000C is 0x%02X\n", data);
149
150 // Loop forever
151 while(true) {;}
152}
void px_board_init(void)
Initialise the board hardware.
Definition: px_board.c:168
#define NULL
NULL pointer.
Definition: px_defs.h:49