PushToGo on STM32F429-Disco Board

Dependencies:   BSP_DISCO_F429ZI LCD_DISCO_F429ZI pushtogo usb

Committer:
caoyuan9642
Date:
Sun Sep 09 19:03:27 2018 +0000
Revision:
1:64c1fd738059
Child:
4:42a64e84f75a
updated docs

Who changed what in which revision?

UserRevisionLine numberNew contents of line
caoyuan9642 1:64c1fd738059 1 /**
caoyuan9642 1:64c1fd738059 2 * Harware setup is implemented in this file
caoyuan9642 1:64c1fd738059 3 */
caoyuan9642 1:64c1fd738059 4
caoyuan9642 1:64c1fd738059 5 #include "telescope_hardware.h"
caoyuan9642 1:64c1fd738059 6 #include "AMIS30543StepperDriver.h"
caoyuan9642 1:64c1fd738059 7 #include "AdaptiveAxis.h"
caoyuan9642 1:64c1fd738059 8 #include "EquatorialMount.h"
caoyuan9642 1:64c1fd738059 9 #include "RTCClock.h"
caoyuan9642 1:64c1fd738059 10 #include "SDBlockDevice.h"
caoyuan9642 1:64c1fd738059 11 #include "FATFileSystem.h"
caoyuan9642 1:64c1fd738059 12 #include "TelescopeConfiguration.h"
caoyuan9642 1:64c1fd738059 13 #include "EqMountServer.h"
caoyuan9642 1:64c1fd738059 14 #include "MCULoadMeasurement.h"
caoyuan9642 1:64c1fd738059 15 #include "USBSerial.h"
caoyuan9642 1:64c1fd738059 16
caoyuan9642 1:64c1fd738059 17 /**
caoyuan9642 1:64c1fd738059 18 * Right-Ascenstion Axis
caoyuan9642 1:64c1fd738059 19 */
caoyuan9642 1:64c1fd738059 20 SPI ra_spi(PC_12, PC_11, PB_3_ALT0);
caoyuan9642 1:64c1fd738059 21 AMIS30543StepperDriver *ra_stepper;
caoyuan9642 1:64c1fd738059 22
caoyuan9642 1:64c1fd738059 23 /**
caoyuan9642 1:64c1fd738059 24 * Declination Axis
caoyuan9642 1:64c1fd738059 25 */
caoyuan9642 1:64c1fd738059 26 SPI dec_spi(PE_6, PE_5, PE_2);
caoyuan9642 1:64c1fd738059 27 AMIS30543StepperDriver *dec_stepper;
caoyuan9642 1:64c1fd738059 28
caoyuan9642 1:64c1fd738059 29 /**
caoyuan9642 1:64c1fd738059 30 * Clock object
caoyuan9642 1:64c1fd738059 31 */
caoyuan9642 1:64c1fd738059 32 RTCClock clk;
caoyuan9642 1:64c1fd738059 33
caoyuan9642 1:64c1fd738059 34 /**
caoyuan9642 1:64c1fd738059 35 * SD card reader hardware configuration
caoyuan9642 1:64c1fd738059 36 */
caoyuan9642 1:64c1fd738059 37 SDBlockDevice sd(PA_7, PB_4, PA_5, PC_13);
caoyuan9642 1:64c1fd738059 38 FATFileSystem fs("sdcard");
caoyuan9642 1:64c1fd738059 39
caoyuan9642 1:64c1fd738059 40 const char *config_file_path = "/sdcard/telescope.cfg";
caoyuan9642 1:64c1fd738059 41 const char *config_saved_file_path = "/sdcard/telescope_saved.cfg";
caoyuan9642 1:64c1fd738059 42 AdaptiveAxis *ra_axis = NULL;
caoyuan9642 1:64c1fd738059 43 AdaptiveAxis *dec_axis = NULL;
caoyuan9642 1:64c1fd738059 44 EquatorialMount *eq_mount = NULL;
caoyuan9642 1:64c1fd738059 45
caoyuan9642 1:64c1fd738059 46 static void add_sys_commands();
caoyuan9642 1:64c1fd738059 47
caoyuan9642 1:64c1fd738059 48 EquatorialMount &telescopeHardwareInit()
caoyuan9642 1:64c1fd738059 49 {
caoyuan9642 1:64c1fd738059 50 // Read configuration
caoyuan9642 1:64c1fd738059 51 printf("Mounting SD card...\n");
caoyuan9642 1:64c1fd738059 52 if (fs.mount(&sd) != 0)
caoyuan9642 1:64c1fd738059 53 {
caoyuan9642 1:64c1fd738059 54 debug(
caoyuan9642 1:64c1fd738059 55 "Error: failed to mount SD card. Falling back to default configuration.\n");
caoyuan9642 1:64c1fd738059 56 }
caoyuan9642 1:64c1fd738059 57 else
caoyuan9642 1:64c1fd738059 58 {
caoyuan9642 1:64c1fd738059 59 // First check saved file
caoyuan9642 1:64c1fd738059 60 const char *file = config_saved_file_path;
caoyuan9642 1:64c1fd738059 61 FILE *fp = fopen(file, "r");
caoyuan9642 1:64c1fd738059 62 if (fp == NULL)
caoyuan9642 1:64c1fd738059 63 {
caoyuan9642 1:64c1fd738059 64 // Then check original file
caoyuan9642 1:64c1fd738059 65 file = config_file_path;
caoyuan9642 1:64c1fd738059 66 fp = fopen(file, "r");
caoyuan9642 1:64c1fd738059 67 if (fp == NULL)
caoyuan9642 1:64c1fd738059 68 {
caoyuan9642 1:64c1fd738059 69 debug("Error: config file not found.\n", config_file_path);
caoyuan9642 1:64c1fd738059 70 }
caoyuan9642 1:64c1fd738059 71 }
caoyuan9642 1:64c1fd738059 72
caoyuan9642 1:64c1fd738059 73 if (fp)
caoyuan9642 1:64c1fd738059 74 {
caoyuan9642 1:64c1fd738059 75 printf("Reading configuration file %s\n", file);
caoyuan9642 1:64c1fd738059 76 TelescopeConfiguration::readFromFile(fp);
caoyuan9642 1:64c1fd738059 77 fclose(fp);
caoyuan9642 1:64c1fd738059 78 }
caoyuan9642 1:64c1fd738059 79 }
caoyuan9642 1:64c1fd738059 80
caoyuan9642 1:64c1fd738059 81 // Object re-initialization
caoyuan9642 1:64c1fd738059 82 if (ra_axis != NULL)
caoyuan9642 1:64c1fd738059 83 {
caoyuan9642 1:64c1fd738059 84 delete ra_axis;
caoyuan9642 1:64c1fd738059 85 }
caoyuan9642 1:64c1fd738059 86 if (dec_axis != NULL)
caoyuan9642 1:64c1fd738059 87 {
caoyuan9642 1:64c1fd738059 88 delete dec_axis;
caoyuan9642 1:64c1fd738059 89 }
caoyuan9642 1:64c1fd738059 90 if (eq_mount != NULL)
caoyuan9642 1:64c1fd738059 91 {
caoyuan9642 1:64c1fd738059 92 delete eq_mount;
caoyuan9642 1:64c1fd738059 93 }
caoyuan9642 1:64c1fd738059 94 if (ra_stepper != NULL)
caoyuan9642 1:64c1fd738059 95 {
caoyuan9642 1:64c1fd738059 96 delete ra_stepper;
caoyuan9642 1:64c1fd738059 97 }
caoyuan9642 1:64c1fd738059 98 if (dec_stepper != NULL)
caoyuan9642 1:64c1fd738059 99 {
caoyuan9642 1:64c1fd738059 100 delete dec_stepper;
caoyuan9642 1:64c1fd738059 101 }
caoyuan9642 1:64c1fd738059 102
caoyuan9642 1:64c1fd738059 103 double stepsPerDeg = TelescopeConfiguration::getDouble("motor_steps")
caoyuan9642 1:64c1fd738059 104 * TelescopeConfiguration::getDouble("gear_reduction")
caoyuan9642 1:64c1fd738059 105 * TelescopeConfiguration::getDouble("worm_teeth") / 360.0;
caoyuan9642 1:64c1fd738059 106
caoyuan9642 1:64c1fd738059 107 ra_stepper = new AMIS30543StepperDriver(&ra_spi, PE_3, PB_7, NC, NC,
caoyuan9642 1:64c1fd738059 108 TelescopeConfiguration::getBool("ra_invert"));
caoyuan9642 1:64c1fd738059 109 dec_stepper = new AMIS30543StepperDriver(&dec_spi, PE_4, PC_8, NC, NC,
caoyuan9642 1:64c1fd738059 110 TelescopeConfiguration::getBool("dec_invert"));
caoyuan9642 1:64c1fd738059 111 ra_axis = new AdaptiveAxis(stepsPerDeg, ra_stepper, "RA_Axis");
caoyuan9642 1:64c1fd738059 112 dec_axis = new AdaptiveAxis(stepsPerDeg, dec_stepper, "DEC_Axis");
caoyuan9642 1:64c1fd738059 113 eq_mount = new EquatorialMount(*ra_axis, *dec_axis, clk,
caoyuan9642 1:64c1fd738059 114 LocationCoordinates(TelescopeConfiguration::getDouble("latitude"),
caoyuan9642 1:64c1fd738059 115 TelescopeConfiguration::getDouble("longitude")));
caoyuan9642 1:64c1fd738059 116
caoyuan9642 1:64c1fd738059 117 printf("Telescope initialized\n");
caoyuan9642 1:64c1fd738059 118
caoyuan9642 1:64c1fd738059 119 return (*eq_mount); // Return reference to eq_mount
caoyuan9642 1:64c1fd738059 120 }
caoyuan9642 1:64c1fd738059 121
caoyuan9642 1:64c1fd738059 122 /* Serial connection */
caoyuan9642 1:64c1fd738059 123 UARTSerial *console;
caoyuan9642 1:64c1fd738059 124 EqMountServer *server_serial;
caoyuan9642 1:64c1fd738059 125
caoyuan9642 1:64c1fd738059 126 /* USB connection */
caoyuan9642 1:64c1fd738059 127 EqMountServer *server_usb;
caoyuan9642 1:64c1fd738059 128
caoyuan9642 1:64c1fd738059 129 bool serverInitialized = false;
caoyuan9642 1:64c1fd738059 130
caoyuan9642 1:64c1fd738059 131 osStatus telescopeServerInit()
caoyuan9642 1:64c1fd738059 132 {
caoyuan9642 1:64c1fd738059 133 if (eq_mount == NULL)
caoyuan9642 1:64c1fd738059 134 return osErrorResource;
caoyuan9642 1:64c1fd738059 135 if (!serverInitialized)
caoyuan9642 1:64c1fd738059 136 {
caoyuan9642 1:64c1fd738059 137 // Only run once
caoyuan9642 1:64c1fd738059 138 serverInitialized = true;
caoyuan9642 1:64c1fd738059 139 add_sys_commands();
caoyuan9642 1:64c1fd738059 140 }
caoyuan9642 1:64c1fd738059 141
caoyuan9642 1:64c1fd738059 142 if (!console)
caoyuan9642 1:64c1fd738059 143 {
caoyuan9642 1:64c1fd738059 144 console = new UARTSerial(USBTX, USBRX,
caoyuan9642 1:64c1fd738059 145 TelescopeConfiguration::getInt("serial_baud"));
caoyuan9642 1:64c1fd738059 146 server_serial = new EqMountServer(*console, false);
caoyuan9642 1:64c1fd738059 147 }
caoyuan9642 1:64c1fd738059 148 server_serial->bind(*eq_mount);
caoyuan9642 1:64c1fd738059 149
caoyuan9642 1:64c1fd738059 150 if (!server_usb)
caoyuan9642 1:64c1fd738059 151 {
caoyuan9642 1:64c1fd738059 152 server_usb = new EqMountServer(USBSerial::getInstance(), false);
caoyuan9642 1:64c1fd738059 153 }
caoyuan9642 1:64c1fd738059 154 server_usb->bind(*eq_mount);
caoyuan9642 1:64c1fd738059 155
caoyuan9642 1:64c1fd738059 156 return osOK;
caoyuan9642 1:64c1fd738059 157 }
caoyuan9642 1:64c1fd738059 158
caoyuan9642 1:64c1fd738059 159 static int eqmount_sys(EqMountServer *server, const char *cmd, int argn,
caoyuan9642 1:64c1fd738059 160 char *argv[])
caoyuan9642 1:64c1fd738059 161 {
caoyuan9642 1:64c1fd738059 162 const int THD_MAX = 32;
caoyuan9642 1:64c1fd738059 163 osThreadId thdlist[THD_MAX];
caoyuan9642 1:64c1fd738059 164 int nt = osThreadEnumerate(thdlist, THD_MAX);
caoyuan9642 1:64c1fd738059 165
caoyuan9642 1:64c1fd738059 166 stprintf(server->getStream(), "Thread list: \r\n");
caoyuan9642 1:64c1fd738059 167 for (int i = 0; i < nt; i++)
caoyuan9642 1:64c1fd738059 168 {
caoyuan9642 1:64c1fd738059 169 osThreadState_t state = osThreadGetState(thdlist[i]);
caoyuan9642 1:64c1fd738059 170 const char *s = "";
caoyuan9642 1:64c1fd738059 171 const char *n;
caoyuan9642 1:64c1fd738059 172 osPriority_t prio = osThreadGetPriority(thdlist[i]);
caoyuan9642 1:64c1fd738059 173
caoyuan9642 1:64c1fd738059 174 if (prio == osPriorityIdle)
caoyuan9642 1:64c1fd738059 175 {
caoyuan9642 1:64c1fd738059 176 n = "Idle thread";
caoyuan9642 1:64c1fd738059 177 }
caoyuan9642 1:64c1fd738059 178 else
caoyuan9642 1:64c1fd738059 179 {
caoyuan9642 1:64c1fd738059 180 n = osThreadGetName(thdlist[i]);
caoyuan9642 1:64c1fd738059 181 if (n == NULL)
caoyuan9642 1:64c1fd738059 182 n = "System thread";
caoyuan9642 1:64c1fd738059 183 }
caoyuan9642 1:64c1fd738059 184
caoyuan9642 1:64c1fd738059 185 switch (state)
caoyuan9642 1:64c1fd738059 186 {
caoyuan9642 1:64c1fd738059 187 case osThreadInactive:
caoyuan9642 1:64c1fd738059 188 s = "Inactive";
caoyuan9642 1:64c1fd738059 189 break;
caoyuan9642 1:64c1fd738059 190 case osThreadReady:
caoyuan9642 1:64c1fd738059 191 s = "Ready";
caoyuan9642 1:64c1fd738059 192 break;
caoyuan9642 1:64c1fd738059 193 case osThreadRunning:
caoyuan9642 1:64c1fd738059 194 s = "Running";
caoyuan9642 1:64c1fd738059 195 break;
caoyuan9642 1:64c1fd738059 196 case osThreadBlocked:
caoyuan9642 1:64c1fd738059 197 s = "Blocked";
caoyuan9642 1:64c1fd738059 198 break;
caoyuan9642 1:64c1fd738059 199 case osThreadTerminated:
caoyuan9642 1:64c1fd738059 200 s = "Terminated";
caoyuan9642 1:64c1fd738059 201 break;
caoyuan9642 1:64c1fd738059 202 case osThreadError:
caoyuan9642 1:64c1fd738059 203 s = "Error";
caoyuan9642 1:64c1fd738059 204 break;
caoyuan9642 1:64c1fd738059 205 default:
caoyuan9642 1:64c1fd738059 206 s = "Unknown";
caoyuan9642 1:64c1fd738059 207 break;
caoyuan9642 1:64c1fd738059 208 }
caoyuan9642 1:64c1fd738059 209 stprintf(server->getStream(), " - %10s 0x%08x %3d %s \r\n", s,
caoyuan9642 1:64c1fd738059 210 (uint32_t) thdlist[i], (int) prio, n);
caoyuan9642 1:64c1fd738059 211 }
caoyuan9642 1:64c1fd738059 212
caoyuan9642 1:64c1fd738059 213 stprintf(server->getStream(), "\r\nRecent CPU usage: %.1f%%\r\n",
caoyuan9642 1:64c1fd738059 214 MCULoadMeasurement::getInstance().getCPUUsage() * 100);
caoyuan9642 1:64c1fd738059 215 return 0;
caoyuan9642 1:64c1fd738059 216 }
caoyuan9642 1:64c1fd738059 217
caoyuan9642 1:64c1fd738059 218 static int eqmount_systime(EqMountServer *server, const char *cmd, int argn,
caoyuan9642 1:64c1fd738059 219 char *argv[])
caoyuan9642 1:64c1fd738059 220 {
caoyuan9642 1:64c1fd738059 221 char buf[32];
caoyuan9642 1:64c1fd738059 222 time_t t = time(NULL);
caoyuan9642 1:64c1fd738059 223
caoyuan9642 1:64c1fd738059 224 core_util_critical_section_enter();
caoyuan9642 1:64c1fd738059 225 char *ibuf = ctime(&t);
caoyuan9642 1:64c1fd738059 226 strncpy(buf, ibuf, sizeof(buf));
caoyuan9642 1:64c1fd738059 227 core_util_critical_section_exit();
caoyuan9642 1:64c1fd738059 228
caoyuan9642 1:64c1fd738059 229 stprintf(server->getStream(), "Current UTC time: %s\r\n", buf);
caoyuan9642 1:64c1fd738059 230
caoyuan9642 1:64c1fd738059 231 return 0;
caoyuan9642 1:64c1fd738059 232 }
caoyuan9642 1:64c1fd738059 233
caoyuan9642 1:64c1fd738059 234 static int eqmount_reboot(EqMountServer *server, const char *cmd, int argn,
caoyuan9642 1:64c1fd738059 235 char *argv[])
caoyuan9642 1:64c1fd738059 236 {
caoyuan9642 1:64c1fd738059 237 NVIC_SystemReset();
caoyuan9642 1:64c1fd738059 238 return 0;
caoyuan9642 1:64c1fd738059 239 }
caoyuan9642 1:64c1fd738059 240
caoyuan9642 1:64c1fd738059 241 static int eqmount_save(EqMountServer *server, const char *cmd, int argn,
caoyuan9642 1:64c1fd738059 242 char *argv[])
caoyuan9642 1:64c1fd738059 243 {
caoyuan9642 1:64c1fd738059 244 if (argn == 0)
caoyuan9642 1:64c1fd738059 245 {
caoyuan9642 1:64c1fd738059 246 FILE *fp = fopen(config_saved_file_path, "w");
caoyuan9642 1:64c1fd738059 247 if (fp)
caoyuan9642 1:64c1fd738059 248 {
caoyuan9642 1:64c1fd738059 249 TelescopeConfiguration::writeToFile(fp);
caoyuan9642 1:64c1fd738059 250 fclose(fp);
caoyuan9642 1:64c1fd738059 251 }
caoyuan9642 1:64c1fd738059 252 else
caoyuan9642 1:64c1fd738059 253 {
caoyuan9642 1:64c1fd738059 254 debug("Failed to write to file %s\n", config_saved_file_path);
caoyuan9642 1:64c1fd738059 255 return -1;
caoyuan9642 1:64c1fd738059 256 }
caoyuan9642 1:64c1fd738059 257 }
caoyuan9642 1:64c1fd738059 258 else if (argn == 1 && strcmp(argv[0], "delete") == 0)
caoyuan9642 1:64c1fd738059 259 {
caoyuan9642 1:64c1fd738059 260 // Delete save file
caoyuan9642 1:64c1fd738059 261 if (remove(config_saved_file_path) != 0)
caoyuan9642 1:64c1fd738059 262 {
caoyuan9642 1:64c1fd738059 263 debug("Failed to delete file %s\n", config_saved_file_path);
caoyuan9642 1:64c1fd738059 264 return -1;
caoyuan9642 1:64c1fd738059 265 }
caoyuan9642 1:64c1fd738059 266 }
caoyuan9642 1:64c1fd738059 267 return 0;
caoyuan9642 1:64c1fd738059 268 }
caoyuan9642 1:64c1fd738059 269
caoyuan9642 1:64c1fd738059 270 static void add_sys_commands()
caoyuan9642 1:64c1fd738059 271 {
caoyuan9642 1:64c1fd738059 272 EqMountServer::addCommand(
caoyuan9642 1:64c1fd738059 273 ServerCommand("sys", "Print system information", eqmount_sys));
caoyuan9642 1:64c1fd738059 274 EqMountServer::addCommand(
caoyuan9642 1:64c1fd738059 275 ServerCommand("systime", "Print system time", eqmount_systime));
caoyuan9642 1:64c1fd738059 276 EqMountServer::addCommand(
caoyuan9642 1:64c1fd738059 277 ServerCommand("reboot", "Reboot the system", eqmount_reboot));
caoyuan9642 1:64c1fd738059 278 EqMountServer::addCommand(
caoyuan9642 1:64c1fd738059 279 ServerCommand("save", "Save configuration file", eqmount_save));
caoyuan9642 1:64c1fd738059 280 }
caoyuan9642 1:64c1fd738059 281