lunes, 19 de marzo de 2018


Hierarchical design

In this example, a 2-input digital adder, input carry and output sum are first designed.
The adder is then used to build a complete adder using the component and port directives. In addition generic is used to atomize the design for N inputs.

Dr. Carlos Hernandez. Any comment you can contact me at: postgraduatecahg@gmail.com
---------------------------------------------------------------------------------




library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity full_adder is
port (a, b, cin: in std_logic;
s, cout: out std_logic);
end full_adder;
architecture Behavioral of full_adder is
begin
  s<= a xor b xor cin;
  cout <= (a and b) or (a and cin) or (b and cin);


end Behavioral;

--------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity carry_ripple_adder is
generic (N: integer := 8); --number of bits
PORT (a, b: in std_logic_vector(N-1 downto 0);
cin: in std_logic;
s: out std_logic_vector(N-1 downto 0);
cout: out std_logic);
end carry_ripple_adder;
architecture Behavioral of carry_ripple_adder is
signal carry: std_logic_vector(N downto 0);
component full_adder is
port (a, b, cin: in std_logic;
s, cout: out std_logic);
end component;
begin
carry(0) <= cin;
gen_adder: for i in a'RANGE generate
FA: full_adder port map (a(i), b(i), carry(i), s(i), carry(i+1));
end generate;
cout <= carry(N);
end Behavioral;

--------------------------------------------------------------------

domingo, 18 de marzo de 2018

UART ARM Cortex M4 (Tiva C) 


/*

This program configures the UART to work with a bit-rate of 115200 bits/seconds.
The system clock is configured to work at 80MHz assisted by PLL.
We first define all register to configure the UART and then perform functions to send and read characters and strings.
*/

#include "TM4C123.h"                    // Device header


// configure the system to get its clock from the PLL


#define SYSCTL_RIS_R            (*((volatile unsigned long *)0x400FE050))

#define SYSCTL_RCC_R            (*((volatile unsigned long *)0x400FE060))
#define SYSCTL_RCC2_R           (*((volatile unsigned long *)0x400FE070))

// Define UART registers

#define GPIO_PORTA_AFSEL_R      (*((volatile unsigned long *)0x40004420))
#define GPIO_PORTA_DEN_R        (*((volatile unsigned long *)0x4000451C))
#define GPIO_PORTA_AMSEL_R      (*((volatile unsigned long *)0x40004528))
#define GPIO_PORTA_PCTL_R       (*((volatile unsigned long *)0x4000452C))
#define UART0_DR_R              (*((volatile unsigned long *)0x4000C000))
#define UART0_FR_R              (*((volatile unsigned long *)0x4000C018))
#define UART0_IBRD_R            (*((volatile unsigned long *)0x4000C024))
#define UART0_FBRD_R            (*((volatile unsigned long *)0x4000C028))
#define UART0_LCRH_R            (*((volatile unsigned long *)0x4000C02C))
#define UART0_CTL_R             (*((volatile unsigned long *)0x4000C030))
#define UART_FR_TXFF            0x00000020  // UART Transmit FIFO Full
#define UART_FR_RXFE            0x00000010  // UART Receive FIFO Empty

#define SYSCTL_RCGC1_R          (*((volatile unsigned long *)0x400FE104))

#define SYSCTL_RCGC2_R          (*((volatile unsigned long *)0x400FE108))


void PLL_Init(void);

void UART_Init(void);
void UART_Char_Output(unsigned char data);
unsigned char UART_Char_Input(void);
void UART_Write_String(char *p);

__asm void

Delay(unsigned long n)
{
    SUBS    R0, #1
    BNE     Delay
    BX      LR ;//the link register is providing the address to //branch to.
}

int main(void){  

  PLL_Init();
  UART_Init();

  while(1){

    UART_Char_Output('a');
    Delay(13333333);           // delay ~0.5 sec at 80 MHz

while(UART_Char_Input()!='b');
UART_Write_String("you pressed the character b");
    
}
}


