Bluetooth enabled control of a BLDC via the Allegro MicroSystems A4960.
Dependencies: BLE_API mbed nRF51822
Fork of BLE_ModularRobot by
a4960.cpp@11:4251b62991ac, 2017-05-16 (annotated)
- Committer:
- anniemao
- Date:
- Tue May 16 19:31:49 2017 +0000
- Revision:
- 11:4251b62991ac
Annie Mao 2017
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
anniemao | 11:4251b62991ac | 1 | #include "a4960.h" |
anniemao | 11:4251b62991ac | 2 | |
anniemao | 11:4251b62991ac | 3 | a4960::a4960() : SPI(NRF_SPI1), _cs_pin(P0_10), _blink_pin(P0_4), _PWM_pin(P0_15) |
anniemao | 11:4251b62991ac | 4 | { |
anniemao | 11:4251b62991ac | 5 | PWM_freq = 20000.0; |
anniemao | 11:4251b62991ac | 6 | PWM_duty = 1; |
anniemao | 11:4251b62991ac | 7 | motor_started = false; |
anniemao | 11:4251b62991ac | 8 | |
anniemao | 11:4251b62991ac | 9 | _config[0] = (0x0 << 10) | (0x8 << 6) | (0x14); // 50 us comm blank time, 2.4 us blank time, 200 ns deadtime |
anniemao | 11:4251b62991ac | 10 | _config[1] = (0x7 << 6) | (0x0); // Vri = 100% Vref, Vdsth = 800mV |
anniemao | 11:4251b62991ac | 11 | _config[2] = (0x10); // 35.6 us current control time |
anniemao | 11:4251b62991ac | 12 | _config[3] = (0x0 << 8) | (0x5 << 4) | (0x4); // current limited, 50% current for hold, 18ms hold time |
anniemao | 11:4251b62991ac | 13 | _config[4] = (0x15 << 4) | (0x4); // 0.8ms min comm time, 24 ms start comm time |
anniemao | 11:4251b62991ac | 14 | _config[5] = (0x0 << 8) | (0x8 << 4) | (0x0); // 16.875deg phase adv, 100% ramp current, 0.4ms ramp rate |
anniemao | 11:4251b62991ac | 15 | _config[6] = (0x0); // fault detection all on |
anniemao | 11:4251b62991ac | 16 | _config[7] = (0x0 << 10) | (0x4 << 7) | (0x0 << 6) | (0x0 << 4) | (0x1 << 3) | (0x0 << 2) | (0x0 << 1) | (0x0); |
anniemao | 11:4251b62991ac | 17 | // auto BEMF hyst, 3.2us zx det window, no stop on fail, DIAG pin = fault, restart on loss of sync, brake off, forward, coast |
anniemao | 11:4251b62991ac | 18 | |
anniemao | 11:4251b62991ac | 19 | SPI_init(); |
anniemao | 11:4251b62991ac | 20 | } |
anniemao | 11:4251b62991ac | 21 | |
anniemao | 11:4251b62991ac | 22 | void a4960::SPI_init() |
anniemao | 11:4251b62991ac | 23 | { |
anniemao | 11:4251b62991ac | 24 | // initialize pins |
anniemao | 11:4251b62991ac | 25 | _cs_pin = 1; |
anniemao | 11:4251b62991ac | 26 | _blink_pin = 1; |
anniemao | 11:4251b62991ac | 27 | _PWM_pin.period(1/PWM_freq); |
anniemao | 11:4251b62991ac | 28 | _PWM_pin.write(PWM_duty); |
anniemao | 11:4251b62991ac | 29 | // initialize SPI connection |
anniemao | 11:4251b62991ac | 30 | SPI.begin(P0_8, P0_9, P0_11);//SCK, MOSI, MOSI |
anniemao | 11:4251b62991ac | 31 | // set registers to default config |
anniemao | 11:4251b62991ac | 32 | for (int i = 0; i < 8; i++) { |
anniemao | 11:4251b62991ac | 33 | write_to_a4960(i, _config[i]); |
anniemao | 11:4251b62991ac | 34 | } |
anniemao | 11:4251b62991ac | 35 | // turn off pin to indicate initialization complete |
anniemao | 11:4251b62991ac | 36 | _blink_pin = 0; |
anniemao | 11:4251b62991ac | 37 | } |
anniemao | 11:4251b62991ac | 38 | void a4960::write_to_a4960(uint8_t addr, uint16_t msg) |
anniemao | 11:4251b62991ac | 39 | { |
anniemao | 11:4251b62991ac | 40 | // split 16-bit message to a4960 into two 8-bit messages |
anniemao | 11:4251b62991ac | 41 | uint8_t ms_half; |
anniemao | 11:4251b62991ac | 42 | uint8_t ls_half; |
anniemao | 11:4251b62991ac | 43 | |
anniemao | 11:4251b62991ac | 44 | // ---- 1st message (bits 15 - 8) |
anniemao | 11:4251b62991ac | 45 | // 3 bit address |
anniemao | 11:4251b62991ac | 46 | ms_half = addr << 5; |
anniemao | 11:4251b62991ac | 47 | // 12 bit message |
anniemao | 11:4251b62991ac | 48 | // shift message to get rid of 8 LSB on the end and OR |
anniemao | 11:4251b62991ac | 49 | // the write bit and the |
anniemao | 11:4251b62991ac | 50 | // 4 remaining bits into the first-half msg |
anniemao | 11:4251b62991ac | 51 | ms_half = ms_half | 1 << 4 | (uint8_t)(msg>>8); |
anniemao | 11:4251b62991ac | 52 | // ---- 2nd message (bits 7 - 0) |
anniemao | 11:4251b62991ac | 53 | ls_half = (uint8_t)(msg); |
anniemao | 11:4251b62991ac | 54 | |
anniemao | 11:4251b62991ac | 55 | // pull to active low |
anniemao | 11:4251b62991ac | 56 | _cs_pin = 0; |
anniemao | 11:4251b62991ac | 57 | wait_us(200); |
anniemao | 11:4251b62991ac | 58 | |
anniemao | 11:4251b62991ac | 59 | // transfer the two messages halves, MSB first |
anniemao | 11:4251b62991ac | 60 | SPI.transfer(ms_half); |
anniemao | 11:4251b62991ac | 61 | SPI.transfer(ls_half); |
anniemao | 11:4251b62991ac | 62 | |
anniemao | 11:4251b62991ac | 63 | // wait and pull CS line back to inactive high |
anniemao | 11:4251b62991ac | 64 | wait_us(200); |
anniemao | 11:4251b62991ac | 65 | _cs_pin = 1; |
anniemao | 11:4251b62991ac | 66 | } |
anniemao | 11:4251b62991ac | 67 | |
anniemao | 11:4251b62991ac | 68 | void a4960::write_run(void) |
anniemao | 11:4251b62991ac | 69 | { |
anniemao | 11:4251b62991ac | 70 | write_to_a4960(7, _config[7] | 1); |
anniemao | 11:4251b62991ac | 71 | } |
anniemao | 11:4251b62991ac | 72 | |
anniemao | 11:4251b62991ac | 73 | void a4960::write_brake(void) |
anniemao | 11:4251b62991ac | 74 | { |
anniemao | 11:4251b62991ac | 75 | write_to_a4960(7, _config[7]); |
anniemao | 11:4251b62991ac | 76 | } |
anniemao | 11:4251b62991ac | 77 | |
anniemao | 11:4251b62991ac | 78 | |
anniemao | 11:4251b62991ac | 79 | |
anniemao | 11:4251b62991ac | 80 | |
anniemao | 11:4251b62991ac | 81 | |
anniemao | 11:4251b62991ac | 82 |