/** * \brief Scrolling start. * * This function start the Bit mapping text. * * \param data Data string buffer. * \param length Data string length. */ void xpro_lcd_text_bitmapping_start(uint8_t user_style) { /* Default config for automated bit mapping */ uint8_t config_user_style = (user_style & 0x03); uint8_t config_size = 0; uint8_t config_fc_value = 0; enum slcd_frame_counter config_fc = SLCD_FRAME_COUNTER_0; /* User buffer to load the user style. In this array new styles can be * added as a new row with the same column width. * At the end of the each style's array member value should be kept * as 0x0000FF00 to calculate the block_count. * The empty elements between the style members should be 0x0000FFFF. */ uint16_t i=0; uint32_t user_style_buf[5][30] = { { /* STYLE 0 */ 0x00000040, 0x000600e0, 0x000C0070, 0x00120000, /*'A' 0x07e4 */ 0x00010005, 0x00070000, 0x000D0000, 0x00130008, /*'T' 0x8005 */ 0x00010085, 0x00070070, 0x000D0060, 0x00130008, /*'M' 0x0678 */ 0x00020004, 0x0008000a, 0x000E0003, 0x00140002, /*'E' 0x23a4 */ 0x00020004, 0x0008002a, 0x000E0023, 0x00140022, /*'L' 0x2220 */ 0x0000FF00, 0x0000FF00, 0x0000FF00, 0x0000FF00 }, { /* STYLE 1 */ 0x00000040,0x00070000,0x000D0060,0x00140002, 0x000600e0,0x000D0060,0x00130008,0x00020004, 0x000C0070,0x00130008,0x00020004,0x0008000a, 0x00120000,0x00010005,0x0008002a,0x000E0003, 0x00010085,0x00070070,0x000E0023,0x00140022, 0x0000FF00,0x0000FF00,0x0000FF00,0x0000FF00 }, { /* STYLE 2 */ 0x00000040,0x00010004,0x00020004,0x00010045, 0x00060060,0x00070070,0x00010085,0x000600E0, 0x00080022,0x0008002a,0x000C0010,0x000E0001, 0x000C0070,0x000D0060,0x000E0023,0x00130008, 0x00140022,0x0000FF00,0x0000FF00,0x0000FF00, 0x0000FF00,0x0000FF00,0x0000FF00,0x0000FF00 }, { /* STYLE 3 */ 0x00000040,0x00010044,0x0000FFFF,0x0000FFFF, 0x00020044,0x00080040,0x00000000,0x00010000, 0x000E0040,0x00140022,0x00020000,0x00080000, 0x00120020,0x00130022,0x000E0000,0x00140000, 0x000C0020,0x00060020,0x00120000,0x00130000, 0x00000040,0x000C0000,0x00060000,0x0000FF00 }, { /* SPARE x */ 0x00000040,0x00010004,0x00020004,0x00010045, 0x00060060,0x00070070,0x00010085,0x000600E0, 0x00080022,0x0008002a,0x000C0010,0x000E0001, 0x000C0070,0x000D0060,0x000E0023,0x00130008, 0x00140022,0x0000FF00,0x0000FF00,0x0000FF00, 0x0000FF00,0x0000FF00,0x0000FF00,0x0000FF00 } }; /* Variable use to find the DMA transfer block count at runtime based * on the user input string/style. */ dma_block_count = 0; /* Clears the previous values present in the dma_source_buf */ clear_buffer(); /* used to copy the user style to dma_source buffer for the DMA transfer. * The user style options are Style0, Style1, Style2 & Style3. */ while (0x0000FF00 != user_style_buf[config_user_style][i]) { dma_source_buf[i] = user_style_buf[config_user_style][i]; /* To find the user style number of segment data */ dma_block_count++; i++; } /* user configurations for automated bit mapping */ if ((uint8_t) 0x03 == config_user_style) { config_size = 1; config_fc_value = 0x01; bitmapping_repeat_count = 0x05; } else { config_size = 3; config_fc_value = 0x0F; bitmapping_repeat_count = 0x01; } config_fc = SLCD_FRAME_COUNTER_1; /* Disable SLCD to write the enable-protected registers */ slcd_disable(); /* write the SLCD ABM configurations in the respective registers */ slcd_set_automated_bit(config_size, config_fc); /* Disable Frame counter to write the enable-protected registers */ slcd_disable_frame_counter(config_fc); /* Set the frame counter configurations and enable it */ slcd_set_frame_counter(config_fc, 1, config_fc_value); slcd_enable_frame_counter(config_fc); /* Enable SLCD */ slcd_enable(); /* Configure DMA */ configure_dma(); /* Start DMA transfer, once DMA gets the peripheral trigger from the ABM, * the data transfer starts. */ dma_start_transfer_job(&example_resource); /* Enable ACM mode */ slcd_enable_automated_bit(); }
static int parse_slot_config(int slot, const unsigned char *buf, struct eeprom_eisa_slot_info *es, struct resource *io_parent, struct resource *mem_parent) { int res=0; int function_len; unsigned int pos=0; unsigned int maxlen; int num_func=0; u_int8_t flags; int p0; char *board; int id_string_used=0; if (NULL == (board = kmalloc(8, GFP_KERNEL))) { return -1; } print_eisa_id(board, es->eisa_slot_id); printk(KERN_INFO "EISA slot %d: %s %s ", slot, board, es->flags&HPEE_FLAG_BOARD_IS_ISA ? "ISA" : "EISA"); maxlen = es->config_data_length < HPEE_MAX_LENGTH ? es->config_data_length : HPEE_MAX_LENGTH; while ((pos < maxlen) && (num_func <= es->num_functions)) { pos+=configure_function(buf+pos, &function_len); if (!function_len) { break; } num_func++; p0 = pos; pos += configure_choise(buf+pos, &flags); if (flags & HPEE_FUNCTION_INFO_F_DISABLED) { /* function disabled, skip silently */ pos = p0 + function_len; continue; } if (flags & HPEE_FUNCTION_INFO_CFG_FREE_FORM) { /* I have no idea how to handle this */ printk("function %d have free-form confgiuration, skipping ", num_func); pos = p0 + function_len; continue; } /* the ordering of the sections need * more investigation. * Currently I think that memory comaed before IRQ * I assume the order is LSB to MSB in the * info flags * eg type, memory, irq, dma, port, HPEE_PORT_init */ if (flags & HPEE_FUNCTION_INFO_HAVE_TYPE) { pos += configure_type_string(buf+pos); } if (flags & HPEE_FUNCTION_INFO_HAVE_MEMORY) { id_string_used=1; pos += configure_memory(buf+pos, mem_parent, board); } if (flags & HPEE_FUNCTION_INFO_HAVE_IRQ) { pos += configure_irq(buf+pos); } if (flags & HPEE_FUNCTION_INFO_HAVE_DMA) { pos += configure_dma(buf+pos); } if (flags & HPEE_FUNCTION_INFO_HAVE_PORT) { id_string_used=1; pos += configure_port(buf+pos, io_parent, board); } if (flags & HPEE_FUNCTION_INFO_HAVE_PORT_INIT) { pos += configure_port_init(buf+pos); } if (p0 + function_len < pos) { printk("\n" KERN_ERR "eisa_enumerator: function %d length mis-match " "got %d, expected %d\n", num_func, pos-p0, function_len); res=-1; break; } pos = p0 + function_len; } printk("\n"); if (!id_string_used) { kfree(board); } if (pos != es->config_data_length) { printk(KERN_ERR "eisa_enumerator: config data length mis-match got %d, expected %d\n", pos, es->config_data_length); res=-1; } if (num_func != es->num_functions) { printk(KERN_ERR "eisa_enumerator: number of functions mis-match got %d, expected %d\n", num_func, es->num_functions); res=-2; } return res; }
/** * \brief Scrolling start. * * This function start the text scrolling. * * \param data Data string buffer. * \param length Data string length. */ void xpro_lcd_text_scrolling_start(char *data) { /* Structures for the ACM configurations */ struct slcd_automated_char_config automated_char_config; uint16_t i=0; dma_block_count = 0; /* used to copy the user scrolling string into dma_source * buffer for the DMA transfer * The scrolling may be runtime user input string 25char max * or the default scrolling string in user_scrolling_str[]. */ while (*data != '\0') { /* Copying the scrolling string into DMA source buffer*/ dma_source_buf[i++] = DIGI_LUT[*(data++) - 32]; /* To find the scrolling string length */ dma_block_count++; } if (true == is_scrolling) { /* configuration for Auto character mapping scrolling mode */ /* Get default config for the ACM mode */ slcd_automated_char_get_config_default(&automated_char_config); /* Segment mapping order. (CMCFG.DEC bit) */ automated_char_config.order = SLCD_AUTOMATED_CHAR_START_FROM_BOTTOM_RIGHT; /* select the number of segment used per digit, * it equal to number of SEG line - 1. (CMCFG.DEC). */ automated_char_config.seg_line_num = 3; /* Define the number of digit per row. (ACMCFG.NDROW) */ automated_char_config.row_digit_num = XPRO_LCD_MAX_CHAR; /* Define the index of the first segment terminal of the digit * to display. (ACMCFG.STSEG). */ automated_char_config.start_seg_line = XPRO_LCD_TXT_SEG_INDEX_S; /* Define the number of digit, it must be greater than 1. * (ACMCFG.NDIG). */ automated_char_config.digit_num = XPRO_LCD_MAX_CHAR; /* STEPS = string length - digit_num + 1. (ACMCFG.STEPS) */ automated_char_config.scrolling_step = dma_block_count - 5 + 1; /* Select the ACM mode (ACMCFG.MODE) */ automated_char_config.mode = SLCD_AUTOMATED_CHAR_SCROLL; /* Select the frame counter for the ACM mode. (ACMCFG.FCS) */ automated_char_config.fc = SLCD_FRAME_COUNTER_1; /* Configure the mask value in the CMDMASK register */ automated_char_config.data_mask = 0x00FF4002; } /* Disable SLCD to write the enable-protected registers */ slcd_disable(); /* write the SLCD ACM configurations in the respective registers */ slcd_automated_char_set_config(&automated_char_config); /* Disable Frame counter to write the enable-protected registers */ slcd_disable_frame_counter(automated_char_config.fc); slcd_dma_display_memory_update_fc_sel(automated_char_config.fc); /* Set the Frame counter configurations and enable it */ slcd_set_frame_counter(automated_char_config.fc, 0, 0x1); slcd_enable_frame_counter(automated_char_config.fc); /* Enable SLCD */ slcd_enable(); /* Configure DMA */ configure_dma(); /* Start DMA transfer, once DMA gets the peripheral trigger from the ACM, * the data transfer starts. */ dma_start_transfer_job(&example_resource); /* Enable ACM mode */ slcd_enable_automated_character(); }
/** * \brief Main Application Routine \n * - Initialize the system clocks \n * NOTE: The clock should be configured in conf_clock.h \n * - Configure port pins (PA14 and PA16) are used here \n * - Enable Global Interrupt \n * - Configure and enable USART \n * - Configure and enable ADC \n * - Configure and enable DMAC and EVSYS if DMAC mode is chosen \n * - Start first ADC conversion \n * - Count idle loop count in forever loop \n */ int main(void) { /* Initialize system clocks */ system_init(); #if defined(ENABLE_PORT_TOGGLE) /* Configure PORT pins PA14 and PA16 are configured here * NOTE: Use oscilloscope to probe the pin. */ configure_port(); #endif /* ENable Global interrupt */ system_interrupt_enable_global(); /* Start SysTick Timer */ systick_init(); /* Configure SERCOM - USART */ configure_usart(); /* Configure and enable ADC */ configure_adc(); /* Configure and enable EVSYS */ configure_event(); /* Configure and enable DMA channel and descriptor */ configure_dma(); /* Get the time stamp 1 before starting ADC transfer */ time_stamp1 = SysTick->VAL; /* * Trigger first ADC conversion through software. * NOTE: In case of using DMA, further conversions are triggered through * event generated when previous ADC result is transferred to destination * (can be USART DATA register [or] RAM buffer). * When DMA is not used, further conversions are triggered via software in * ADC handler after each result ready. */ adc_start_conversion(&adc_instance); while (1){ #if defined (ENABLE_PORT_TOGGLE) /* Use oscilloscope to probe the pin. */ port_base->OUTTGL.reg = (1UL << PIN_PA16 % 32 ); #endif /* Increment idle count whenever application reached while(1) loop */ idle_loop_count++; /* * Check if 1024 bytes transfer is done in either case (I.e. with or without * using DMA. * 'adc_conv_done' flag is set to true in the ADC handler once * 'adc_sample_count' reaches BLOCK_COUNT. * 'adc_dma_transfer_is_done' is set to true once DMA transfer is done * in DMA call back for channel zero when 'ADC_DMAC_USART' is chosen. * When choosing ADC_DMAC_MEM_MEM_USART mode, 'adc_dma_transfer_is_done' * is set to true in DMA channel call back for channel 2. * DMA channel is disabled once reaching BLOCK_COUNT (with DMA cases). * ADC is disabled once reaching BLOBK_COUNT samples (without DMA cases). */ if (adc_dma_transfer_is_done == true){ /* * Calculate number of cycles taken from the time stamp * taken before start of the conversion and after 1024 transfer * is completed. * NOTE: This value in relation to the idle_loop_count is * used in calculating CPU usage. */ cycles_taken = calculate_cycles_taken(time_stamp1,time_stamp2); /* Write the CPU cycles taken on USART */ usart_write_buffer_wait(&usart_instance, (uint8_t *)&cycles_taken, sizeof(cycles_taken)); /* Print idle loop count on USART */ usart_write_buffer_wait(&usart_instance,(uint8_t *)&idle_loop_count, sizeof(idle_loop_count)); /* * Enter into forever loop as all transfers are completed and * DMAC/ADC is disabled */ while(1); } } }//end of main