-/* Copyright (C) 2013 Czech Technical University in Prague
+/* Copyright (C) 2013, 2014, 2015 Czech Technical University in Prague
*
* Authors:
* - Carlos Jenkins <carlos@jenkins.co.cr>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* File : hbr.c
* Abstract:
#include "rpp/rpp.h"
+#include "rpp/mutex.h"
-#if rppCONFIG_INCLUDE_HBR == 1
+#ifndef FREERTOS_POSIX
+#include "drv/hbridge.h"
+#include "drv/spi_def.h"
+#endif
+
+RPP_MUTEX_DEFINE(mutex_hbr);
static boolean_t initialized = FALSE;
int8_t rpp_hbr_init()
{
- if(initialized) {
- return FAIL;
- }
- initialized = TRUE;
+ if (initialized)
+ return FAILURE;
+ if (!RPP_MUTEX_INIT(mutex_hbr))
+ return FAILURE;
+ initialized = TRUE;
+#ifndef FREERTOS_POSIX
+ dmmInit();
+ hetInit();
+ spi_init();
+#endif
+ return SUCCESS;
+}
- // FIXME: Implement.
- return SUCCESS;
+
+// Private function to set the H-Bridge to default OFF settings
+static void rpp_hdr_reset()
+{
+#ifndef FREERTOS_POSIX
+ drv_hbr_set_en(LOW);
+ drv_hbr_pwm_set_duty(0);
+ drv_hbr_pwm_stop();
+ drv_hbr_set_dir(LOW);
+#endif
}
-#endif /* rppCONFIG_INCLUDE_HBR */
+static boolean_t enabled = FALSE;
+
+int8_t rpp_hbr_enable(int32_t period)
+{
+ if (enabled)
+ return FAILURE;
+
+ if (period < 1)
+ period = 55; // ~18kHz (18181.818181818 Hz to be precise)
+
+#ifndef FREERTOS_POSIX
+ RPP_MUTEX_LOCK(mutex_hbr);
+ rpp_hdr_reset();
+ // Configure N2HET
+ if (drv_hbr_pwm_set_signal(period, 0) != SUCCESS) {
+ RPP_MUTEX_UNLOCK(mutex_hbr);
+ return FAILURE;
+ }
+ drv_hbr_pwm_start();
+
+ drv_hbr_set_en(HIGH);
+
+ // Start watchdog
+ int ret = drv_hbr_wdg_start();
+ if (ret != SUCCESS && ret != -RPP_EBUSY) { // Don't fail if already started
+ RPP_MUTEX_UNLOCK(mutex_hbr);
+ return FAILURE;
+ }
+ RPP_MUTEX_UNLOCK(mutex_hbr);
+#endif
+
+ enabled = TRUE;
+
+ return SUCCESS;
+}
+
+
+int8_t rpp_hbr_control(double cmd)
+{
+ if (!enabled)
+ return -1;
+
+ // Check range of the command
+ if ((cmd < -1.0) || (cmd > 1.0))
+ return -2;
+
+#ifndef FREERTOS_POSIX
+ // Great, now scale and return to sanity world of ints :D
+ int32_t scaled = (int32_t)(cmd * 100.0);
+
+
+ // Set direction
+ RPP_MUTEX_LOCK(mutex_hbr);
+ drv_hbr_set_dir(scaled > 0);
+
+ // Set PWM duty cycle
+ drv_hbr_pwm_set_duty(abs(scaled));
+ RPP_MUTEX_UNLOCK(mutex_hbr);
+#endif
+
+ return SUCCESS;
+}
+
+
+int8_t rpp_hbr_disable()
+{
+ if (!enabled)
+ return FAILURE;
+
+#ifndef FREERTOS_POSIX
+ RPP_MUTEX_LOCK(mutex_hbr);
+ rpp_hdr_reset();
+
+ // We ignore is watchdog could not be stopped, because is harmless.
+ // It would be worse if we just could not stop the H-Bridge just because
+ // the watchdog could not be stopped.
+ drv_hbr_wdg_stop();
+ RPP_MUTEX_UNLOCK(mutex_hbr);
+#endif
+
+ enabled = FALSE;
+
+ return SUCCESS;
+}