void PLL_Init(void){

  // 0) Use RCC2
  SYSCTL_RCC2_R |=  0x80000000;  // USERCC2
  // 1) bypass PLL while initializing
  SYSCTL_RCC2_R |=  0x00000800;  // BYPASS2, PLL bypass
  // 2) select the crystal value and oscillator source
  SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0)   // clear XTAL field, bits 10-6
                 + 0x00000540;   // 10101, configure for 16 MHz crystal
  SYSCTL_RCC2_R &= ~0x00000070;  // configure for main oscillator source 10001111
  // 3) activate PLL by clearing PWRDN
  SYSCTL_RCC2_R &= ~0x00002000;
  // 4) set the desired system divider
  SYSCTL_RCC2_R |= 0x40000000;   // use 400 MHz PLL, DIV400
  SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000)  // clear system clock divider
                  + (4<<22);      // configure for 80 MHz clock,  400/(4+1) = 80MHz
  // 5) wait for the PLL to lock by polling PLLLRIS
  while((SYSCTL_RIS_R&0x00000040)==0){};  // wait for PLLRIS bit
  // 6) enable use of PLL by clearing BYPASS
  SYSCTL_RCC2_R &= ~0x00000800;
}

void UART_Init(void){

  SYSCTL_RCGC1_R |= 0x01; // activate UART0
  SYSCTL_RCGC2_R |= 0x01; // activate port A
  UART0_CTL_R &= ~0x01;   // disable UART
  UART0_IBRD_R = 43;   // IBRD = int(80,000,000 / (16 * 115,200)) = int(43.40278)
  UART0_FBRD_R = 26;      // FBRD = round(0.40278 * 64) = 26
  // 8 bit word length (no parity bits, one stop bit, FIFOs)
  UART0_LCRH_R = 0x70;// 0x01110000 
  //UART0_CTL_R |= UART_CTL_UARTEN;  // enable UART,  0x00000001  // UART Enable
  UART0_CTL_R |= 0x01;       // enable UART,  0x00000001  // UART Enable
  GPIO_PORTA_AFSEL_R |= 0x03;           // enable alt funct on PA1-0
  GPIO_PORTA_DEN_R |= 0x03;             // enable digital I/O on PA1-0
                                        // configure PA1-0 as UART
  GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0xFFFFFF00)+0x00000011;
  GPIO_PORTA_AMSEL_R &= ~0x03;          // disable analog functionality on PA
}

void UART_Char_Output(unsigned char data){

  while((UART0_FR_R & UART_FR_TXFF) != 0);
  UART0_DR_R = data;
}

unsigned char UART_Char_Input(void){

  while((UART0_FR_R & UART_FR_RXFE) != 0);
  return((unsigned char)(UART0_DR_R & 0xFF));
}

void UART_Write_String(char *p){

  while(*p){
    UART_Char_Output(*p);
    p++;
  }
}


Buffered Mux

This program is a sample of mux design using VHDL
Any comment you can contact me at: 
postgraduatecagh@gmail.com
---------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity buffered_mux is
  port (
  a, b, c, d: in std_logic_vector(7 downto 0);
  sel: in std_logic_vector(1 downto 0);
  enable: in std_logic;
  y: out std_logic_vector (7 downto 0));
end buffered_mux;
architecture Behavioral of buffered_mux is
signal x: std_logic_vector (7 downto 0);
begin
  x <= a when sel = "00" else --
  b when sel = "01" else
  c when sel = "10" else
  d;
 
  y <= x when enable = '1' else
  (others =>'Z');
 
end Behavioral;

lunes, 12 de marzo de 2018


Dr. Carlos Hernandez.

