4 Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
6 This file is part of simavr.
8 simavr is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 simavr is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with simavr. If not, see <http://www.gnu.org/licenses/>.
31 #include <GLUT/glut.h>
38 #include "avr_ioport.h"
42 #include "sim_vcd_file.h"
45 #include "thermistor.h"
48 #define __AVR_ATmega644__
49 #include "marlin/pins.h"
52 #define THERMISTORHEATER_0 5
53 #include "marlin/thermistortables.h"
55 thermistor_t therm_hotend;
56 thermistor_t therm_hotbed;
59 int do_button_press = 0;
62 uint8_t pin_state = 0; // current port B
68 * called when the AVR change any of the pins on port B
69 * so lets update our buffer
71 void pin_changed_hook(struct avr_irq_t * irq, uint32_t value, void * param)
73 // pin_state = (pin_state & ~(1 << irq->irq)) | (value << irq->irq);
76 void displayCB(void) /* function called whenever redisplay needed */
78 // OpenGL rendering goes here...
79 glClear(GL_COLOR_BUFFER_BIT);
81 // Set up modelview matrix
82 glMatrixMode(GL_MODELVIEW); // Select modelview matrix
83 glLoadIdentity(); // Start with an identity matrix
85 //float grid = pixsize;
86 //float size = grid * 0.8;
91 for (int di = 0; di < 8; di++) {
92 char on = (pin_state & (1 << di)) != 0;
94 float x = (di) * grid;
95 float y = 0; //(si * grid * 8) + (di * grid);
96 glVertex2f(x + size, y + size);
97 glVertex2f(x, y + size);
99 glVertex2f(x + size, y);
105 //glFlush(); /* Complete any pending operations */
108 void keyCB(unsigned char key, int x, int y) /* called on key press */
112 //static uint8_t buf[64];
119 do_button_press++; // pass the message to the AVR thread
122 printf("Starting VCD trace\n");
123 avr_vcd_start(&vcd_file);
126 printf("Stopping VCD trace\n");
127 avr_vcd_stop(&vcd_file);
132 // gl timer. if the pin have changed states, refresh display
135 //static uint8_t oldstate = 0xff;
137 glutTimerFunc(1000/64, timerCB, 0);
139 if (oldstate != pin_state) {
140 oldstate = pin_state;
146 static void * avr_run_thread(void * oaram)
148 // int b_press = do_button_press;
151 int state = avr_run(avr);
152 if ( state == cpu_Done || state == cpu_Crashed)
159 char avr_flash_path[1024];
160 int avr_flash_fd = 0;
162 // avr special flash initalization
163 // here: open and map a file to enable a persistent storage for the flash memory
164 void avr_special_init( avr_t * avr)
167 avr_flash_fd = open(avr_flash_path, O_RDWR|O_CREAT, 0644);
168 if (avr_flash_fd < 0) {
169 perror(avr_flash_path);
172 // resize and map the file the file
173 (void)ftruncate(avr_flash_fd, avr->flashend + 1);
174 ssize_t r = read(avr_flash_fd, avr->flash, avr->flashend + 1);
175 if (r != avr->flashend + 1) {
176 fprintf(stderr, "unable to load flash memory\n");
177 perror(avr_flash_path);
182 // avr special flash deinitalization
183 // here: cleanup the persistent storage
184 void avr_special_deinit( avr_t* avr)
187 lseek(avr_flash_fd, SEEK_SET, 0);
188 ssize_t r = write(avr_flash_fd, avr->flash, avr->flashend + 1);
189 if (r != avr->flashend + 1) {
190 fprintf(stderr, "unable to load flash memory\n");
191 perror(avr_flash_path);
194 uart_pty_stop(&uart_pty);
197 int main(int argc, char *argv[])
201 for (int i = 1; i < argc; i++)
202 if (!strcmp(argv[i], "-d"))
204 avr = avr_make_mcu_by_name("atmega644");
206 fprintf(stderr, "%s: Error creating the AVR core\n", argv[0]);
209 // snprintf(avr_flash_path, sizeof(avr_flash_path), "%s/%s", pwd, "simduino_flash.bin");
210 strcpy(avr_flash_path, "reprap_flash.bin");
211 // register our own functions
212 avr->special_init = avr_special_init;
213 avr->special_deinit = avr_special_deinit;
215 avr->frequency = 20000000;
216 avr->aref = avr->avcc = avr->vcc = 5 * 1000; // needed for ADC
220 const char * fname = "/opt/reprap/tvrrug/Marlin.base/Marlin/applet/Marlin.elf";
221 elf_read_firmware(fname, &f);
223 printf("firmware %s f=%d mmcu=%s\n", fname, (int)f.frequency, f.mmcu);
224 avr_load_firmware(avr, &f);
228 // snprintf(path, sizeof(path), "%s/%s", pwd, "ATmegaBOOT_168_atmega328.ihex");
229 strcpy(path, "marlin/Marlin.hex");
230 //strcpy(path, "marlin/bootloader-644-20MHz.hex");
231 uint8_t * boot = read_ihex_file(path, &size, &base);
233 fprintf(stderr, "%s: Unable to load %s\n", argv[0], path);
236 printf("Firmware %04x: %d\n", base, size);
237 memcpy(avr->flash + base, boot, size);
240 avr->codeend = avr->flashend;
244 // even if not setup at startup, activate gdb if crashing
245 avr->gdb_port = 1234;
247 printf("AVR is stopped, waiting on gdb on port %d. Use 'target remote :%d' in avr-gdb\n",
248 avr->gdb_port, avr->gdb_port);
249 avr->state = cpu_Stopped;
253 uart_pty_init(avr, &uart_pty);
254 uart_pty_connect(&uart_pty, '0');
256 thermistor_init(avr, &therm_hotend, TEMP_0_PIN,
257 (short*)temptable_5, sizeof(temptable_5) / sizeof(short) / 2, OVERSAMPLENR, 22.5f);
258 thermistor_init(avr, &therm_hotbed, TEMP_BED_PIN,
259 (short*)temptable_5, sizeof(temptable_5) / sizeof(short) / 2, OVERSAMPLENR, 22.0f);
262 * OpenGL init, can be ignored
264 glutInit(&argc, argv); /* initialize GLUT system */
266 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
267 glutInitWindowSize(8 * pixsize, 1 * pixsize); /* width=400pixels height=500pixels */
268 window = glutCreateWindow("Glut"); /* create window */
270 // Set up projection matrix
271 glMatrixMode(GL_PROJECTION); // Select projection matrix
272 glLoadIdentity(); // Start with an identity matrix
273 glOrtho(0, 8 * pixsize, 0, 1 * pixsize, 0, 10);
275 glTranslatef(0, -1 * pixsize, 0);
277 glutDisplayFunc(displayCB); /* set window's display callback */
278 glutKeyboardFunc(keyCB); /* set window's key callback */
279 glutTimerFunc(1000 / 24, timerCB, 0);
281 // the AVR run on it's own thread. it even allows for debugging!
283 pthread_create(&run, NULL, avr_run_thread, NULL);