bd_size_t HeapBlockDevice::get_read_size() const { MBED_ASSERT(_blocks != NULL); return _read_size; }
HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t read, bd_size_t program, bd_size_t erase) : _read_size(read), _program_size(program), _erase_size(erase) , _count(size / erase), _blocks(0) { MBED_ASSERT(_count * _erase_size == size); }
void analogin_init(analogin_t *obj, PinName pin) { uint32_t function = (uint32_t)NC; // ADC Internal Channels "pins" (Temperature, Vref, Vbat, ...) // are described in PinNames.h and PeripheralPins.c // Pin value must be between 0xF0 and 0xFF if ((pin < 0xF0) || (pin >= 0x100)) { // Normal channels // Get the peripheral name from the pin and assign it to the object obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC); // Get the functions (adc channel) from the pin and assign it to the object function = pinmap_function(pin, PinMap_ADC); // Configure GPIO pinmap_pinout(pin, PinMap_ADC); } else { // Internal channels obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC_Internal); function = pinmap_function(pin, PinMap_ADC_Internal); // No GPIO configuration for internal channels } MBED_ASSERT(obj->handle.Instance != (ADC_TypeDef *)NC); MBED_ASSERT(function != (uint32_t)NC); obj->channel = STM_PIN_CHANNEL(function); // Save pin number for the read function obj->pin = pin; // Configure ADC object structures obj->handle.State = HAL_ADC_STATE_RESET; obj->handle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; obj->handle.Init.Resolution = ADC_RESOLUTION_12B; obj->handle.Init.ScanConvMode = DISABLE; obj->handle.Init.ContinuousConvMode = DISABLE; obj->handle.Init.DiscontinuousConvMode = DISABLE; obj->handle.Init.NbrOfDiscConversion = 0; obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; obj->handle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; obj->handle.Init.NbrOfConversion = 1; obj->handle.Init.DMAContinuousRequests = DISABLE; obj->handle.Init.EOCSelection = DISABLE; #if defined(ADC1) if ((ADCName)obj->handle.Instance == ADC_1) { __HAL_RCC_ADC1_CLK_ENABLE(); } #endif #if defined(ADC2) if ((ADCName)obj->handle.Instance == ADC_2) { __HAL_RCC_ADC2_CLK_ENABLE(); } #endif #if defined(ADC3) if ((ADCName)obj->handle.Instance == ADC_3) { __HAL_RCC_ADC3_CLK_ENABLE(); } #endif if (HAL_ADC_Init(&obj->handle) != HAL_OK) { error("Cannot initialize ADC"); } }
HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t block) : _read_size(block), _program_size(block), _erase_size(block) , _count(size / block), _blocks(0) { MBED_ASSERT(_count * _erase_size == size); }
// serial_baud // set the baud rate, taking in to account the current SystemFrequency void serial_baud(serial_t *obj, int baudrate) { MBED_ASSERT((int)obj->uart <= UART_3); // The LPC2300 and LPC1700 have a divider and a fractional divider to control the // baud rate. The formula is: // // Baudrate = (1 / PCLK) * 16 * DL * (1 + DivAddVal / MulVal) // where: // 1 < MulVal <= 15 // 0 <= DivAddVal < 14 // DivAddVal < MulVal // // set pclk to /1 switch ((int)obj->uart) { case UART_0: LPC_SC->PCLKSEL0 &= ~(0x3 << 6); LPC_SC->PCLKSEL0 |= (0x1 << 6); break; case UART_1: LPC_SC->PCLKSEL0 &= ~(0x3 << 8); LPC_SC->PCLKSEL0 |= (0x1 << 8); break; case UART_2: LPC_SC->PCLKSEL1 &= ~(0x3 << 16); LPC_SC->PCLKSEL1 |= (0x1 << 16); break; case UART_3: LPC_SC->PCLKSEL1 &= ~(0x3 << 18); LPC_SC->PCLKSEL1 |= (0x1 << 18); break; default: break; } uint32_t PCLK = SystemCoreClock; // First we check to see if the basic divide with no DivAddVal/MulVal // ratio gives us an integer result. If it does, we set DivAddVal = 0, // MulVal = 1. Otherwise, we search the valid ratio value range to find // the closest match. This could be more elegant, using search methods // and/or lookup tables, but the brute force method is not that much // slower, and is more maintainable. uint16_t DL = PCLK / (16 * baudrate); uint8_t DivAddVal = 0; uint8_t MulVal = 1; int hit = 0; uint16_t dlv; uint8_t mv, dav; if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder int err_best = baudrate, b; for (mv = 1; mv < 16 && !hit; mv++) { for (dav = 0; dav < mv; dav++) { // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; else // 2 bits headroom, use more precision dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood if (dlv == 0) dlv = 1; // datasheet says if dav > 0 then DL must be >= 2 if ((dav > 0) && (dlv < 2)) dlv = 2; // integer rearrangement of the baudrate equation (with rounding) b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; // check to see how we went b = abs(b - baudrate); if (b < err_best) { err_best = b; DL = dlv; MulVal = mv; DivAddVal = dav; if (b == baudrate) { hit = 1; break; } } } } } // set LCR[DLAB] to enable writing to divider registers obj->uart->LCR |= (1 << 7); // set divider values obj->uart->DLM = (DL >> 8) & 0xFF; obj->uart->DLL = (DL >> 0) & 0xFF; obj->uart->FDR = (uint32_t) DivAddVal << 0 | (uint32_t) MulVal << 4; // clear LCR[DLAB] obj->uart->LCR &= ~(1 << 7); }