/*
This program configures the TIMER0 of the PIC182550 for a periodic interrupt.
/*


void interrupt() {

  PORTC.F0 = ~PORTC.F0;
  INTCON.TMR0IF=0; // clear the TIMER0 interrupt
  TMR0L = 100;
  T0CON.TMR0ON = 1;

}



void main() {

 PORTC = 0;
 LATC = 0;
 TRISC = 0x00;

 INTCON.GIE = 1;  // Global interrups enable

 INTCON.PEIE = 1;  // peripheri.
 INTCON.INT0IE = 0; // external interrup enable
 INTCON.TMR0IE = 1; // TIMER0  interrupt enable

 INTCON2.TMR0IP = 1; //TMR0 Overflow Interrupt Priority bit


 T0CON.T08BIT = 1; //8 bits TIMER0 configuration

 T0CON.T0CS = 0; //Timer0 Clock Source Select bit,
                 //0 = Internal instruction cycle clock (CLKO)
 T0CON.PSA = 0;  //0 = Timer0 prescaler is assigned.
                 // Timer0 clock input comes from prescaler output.
 T0CON.T0PS0 = 1; // Timer0 Prescaler Select bits
 T0CON.T0PS1 = 1; 
 T0CON.T0PS2 = 1; 

 TMR0L = 100;

 T0CON.TMR0ON = 1;   //start TMR0


while(1){


}


}











/*
LCD MikroC PIC18F2550
*/


unsigned int i = 0;
unsigned int temp_res=0;
unsigned int temp_average=0;
float temperature = 0;

// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC6_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC6_bit;
// End LCD module connections
char txt1[] = "STARTING";
char txt2[10];
char txt3[15];



void main() {
 PORTC = 0;
 LATC = 0;
 TRISC = 0x00;
 PORTA = 0;
 CMCON = 0;
 TRISA  = 0xFF;
 ADCON1 = 0x0E;  //  entradas digitales // 0xE
 PORTB = 0;
 TRISB = 0xCF;

Lcd_Init();                        // Initialize LCD
Lcd_Cmd(_LCD_CLEAR);               // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
Lcd_Out(1,1,txt1);                 // Write text in first row
Delay_ms(300);
Lcd_Cmd(_LCD_CLEAR);               // Clear display
Lcd_Out(1,1,"DR:");                // Write text in first row
Lcd_Out(2,1,"CARLOS HERNANDEZ");   // Write text in first row
Delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR);

  while(1) {   
        //adc_temperature();
        i++;
        IntToStr(i, txt2);
        Lcd_Out(2,0,txt2);
        delay_ms(500);
        if(i==100){
        i=0;
        }
  }
}


martes, 6 de marzo de 2018



How to perform an Assembly code within a C program in Keil for ARM cortex M



Dr. Carlos Hernandez-Gutierrez.

This sample is to perform an Assembly code within a C program.
The function is for a delay routine, where the R0 loads the value of n parameter of Delay function.
Then R0 is decreased to 0 and Jump to Delay until R0 is 0.
The routine spends three machine cycles. Thus if the clock system is 80MHz the delay obeys to the following formula.


Delay = n * 3 (1/80Mhz)

/* ****************************************************************************/*
__asm void
Delay(unsigned long n)
{
            SUBS    R0, #1
            BNE     Delay
            BX      LR ; //the link register is providing the address to branch to.
}



PLL (phase lock loop)



/*

*******************************************************************************************************
This program configures the PLL to operates at 80 MHz.
Therefore the system clock is runing at 80 MHz insted of 16 MHz.
*/

/* ***************************************************************************************************** 

These addresses define the registers that configure the PLL
*/

#define SYSCTL_RIS_R  (*((volatile unsigned long *)0x400FE050))

#define SYSCTL_RCC_R  (*((volatile unsigned long *)0x400FE060))
#define SYSCTL_RCC2_R (*((volatile unsigned long *)0x400FE070))

// The end of PLL registers definition.


#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))

