Test application for getting the Nucleo F0 30 board to work with Evan's prototype LED board.
Dependencies: mbed
main.cpp
- Committer:
- bgrissom
- Date:
- 2014-08-08
- Revision:
- 6:e4da8955cf65
- Parent:
- 5:9a662dec2ddb
File content as of revision 6:e4da8955cf65:
#include "mbed.h" #define OK (0) #define ERROR (-1) #define PIN_41 PB_5 #define PIN_46 PB_9 #define PIN_32 PA_11 #define PIN_20 PB_2 #define HEX_ONE_THOUSAND (0x03E8) DigitalOut ENA(PIN_41); DigitalOut ENB(PIN_46); DigitalOut ENC(PIN_32); DigitalOut EnSclk(PIN_20); // Forward Declarations void pwmout_period_ns(pwmout_t* obj, int us); int cmd_S0(uint16_t value); void cmd_S1(void); // Globals bool gSpiMode = false; SPI* gSpiPtr = NULL; DigitalOut gbbTRANS(PA_4); // Global bit bang TRANS (data) line const int SCLK_ENABLED = 0; int main() { ENA = 1; ENB = 1; ENC = 1; EnSclk = SCLK_ENABLED; // NOTE: 24MHz is half the 48MHz clock rate. The PWM registers // seem to only allow 24MHz at this point, so I'm matching // the SPI bus speed to be the same. // // 1/24MHz => 1/(24*10^6) => 41.6*10^-9 second period, // which means 41.6ns period and 20.8ns pulse width at // 50% duty cycle (which seems to be right for the SPI clock // line as well as a reasonable choice for the PWM line). // BAG ORIG: gbbTRANS = 1; // Start with TRANS high. It acts like a SPI slave select // that is active-low. gbbTRANS = 0; // PWMCLK pwmout_t outs; pwmout_init(&outs, PB_4); pwmout_period_ns(&outs, 2); // 24 MHz (not very clean on the scope) // pwmout_period_ns(&outs, 40); // 1.2 MHz on the scope // Very slow! pwmout_period_us(&outs, 2); pwmout_write(&outs, 0.5f); int ret = OK; // Return value int i = 0; printf("17:10\n"); //while (1) { for (i=0; i<400; i++) { ret = cmd_S0(0x0900); // ORIG: ret = cmd_S0(0xFFFF); if (ret != OK) { printf("ERROR cmd_S0()\n"); return ERROR; } } cmd_S1(); //} } // S0 Command: // Needs only SCK and SIN (which are SPI_SCK and SPI_MOSI respectively). // This is because TRANS can be 0 for this command according to the datasheet. int cmd_S0(uint16_t value) { // Command S0 and S1 share the same clock line, so we need to be // careful which mode we are in. This avoids re-initializing these // pins if we are already in SPI mode. // WARNING: Re-initializing every time makes the MOSI line dirty and // is wasteful for the CPU. if ( gSpiMode == false && gSpiPtr == NULL) { // We are not using MISO, this is a one-way bus gSpiPtr = new SPI(SPI_MOSI, NC, SPI_SCK); if (gSpiPtr == NULL) { printf("ERROR: Could not allocate SPI\n"); return ERROR; } // Note: Polarity and phase are both 0 for the TC62D723FNG // For a graphical reminder on polarity and phase, visit: // http://www.eetimes.com/document.asp?doc_id=1272534 gSpiPtr->format(16, 0); // gSpiPtr->frequency(1000000); // 1.5 MHz on the scope gSpiPtr->frequency(24000000); // 24 MHz gSpiMode = true; } gbbTRANS = 0; // Like an SPI slave select gSpiPtr->write(value); gbbTRANS = 1; // Like an SPI slave select // LONGTERM OPTIMIZATION: Evan suggests setting it // wait_us(1); // gbbTRANS = 0; // Set back low return OK; } void cmd_S1(void) { int i = 0; int j = 0; gbbTRANS = 0; // FIXME if ( gSpiMode == true && gSpiPtr != NULL) { delete gSpiPtr; gSpiPtr = NULL; gSpiMode = false; } DigitalOut bbSCK (D13); // bit bang clock bbSCK = 0; // Start off/low gbbTRANS = 1; // Set high // Loop 6 times = 3 clock cycles for (j=0; j<6; j++) { // Always use an even number here! // The order of these two lines matter! i == 0 ? i = 1 : i = 0; // Toggle i i == 0 ? bbSCK = 0 : bbSCK = 1; // Set SCK to the same value as i } gbbTRANS = 0; // Set low } /* USED FOR THE F030 BOARD // This code is based off: // mbed/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c pwmout_period_us() void pwmout_period_ns_NOT_USED(pwmout_t* obj, int us) { TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; float dc = pwmout_read(obj); TIM_Cmd(tim, DISABLE); obj->period = us; TIM_TimeBaseStructure.TIM_Period = obj->period - 1; // Orig code: TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick TIM_TimeBaseStructure.TIM_Prescaler = 0; // BAG 1 ns tick (?) TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure); // Set duty cycle again pwmout_write(obj, dc); TIM_ARRPreloadConfig(tim, ENABLE); TIM_Cmd(tim, ENABLE); } */ static TIM_HandleTypeDef TimHandleBAG; void pwmout_write_BAG(pwmout_t* obj, float value) { TIM_OC_InitTypeDef sConfig; int channel = 0; int complementary_channel = 0; TimHandleBAG.Instance = (TIM_TypeDef *)(obj->pwm); if (value < (float)0.0) { value = 0.0; } else if (value > (float)1.0) { value = 1.0; } obj->pulse = (uint32_t)((float)obj->period * value); // Configure channels sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.Pulse = obj->pulse; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCFastMode = TIM_OCFAST_DISABLE; sConfig.OCIdleState = TIM_OCIDLESTATE_RESET; sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET; switch (obj->pin) { // Channels 1 case PA_2: case PA_4: case PA_6: case PA_7: case PA_8: case PB_1: case PB_4: case PB_8: case PB_9: case PB_14: case PC_6: channel = TIM_CHANNEL_1; break; // Channels 1N case PA_1: case PB_6: case PB_7: case PB_13: channel = TIM_CHANNEL_1; complementary_channel = 1; break; // Channels 2 case PA_3: case PA_9: case PB_5: case PB_15: case PC_7: channel = TIM_CHANNEL_2; break; // Channels 3 case PA_10: case PB_0: case PC_8: channel = TIM_CHANNEL_3; break; // Channels 4 case PA_11: case PC_9: channel = TIM_CHANNEL_4; break; default: return; } HAL_TIM_PWM_ConfigChannel(&TimHandleBAG, &sConfig, channel); if (complementary_channel) { HAL_TIMEx_PWMN_Start(&TimHandleBAG, channel); } else { HAL_TIM_PWM_Start(&TimHandleBAG, channel); } } void pwmout_period_ns(pwmout_t* obj, int us) { TimHandleBAG.Instance = (TIM_TypeDef *)(obj->pwm); float dc = pwmout_read(obj); __HAL_TIM_DISABLE(&TimHandleBAG); // Update the SystemCoreClock variable SystemCoreClockUpdate(); TimHandleBAG.Init.Period = us - 1; // BAG Orig: TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick TimHandleBAG.Init.Prescaler = 0; // BAG 1 ns tick (?) TimHandleBAG.Init.ClockDivision = 0; TimHandleBAG.Init.CounterMode = TIM_COUNTERMODE_UP; HAL_TIM_PWM_Init(&TimHandleBAG); // Set duty cycle again pwmout_write_BAG(obj, dc); // Save for future use obj->period = us; __HAL_TIM_ENABLE(&TimHandleBAG); }