Added doxygen comments and refactored a few functions
This commit is contained in:
		| @@ -16,14 +16,15 @@ | ||||
|  | ||||
| #include "hifive1_io.h" | ||||
|  | ||||
| volatile uint32_t nextCommutationStep; | ||||
| /* | ||||
| Kommutierungsblöcke | ||||
|     1   2   3   4   5   6 | ||||
| U   0   z   +1  +1  z   0 | ||||
| V   +1  +1  z   0   0   z | ||||
| W   z   0   0   z   +1  +1 | ||||
| */ | ||||
| volatile uint32_t nextCommutationStep=0; | ||||
|  | ||||
| /* commutation blocks | ||||
|  *     1   2   3   4   5   6 | ||||
|  * U   0   z   +1  +1  z   0 | ||||
|  * V   +1  +1  z   0   0   z | ||||
|  * W   z   0   0   z   +1  +1 | ||||
|  */ | ||||
|  | ||||
| std::array<uint32_t, 6> driveTable { //! Drive pattern for commutation, CW rotation | ||||
|             ((1 << VH) | (1 << UL)), //1 | ||||
|             ((1 << VH) | (1 << WL)), //2 | ||||
| @@ -32,6 +33,7 @@ std::array<uint32_t, 6> driveTable { //! Drive pattern for commutation, CW rotat | ||||
|             ((1 << WH) | (1 << VL)), //5 | ||||
|             ((1 << WH) | (1 << UL))  //6 | ||||
| }; | ||||
|  | ||||
| std::array<uint32_t, 6> senseTable { //! channels to sense during the applied pattern | ||||
|     SENSW_N, //1 | ||||
|     SENSU_P, //2 | ||||
| @@ -44,10 +46,14 @@ std::array<uint32_t, 6> senseTable { //! channels to sense during the applied pa | ||||
| bool ccw=false; | ||||
|  | ||||
| typedef void (*function_ptr_t) (void); | ||||
| // Instance data for the PLIC. | ||||
| //! Instance data for the PLIC. | ||||
| plic_instance_t g_plic; | ||||
| std::array<function_ptr_t,PLIC_NUM_INTERRUPTS>  g_ext_interrupt_handlers; | ||||
|  | ||||
| /*! \brief external interrupt handler | ||||
|  * | ||||
|  * routes the peripheral interrupts to the the respective handler | ||||
|  * | ||||
|  */ | ||||
| extern "C" void handle_m_ext_interrupt() { | ||||
|     plic_source int_num  = PLIC_claim_interrupt(&g_plic); | ||||
|     if ((int_num >=1 ) && (int_num < PLIC_NUM_INTERRUPTS)) | ||||
| @@ -56,8 +62,9 @@ extern "C" void handle_m_ext_interrupt() { | ||||
|       exit(1 + (uintptr_t) int_num); | ||||
|     PLIC_complete_interrupt(&g_plic, int_num); | ||||
| } | ||||
|  | ||||
| // 1sec interval interrupt | ||||
| /*! \brief  mtime interval interrupt | ||||
|  * | ||||
|  */ | ||||
| extern "C" void handle_m_time_interrupt(){ | ||||
|     clear_csr(mie, MIP_MTIP); | ||||
|     // Reset the timer for 3s in the future. | ||||
| @@ -70,9 +77,13 @@ extern "C" void handle_m_time_interrupt(){ | ||||
|     // Re-enable the timer interrupt. | ||||
|     set_csr(mie, MIP_MTIP); | ||||
| } | ||||
|  | ||||
| /*! \brief dummy interrupt handler | ||||
|  * | ||||
|  */ | ||||
| void no_interrupt_handler (void) {}; | ||||
|  | ||||
| /*! \brief configure the per-interrupt handler | ||||
|  * | ||||
|  */ | ||||
| void configure_irq(size_t irq_num, function_ptr_t handler, unsigned char prio=1) { | ||||
|     g_ext_interrupt_handlers[irq_num] = handler; | ||||
|     // Priority must be set > 0 to trigger the interrupt. | ||||
| @@ -80,7 +91,9 @@ void configure_irq(size_t irq_num, function_ptr_t handler, unsigned char prio=1) | ||||
|     // Have to enable the interrupt both at the GPIO level, and at the PLIC level. | ||||
|     PLIC_enable_interrupt(&g_plic, irq_num); | ||||
| } | ||||
|  | ||||
| /*!\brief initializes platform | ||||
|  * | ||||
|  */ | ||||
| void platform_init(){ | ||||
|     // configure clocks | ||||
|     PRCI_use_hfxosc(1); // is equivalent to | ||||
| @@ -125,7 +138,9 @@ void platform_init(){ | ||||
|     // Enable interrupts in general. | ||||
|     set_csr(mstatus, MSTATUS_MIE); | ||||
| } | ||||
|  | ||||
| /*! \brief reads adc channel and returns measured value | ||||
|  * | ||||
|  */ | ||||
| unsigned read_adc(unsigned channel){ | ||||
|     std::array<uint8_t, 3> bytes{ | ||||
|                 uint8_t(0x06 | (channel>>2 & 0x1)), /* start bit, single ended measurement, channel[2] */ | ||||
| @@ -137,13 +152,8 @@ unsigned read_adc(unsigned channel){ | ||||
|     qspi1::transfer(bytes); | ||||
|     return (bytes[1]&0xf)*256+bytes[2]; | ||||
| } | ||||
|  | ||||
| /*! \brief Generates a delay used during startup | ||||
| /*! \brief waits for zero crossing and measures time until | ||||
|  * | ||||
|  *  This functions is used to generate a delay during the startup procedure. | ||||
|  *  The length of the delay equals delay * STARTUP_DELAY_MULTIPLIER microseconds. | ||||
|  *  Since Timer/Counter1 is used in this function, it must never be called when | ||||
|  *  sensorless operation is running. | ||||
|  */ | ||||
| unsigned short measured_zc_time(unsigned short max_delay){ | ||||
|     long delay_us = max_delay; | ||||
| @@ -169,21 +179,25 @@ unsigned short measured_zc_time(unsigned short max_delay){ | ||||
|     pwm0::cfg_reg().enoneshot=false; | ||||
|     return sreg*(1<<scaling_factor); | ||||
| } | ||||
|  | ||||
| void next_commutation_step(void) { | ||||
| /*! \brief calculates the next commutation step | ||||
|  * | ||||
|  */ | ||||
| inline void next_commutation_step(void) { | ||||
|     if (ccw) { | ||||
|         if (nextCommutationStep == 0) | ||||
|             nextCommutationStep = 0; | ||||
|         else | ||||
|             nextCommutationStep--; | ||||
|         nextCommutationStep = nextCommutationStep == 0? 5 : nextCommutationStep-1; | ||||
|     } else { | ||||
|         if (nextCommutationStep == 5) | ||||
|             nextCommutationStep = 0; | ||||
|         else | ||||
|             nextCommutationStep++; | ||||
|         nextCommutationStep = nextCommutationStep == 5? 0 : nextCommutationStep+1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*! \brief write the drive pattern to gpio | ||||
|  * | ||||
|  */ | ||||
| void setDrivePattern(uint32_t nextDrivePattern) { | ||||
|     gpio0::port_reg() = (gpio0::port_reg() & ~DRIVE_MASK & 0x00ffffff) | nextDrivePattern | nextCommutationStep << 24; | ||||
| } | ||||
| /*! \brief open-loop commutation to start the motor | ||||
|  * | ||||
|  */ | ||||
| void start_open_loop(void){ | ||||
|     auto delay = 30120U; | ||||
|     std::array<double, 2> multiplier={0.83, 1.0}; | ||||
| @@ -195,8 +209,7 @@ void start_open_loop(void){ | ||||
|     next_commutation_step(); | ||||
|     auto nextDrivePattern = driveTable[nextCommutationStep]; | ||||
|     for (size_t i = 0; i < 12; i++){ | ||||
|         gpio0::port_reg() = (gpio0::port_reg() & ~DRIVE_MASK & 0x00ffffff) | ||||
|                 | nextDrivePattern | nextCommutationStep<<24; | ||||
|         setDrivePattern(nextDrivePattern); | ||||
|         auto channel=senseTable[nextCommutationStep]&0x3; | ||||
|         auto zcPolRise = senseTable[nextCommutationStep]<4; | ||||
|         auto bemf_0=read_adc(channel); | ||||
| @@ -208,21 +221,24 @@ void start_open_loop(void){ | ||||
|         nextDrivePattern = driveTable[nextCommutationStep]; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*! \brief closed-loop commutation to run the motor | ||||
|  * | ||||
|  */ | ||||
| void run_closed_loop(void){ | ||||
|     auto count=0; | ||||
|     auto zc_delay=0U; | ||||
|     auto tmp=0U; | ||||
|     auto nextDrivePattern = driveTable[nextCommutationStep]; | ||||
|     for(;;){ | ||||
|         gpio0::port_reg() = (gpio0::port_reg() & ~DRIVE_MASK & 0x00ffffff) | ||||
|                 | nextDrivePattern | nextCommutationStep<<24; | ||||
|         setDrivePattern(nextDrivePattern); | ||||
|         zc_delay=measured_zc_time(50000); | ||||
|         next_commutation_step(); | ||||
|         nextDrivePattern = driveTable[nextCommutationStep]; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*! \brief main function | ||||
|  * | ||||
|  */ | ||||
| int main() { | ||||
|     platform_init(); | ||||
|     printf("Starting motor\n"); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user