#define GPIO_PORTF_DIR_R  (*((volatile unsigned long *)0x40025400))
#define GPIO_PORTF_AFSEL_R (*((volatile unsigned long *)0x40025420))
#define GPIO_PORTF_PUR_R   (*((volatile unsigned long *)0x40025510))
#define GPIO_PORTF_DEN_R   (*((volatile unsigned long *)0x4002551C))
#define GPIO_PORTF_LOCK_R  (*((volatile unsigned long *)0x40025520))
#define GPIO_PORTF_CR_R    (*((volatile unsigned long *)0x40025524))
#define GPIO_PORTF_AMSEL_R (*((volatile unsigned long *)0x40025528))
#define GPIO_PORTF_PCTL_R  (*((volatile unsigned long *)0x4002552C))
#define SYSCTL_RCGC2_R     (*((volatile unsigned long *)0x400FE108))


void PortF_Init(void);

void PLL_Init(void);

__asm void

Delay(unsigned long n)
{
    SUBS    R0, #1
    BNE     Delay
    bx      LR ;//the link register is providing the address to branch to.
}

int main(void){  

  PLL_Init();
PortF_Init();
  
  while(1){
    GPIO_PORTF_DATA_R |= 0x08;
    Delay(13333333);           // delay ~0.5 sec at 80 MHz
    GPIO_PORTF_DATA_R &= ~0x08;
    Delay(13333333);           // delay ~0.5 sec at 80 MHz
}
}

void PortF_Init(void){ 
  volatile unsigned long delay;
  SYSCTL_RCGC2_R |= 0x00000020;     // 1) F clock
  delay = SYSCTL_RCGC2_R;           // delay   
  GPIO_PORTF_LOCK_R = 0x4C4F434B;   // 2) unlock PortF PF0  
  GPIO_PORTF_CR_R |= 0x1F;           // allow changes to PF4-0       
  GPIO_PORTF_AMSEL_R &= 0x00;        // 3) disable analog function
  GPIO_PORTF_PCTL_R &= 0x00000000;   // 4) GPIO clear bit PCTL  
  GPIO_PORTF_DIR_R &= ~0x11;         // 5.1) PF4,PF0 input, 
  GPIO_PORTF_DIR_R |= 0x08;        // 5.2) PF3 output  
  GPIO_PORTF_AFSEL_R &= 0x00;     // 6) no alternate function
  GPIO_PORTF_PUR_R |= 0x11;   // enable pullup resistors on PF4,PF0       
  GPIO_PORTF_DEN_R |= 0x1F;     // 7) enable digital pins PF4-PF0     }

void PLL_Init(void){

  // 0) Use RCC2
  SYSCTL_RCC2_R |=  0x80000000;  // USERCC2
  // 1) bypass PLL while initializing
  SYSCTL_RCC2_R |=  0x00000800;  // BYPASS2, PLL bypass
  // 2) select the crystal value and oscillator source
  SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0)   
 // clear XTAL field, bits 10-6  + 0x00000540;   
 // 10101, configure for 16 MHz crystal
  SYSCTL_RCC2_R &= ~0x00000070;  // configure for main oscillator source 10001111
  // 3) activate PLL by clearing PWRDN
  SYSCTL_RCC2_R &= ~0x00002000;
  // 4) set the desired system divider
  SYSCTL_RCC2_R |= 0x40000000;   // use 400 MHz PLL, DIV400
  SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000)  // clear system clock divider
                  + (4<<22);      // configure for 80 MHz clock,  400/(4+1) = 80MHz
  // 5) wait for the PLL to lock by polling PLLLRIS
  while((SYSCTL_RIS_R&0x00000040)==0){};  // wait for PLLRIS bit
  // 6) enable use of PLL by clearing BYPASS
  SYSCTL_RCC2_R &= ~0x00000800;
}

BTFSS INSTRUCTION  IN ASSEMBLER FOR PIC18F In this sample, we show that how to use a switch input to make an action. Remember that I...