examples: New board_usb
[simavr] / examples / board_usb / simusb.c
1 /* vim: set sts=4:sw=4:ts=4:noexpandtab
2         simusb.c
3
4         Copyright 2012 Torbjorn Tyridal <ttyridal@gmail.com>
5
6         This file is part of simavr.
7
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.
12
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.
17
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/>.
20  */
21
22 #include <sys/mman.h>
23 #include <unistd.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <libgen.h>
30
31 #include <pthread.h>
32
33 #include "sim_avr.h"
34 #include "avr_ioport.h"
35 #include "sim_elf.h"
36 #include "sim_hex.h"
37 #include "sim_gdb.h"
38 #include "vhci_usb.h"
39 #include "sim_vcd_file.h"
40
41 struct vhci_usb_t vhci_usb;
42 avr_t * avr = NULL;
43 avr_vcd_t vcd_file;
44
45
46
47 char avr_flash_path[1024];
48 int avr_flash_fd = 0;
49
50 // avr special flash initalization
51 // here: open and map a file to enable a persistent storage for the flash memory
52 void avr_special_init( avr_t* avr)
53 {
54         //puts(" --=== INIT CALLED ===--");
55         // release flash memory if allocated
56         if(avr->flash) free(avr->flash);
57         // open the file
58         avr_flash_fd = open(avr_flash_path, O_RDWR|O_CREAT, 0644);
59         if (avr_flash_fd < 0) {
60                 perror(avr_flash_path);
61                 exit(1);
62         }
63         // resize and map the file the file
64         (void)ftruncate(avr_flash_fd, avr->flashend + 1);
65         avr->flash = (uint8_t*)mmap(NULL, avr->flashend + 1, // 32k is multiple of 4096
66                                                         PROT_READ|PROT_WRITE, MAP_SHARED, avr_flash_fd, 0);
67         if (!avr->flash) {
68                 fprintf(stderr, "unable to map memory\n");
69                 perror(avr_flash_path);
70                 exit(1);
71         }
72 }
73
74 // avr special flash deinitalization
75 // here: cleanup the persistent storage
76 void avr_special_deinit( avr_t* avr)
77 {
78         //puts(" --=== DEINIT CALLED ===--");
79         // unmap and close the file
80         munmap( avr->flash, avr->flashend + 1);
81         close( avr_flash_fd);
82         // signal that cleanup is done
83         avr->flash = NULL;
84 }
85
86 int main(int argc, char *argv[])
87 {
88         elf_firmware_t f;
89         const char * pwd = dirname(argv[0]);
90
91         avr = avr_make_mcu_by_name("at90usb162");
92         if (!avr) {
93                 fprintf(stderr, "%s: Error creating the AVR core\n", argv[0]);
94                 exit(1);
95         }
96         strcpy(avr_flash_path,  "simusb_flash.bin");
97         // register our own functions
98         avr->special_init = avr_special_init;
99         avr->special_deinit = avr_special_deinit;
100         //avr->reset = NULL;
101         avr_init(avr);
102         avr->frequency = 8000000;
103
104         // this trick creates a file that contains /and keep/ the flash
105         // in the same state as it was before. This allow the bootloader
106         // app to be kept, and re-run if the bootloader doesn't get a
107         // new one
108         {
109                 char path[1024];
110                 uint32_t base, size;
111                 snprintf(path, sizeof(path), "%s/../%s", pwd, "at90usb162_cdc_loopback.hex");
112
113                 uint8_t * boot = read_ihex_file(path, &size, &base);
114                 if (!boot) {
115                         fprintf(stderr, "%s: Unable to load %s\n", argv[0], path);
116                         exit(1);
117                 }
118                 printf("Booloader %04x: %d\n", base, size);
119                 memcpy(avr->flash + base, boot, size);
120                 free(boot);
121                 avr->pc = base;
122                 avr->codeend = avr->flashend;
123         }
124
125         // even if not setup at startup, activate gdb if crashing
126         avr->gdb_port = 1234;
127         if (0) {
128                 //avr->state = cpu_Stopped;
129                 avr_gdb_init(avr);
130         }
131
132         vhci_usb_init(avr, &vhci_usb);
133         vhci_usb_connect(&vhci_usb, '0');
134
135
136         while (1) {
137                 avr_run(avr);
138         }
139 }