Stefan Schuermans commited on 2012-04-04 22:26:27
              Showing 5 changed files, with 271 additions and 53 deletions.
            
| ... | ... | @@ -1,48 +1,16 @@ | 
| 1 | 1 | #include "arp.h" | 
| 2 | 2 | #include "cyc_cnt.h" | 
| 3 | +#include "dhcp.h" | |
| 3 | 4 | #include "eth.h" | 
| 4 | 5 | #include "ip.h" | 
| 5 | -#include "lcd.h" | |
| 6 | 6 | #include "leds.h" | 
| 7 | -#include "switches.h" | |
| 7 | +#include "menu.h" | |
| 8 | 8 | #include "uart.h" | 
| 9 | 9 | #include "udp.h" | 
| 10 | 10 |  | 
| 11 | 11 | unsigned char leds_val = 0x88; | 
| 12 | 12 |  | 
| 13 | -void uint2digits(unsigned int uint, unsigned int cnt, char digits[]) | |
| 14 | -{ | |
| 15 | -  while (cnt > 0) { | |
| 16 | - --cnt; | |
| 17 | - digits[cnt] = '0' + uint % 10; | |
| 18 | - uint /= 10; | |
| 19 | - } | |
| 20 | -} | |
| 21 | - | |
| 22 | -void switches(void) | |
| 23 | -{ | |
| 24 | - char cnt_digits[4]; | |
| 25 | - | |
| 26 | - lcd_chr(1, 0, switches_get_state(sw_0) ? '0' : ' '); | |
| 27 | - lcd_chr(1, 1, switches_get_state(sw_1) ? '1' : ' '); | |
| 28 | - lcd_chr(1, 2, switches_get_state(sw_2) ? '2' : ' '); | |
| 29 | - lcd_chr(1, 3, switches_get_state(sw_3) ? '3' : ' '); | |
| 30 | - lcd_chr(1, 4, switches_get_state(sw_east) ? 'E' : ' '); | |
| 31 | - lcd_chr(1, 5, switches_get_state(sw_north) ? 'N' : ' '); | |
| 32 | - lcd_chr(1, 6, switches_get_state(sw_south) ? 'S' : ' '); | |
| 33 | - lcd_chr(1, 7, switches_get_state(sw_west) ? 'W' : ' '); | |
| 34 | - lcd_chr(1, 8, switches_get_state(sw_center) ? 'C' : ' '); | |
| 35 | - lcd_chr(1, 9, switches_get_state(sw_rot_a) ? 'a' : ' '); | |
| 36 | - lcd_chr(1, 10, switches_get_state(sw_rot_b) ? 'b' : ' '); | |
| 37 | - | |
| 38 | - uint2digits(switches_get_rot_cnt(), 4, cnt_digits); | |
| 39 | - lcd_chr(1, 12, cnt_digits[0]); | |
| 40 | - lcd_chr(1, 13, cnt_digits[1]); | |
| 41 | - lcd_chr(1, 14, cnt_digits[2]); | |
| 42 | - lcd_chr(1, 15, cnt_digits[3]); | |
| 43 | -} | |
| 44 | - | |
| 45 | -void uart(void) | |
| 13 | +void uart_rx_task(void) | |
| 46 | 14 |  { | 
| 47 | 15 | unsigned short chr; | 
| 48 | 16 |  | 
| ... | ... | @@ -53,28 +21,20 @@ void uart(void) | 
| 53 | 21 | } | 
| 54 | 22 | } | 
| 55 | 23 |  | 
| 56 | -void eth_task(void) | |
| 24 | +void eth_rx_task(void) | |
| 57 | 25 |  { | 
| 58 | 26 | void *vptr; | 
| 59 | 27 | unsigned int sz; | 
| 60 | - char digits[2]; | |
| 61 | 28 |  | 
| 62 | 29 | while (eth_rx(&vptr, &sz)) | 
| 63 | 30 | ethernet_recv(vptr, sz); | 
| 64 | - | |
| 65 | - uint2digits(eth_rx_get_cnt(), 2, digits);; | |
| 66 | - lcd_chr(0, 11, digits[0]); | |
| 67 | - lcd_chr(0, 12, digits[1]); | |
| 68 | - uint2digits(eth_tx_get_cnt(), 2, digits);; | |
| 69 | - lcd_chr(0, 14, digits[0]); | |
| 70 | - lcd_chr(0, 15, digits[1]); | |
| 71 | 31 | } | 
| 72 | 32 |  | 
| 73 | 33 | void tasks(void) | 
| 74 | 34 |  { | 
| 75 | - switches(); | |
| 76 | - uart(); | |
| 77 | - eth_task(); | |
| 35 | + uart_rx_task(); | |
| 36 | + eth_rx_task(); | |
| 37 | + menu_task(); | |
| 78 | 38 | } | 
| 79 | 39 |  | 
| 80 | 40 | void leds_tick200(void) | 
| ... | ... | @@ -89,6 +49,7 @@ void tick200(void) | 
| 89 | 49 | arp_tick200(); | 
| 90 | 50 | ip_tick200(); | 
| 91 | 51 | udp_tick200(); | 
| 52 | + dhcp_tick200(); | |
| 92 | 53 | } | 
| 93 | 54 |  | 
| 94 | 55 | int main() | 
| ... | ... | @@ -97,15 +58,13 @@ int main() | 
| 97 | 58 |  | 
| 98 | 59 | leds_set_state(0x01); | 
| 99 | 60 |  | 
| 100 | - eth_mac_init(); | |
| 101 | - eth_rx_init(); | |
| 102 | - eth_tx_init(); | |
| 61 | + menu_init(); | |
| 103 | 62 |  | 
| 104 | 63 | leds_set_state(0x02); | 
| 105 | 64 |  | 
| 106 | - lcd_init(); | |
| 107 | - lcd_str(0, "MIPS I"); | |
| 108 | - lcd_str(1, ""); | |
| 65 | + eth_mac_init(); | |
| 66 | + eth_rx_init(); | |
| 67 | + eth_tx_init(); | |
| 109 | 68 |  | 
| 110 | 69 | leds_set_state(0x04); | 
| 111 | 70 |  | 
| ... | ... | @@ -34,3 +34,39 @@ void memcpy(void *dest, const void *src, unsigned int sz) | 
| 34 | 34 | *dest1++ = *src1++; | 
| 35 | 35 | } | 
| 36 | 36 |  | 
| 37 | +/** | |
| 38 | + * @brief set memory to fixed value | |
| 39 | + * @param[in] dest pointer to destination buffer | |
| 40 | + * @param[in] val fixed value to fill memory with | |
| 41 | + * @param[in] sz size of memory to fill | |
| 42 | + */ | |
| 43 | +void memset(void *dest, int val, unsigned int sz) | |
| 44 | +{ | |
| 45 | + unsigned char val1; | |
| 46 | + unsigned int *dest4; | |
| 47 | + unsigned int val4; | |
| 48 | + unsigned int sz4; | |
| 49 | + unsigned char *dest1; | |
| 50 | + | |
| 51 | + val1 = val; | |
| 52 | + | |
| 53 | + // word aligned memory address -> fast fill | |
| 54 | +  if (((unsigned int)dest & 3) == 0) { | |
| 55 | + dest4 = dest; | |
| 56 | + val4 = val1; | |
| 57 | + val4 |= val4 << 8; | |
| 58 | + val4 |= val4 << 16; | |
| 59 | + sz4 = sz >> 2; | |
| 60 | + for ( ; sz4 > 0; --sz4) | |
| 61 | + *dest4++ = val4; | |
| 62 | + // there might still be a few bytes to fill now | |
| 63 | + dest = dest4; | |
| 64 | + sz &= 3; | |
| 65 | + } | |
| 66 | + | |
| 67 | + // safe and slow fallback: fill byte-wise | |
| 68 | + dest1 = dest; | |
| 69 | + for ( ; sz > 0; --sz) | |
| 70 | + *dest1++ = val1; | |
| 71 | +} | |
| 72 | + | 
| ... | ... | @@ -9,5 +9,13 @@ | 
| 9 | 9 | */ | 
| 10 | 10 | void memcpy(void *dest, const void *src, unsigned int sz); | 
| 11 | 11 |  | 
| 12 | +/** | |
| 13 | + * @brief set memory to fixed value | |
| 14 | + * @param[in] dest pointer to destination buffer | |
| 15 | + * @param[in] val fixed value to fill memory with | |
| 16 | + * @param[in] sz size of memory to fill | |
| 17 | + */ | |
| 18 | +void memset(void *dest, int val, unsigned int sz); | |
| 19 | + | |
| 12 | 20 | #endif // #ifdef MEMCPY_H | 
| 13 | 21 |  | 
| ... | ... | @@ -0,0 +1,204 @@ | 
| 1 | +#include "config.h" | |
| 2 | +#include "eth.h" | |
| 3 | +#include "lcd.h" | |
| 4 | +#include "macros.h" | |
| 5 | +#include "menu.h" | |
| 6 | +#include "switches.h" | |
| 7 | + | |
| 8 | +/// last value of rotary knob | |
| 9 | +static unsigned int menu_cur_rot_val = 0; | |
| 10 | + | |
| 11 | +/// current screen | |
| 12 | +static int menu_cur_screen = 0; | |
| 13 | + | |
| 14 | +/// current content on screen | |
| 15 | +static char menu_cur_content[16]; | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * @brief convert unsigned integer to decimal | |
| 19 | + * @param[in] uint unsigned integer value | |
| 20 | + * @param[in] cnt number of digits | |
| 21 | + * @param[out] digits value as decimal digits | |
| 22 | + */ | |
| 23 | +void menu_uint2dec(unsigned int uint, unsigned int cnt, char digits[]) | |
| 24 | +{ | |
| 25 | +  while (cnt > 0) { | |
| 26 | + --cnt; | |
| 27 | + digits[cnt] = '0' + uint % 10; | |
| 28 | + uint /= 10; | |
| 29 | + } | |
| 30 | +} | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * @brief convert unsigned integer to hexadecimal | |
| 34 | + * @param[in] uint unsigned integer value | |
| 35 | + * @param[in] cnt number of digits | |
| 36 | + * @param[out] digits value as decimal hexadigits | |
| 37 | + */ | |
| 38 | +void menu_uint2hex(unsigned int uint, unsigned int cnt, char digits[]) | |
| 39 | +{ | |
| 40 | + unsigned int val; | |
| 41 | + | |
| 42 | +  while (cnt > 0) { | |
| 43 | + --cnt; | |
| 44 | + val = uint & 15; | |
| 45 | + digits[cnt] = val < 10 ? '0' + val : 'A' - 10 + val; | |
| 46 | + uint >>= 4; | |
| 47 | + } | |
| 48 | +} | |
| 49 | + | |
| 50 | +/** | |
| 51 | + * @brief update screen content | |
| 52 | + * @param[in] str new content to display | |
| 53 | + */ | |
| 54 | +static void menu_update_content(const char *str) | |
| 55 | +{ | |
| 56 | + unsigned int i; | |
| 57 | + | |
| 58 | + // update only characters that changed (LCD is slow) | |
| 59 | +  for (i = 0; str[i] != 0 && i < 16; ++i) { | |
| 60 | +    if (menu_cur_content[i] != str[i]) { | |
| 61 | + menu_cur_content[i] = str[i]; | |
| 62 | + lcd_chr(1, i, str[i]); | |
| 63 | + } | |
| 64 | + } | |
| 65 | + // clear rest of line | |
| 66 | +  for (; i < 16; ++i) { | |
| 67 | +    if (menu_cur_content[i] != ' ') { | |
| 68 | + menu_cur_content[i] = ' '; | |
| 69 | + lcd_chr(1, i, ' '); | |
| 70 | + } | |
| 71 | + } | |
| 72 | +} | |
| 73 | + | |
| 74 | +/// start screen | |
| 75 | +static void menu_screen_start(void) | |
| 76 | +{ | |
| 77 | +  menu_update_content("turn knob..."); | |
| 78 | +} | |
| 79 | + | |
| 80 | +/// switches screen | |
| 81 | +static void menu_screen_switches(void) | |
| 82 | +{ | |
| 83 | + char buf[11]; | |
| 84 | + | |
| 85 | + buf[0] = switches_get_state(sw_0) ? '0' : ' '; | |
| 86 | + buf[1] = switches_get_state(sw_1) ? '1' : ' '; | |
| 87 | + buf[2] = switches_get_state(sw_2) ? '2' : ' '; | |
| 88 | + buf[3] = switches_get_state(sw_3) ? '3' : ' '; | |
| 89 | + buf[4] = switches_get_state(sw_east) ? 'E' : ' '; | |
| 90 | + buf[5] = switches_get_state(sw_north) ? 'N' : ' '; | |
| 91 | + buf[6] = switches_get_state(sw_south) ? 'S' : ' '; | |
| 92 | + buf[7] = switches_get_state(sw_west) ? 'W' : ' '; | |
| 93 | + buf[8] = switches_get_state(sw_center) ? 'C' : ' '; | |
| 94 | + buf[9] = switches_get_state(sw_rot_a) ? 'a' : ' '; | |
| 95 | + buf[10] = switches_get_state(sw_rot_b) ? 'b' : ' '; | |
| 96 | + buf[11] = 0; | |
| 97 | + | |
| 98 | + menu_update_content(buf); | |
| 99 | +} | |
| 100 | + | |
| 101 | +/// ethernet screen | |
| 102 | +static void menu_screen_eth(void) | |
| 103 | +{ | |
| 104 | + char buf[] = "RX 0000 TX 0000"; | |
| 105 | + | |
| 106 | + menu_uint2dec(eth_rx_get_cnt(), 4, &buf[3]); | |
| 107 | + menu_uint2dec(eth_tx_get_cnt(), 4, &buf[11]); | |
| 108 | + | |
| 109 | + menu_update_content(buf); | |
| 110 | +} | |
| 111 | + | |
| 112 | +/// MAC address screen | |
| 113 | +static void menu_screen_mac(void) | |
| 114 | +{ | |
| 115 | + unsigned int i; | |
| 116 | + char buf[] = "000000000000"; | |
| 117 | + | |
| 118 | + for (i = 0; i < 6; ++i) | |
| 119 | + menu_uint2hex(config_mac.mac[i], 2, &buf[i * 2]); | |
| 120 | + | |
| 121 | + menu_update_content(buf); | |
| 122 | +} | |
| 123 | + | |
| 124 | +/// IP address screen | |
| 125 | +static void menu_screen_ip(void) | |
| 126 | +{ | |
| 127 | + unsigned int i; | |
| 128 | + char buf[] = "000.000.000.000"; | |
| 129 | + | |
| 130 | + for (i = 0; i < 4; ++i) | |
| 131 | + menu_uint2dec(config_ip.ip[i], 3, &buf[i * 4]); | |
| 132 | + | |
| 133 | + menu_update_content(buf); | |
| 134 | +} | |
| 135 | + | |
| 136 | +/// subnet mask screen | |
| 137 | +static void menu_screen_netmask(void) | |
| 138 | +{ | |
| 139 | + unsigned int i; | |
| 140 | + char buf[] = "000.000.000.000"; | |
| 141 | + | |
| 142 | + for (i = 0; i < 4; ++i) | |
| 143 | + menu_uint2dec(config_ip.mask[i], 3, &buf[i * 4]); | |
| 144 | + | |
| 145 | + menu_update_content(buf); | |
| 146 | +} | |
| 147 | + | |
| 148 | +/// gateway IP screen | |
| 149 | +static void menu_screen_gateway(void) | |
| 150 | +{ | |
| 151 | + unsigned int i; | |
| 152 | + char buf[] = "000.000.000.000"; | |
| 153 | + | |
| 154 | + for (i = 0; i < 4; ++i) | |
| 155 | + menu_uint2dec(config_ip.gw[i], 3, &buf[i * 4]); | |
| 156 | + | |
| 157 | + menu_update_content(buf); | |
| 158 | +} | |
| 159 | + | |
| 160 | +/// available screens | |
| 161 | +static struct menu_screen { | |
| 162 | + const char *title; ///< title of screen | |
| 163 | + void (*update)(void); ///< function to update screen content | |
| 164 | +} menu_screens[] = { | |
| 165 | +  { "MIPS I", menu_screen_start }, | |
| 166 | +  { "switches", menu_screen_switches }, | |
| 167 | +  { "ethernet", menu_screen_eth }, | |
| 168 | +  { "MAC address", menu_screen_mac }, | |
| 169 | +  { "IP address", menu_screen_ip }, | |
| 170 | +  { "subnet mask", menu_screen_netmask }, | |
| 171 | +  { "gateway IP", menu_screen_gateway }, | |
| 172 | +}; | |
| 173 | + | |
| 174 | +/// initialize | |
| 175 | +void menu_init(void) | |
| 176 | +{ | |
| 177 | + lcd_init(); | |
| 178 | + menu_cur_screen = 0; | |
| 179 | + lcd_str(0, menu_screens[0].title); | |
| 180 | + menu_screens[0].update(); | |
| 181 | +} | |
| 182 | + | |
| 183 | +/// task procedure - call as often as possible | |
| 184 | +void menu_task(void) | |
| 185 | +{ | |
| 186 | + // get new screen to show | |
| 187 | + unsigned int new_rot_cnt = switches_get_rot_cnt(); | |
| 188 | + unsigned int new_rot_val = (new_rot_cnt + 2) / 4; // 1 click is 4 steps | |
| 189 | + int delta = new_rot_val - menu_cur_rot_val; | |
| 190 | + menu_cur_rot_val = new_rot_val; | |
| 191 | + int new_screen = menu_cur_screen + delta; | |
| 192 | + if (new_screen < 0) | |
| 193 | + new_screen = count(menu_screens) - (-new_screen % count(menu_screens)); | |
| 194 | + new_screen = new_screen % count(menu_screens); | |
| 195 | + | |
| 196 | + // screen changed -> show new title | |
| 197 | +  if (new_screen != menu_cur_screen) { | |
| 198 | + menu_cur_screen = new_screen; | |
| 199 | + lcd_str(0, menu_screens[menu_cur_screen].title); | |
| 200 | + } | |
| 201 | + // update current screen | |
| 202 | + menu_screens[menu_cur_screen].update(); | |
| 203 | +} | |
| 204 | + |