Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added PWM, ADC tasks, interfaced potentiometer, RGB LEDs #3

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added ADC_PWM_Assignment_Part0_Tejas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ADC_PWM_Assignment_Part1_Tejas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions projects/lpc40xx_freertos/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files.associations": {
"cstdio": "c"
}
}
24 changes: 24 additions & 0 deletions projects/lpc40xx_freertos/assignment_include.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @file assignment_include.h
* @author Tejas Pidkalwar
* @date 19th Sept 2020
* @brief This file maintains the macro defined to enable specific assignment implementation for
* execution, along with subparts of assignment enabling feature
*/
#ifndef _ASSIGNMENT_INCLUDE_
#define _ASSIGNMENT_INCLUDE_

/*
* This file defines macros corresponding each assignment.
* Enable only one assignment macro while compiling.
* This file also defines macros for sub parts corresponding to each assignment.
* Take care to enable only one part macro enabled while compiling.
*/

// Assignment 5
#define ADC_PWM_ASSIGNMENT
//#define PART0_ADC_PWM_ASSGNMT
//#define PART1_ADC_PWM_ASSGNMT
#define PART2_ADC_PWM_ASSGNMT

#endif
12 changes: 12 additions & 0 deletions projects/lpc40xx_freertos/l3_drivers/adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,15 @@ void adc__initialize(void);
* This starts conversion of one channel, and should not be used from multiple tasks
*/
uint16_t adc__get_adc_value(adc_channel_e channel_num);

/**
* This function is responsible for enabling burst mode by configuring CR register
*/
void adc__enable_burst_mode(void);

/**
* Read the ADC channel values while in burst mode for a given channel
* @param channel_number The channel number of ADC to read the values
* @return read ADC values
*/
uint16_t adc__get_channel_reading_with_burst_mode(adc_channel_e channel_number);
17 changes: 16 additions & 1 deletion projects/lpc40xx_freertos/l3_drivers/sources/adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void adc__initialize(void) {
lpc_peripheral__turn_on_power_to(LPC_PERIPHERAL__ADC);

const uint32_t enable_adc_mask = (1 << 21);
LPC_ADC->CR = enable_adc_mask;
LPC_ADC->CR |= enable_adc_mask;

const uint32_t max_adc_clock = (12 * 1000UL * 1000UL); // 12.4Mhz : max ADC clock in datasheet for lpc40xx
const uint32_t adc_clock = clock__get_peripheral_clock_hz();
Expand Down Expand Up @@ -51,3 +51,18 @@ uint16_t adc__get_adc_value(adc_channel_e channel_num) {

return result;
}

void adc__enable_burst_mode(void) {
// Set the BURST bit in control register
LPC_ADC->CR |= (1 << 16);

// Clear Start bits from control register to be in burst mode
LPC_ADC->CR &= ~(0b111 << 24);
}

uint16_t adc__get_channel_reading_with_burst_mode(uint8_t channel_number) {
LPC_ADC->CR &= ~(0xFF);
LPC_ADC->CR |= (1 << 2);
uint32_t status = LPC_ADC->DR[2];
return ((status >> 4) & 0x0FFF);
}
9 changes: 9 additions & 0 deletions projects/lpc40xx_freertos/l3_drivers/sources/pwm1.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "clock.h"
#include "lpc40xx.h"
#include "lpc_peripherals.h"
#include "stdio.h"

void pwm1__init_single_edge(uint32_t frequency_in_hertz) {
const uint32_t pwm_channel_output_enable_mask = 0x3F;
Expand All @@ -16,6 +17,9 @@ void pwm1__init_single_edge(uint32_t frequency_in_hertz) {
}
const uint32_t match_reg_value = (clock__get_peripheral_clock_hz() / valid_frequency_in_hertz);

// TODO: Remove before commiting
fprintf(stderr, "PWM valid freq is %ld and match reg value is %ld \n", valid_frequency_in_hertz, match_reg_value);

// MR0 holds the value that Timer Counter should count upto
// This will get us the desired PWM pulses per second
// Ex: If CPU freq = 10Hz, desired frequency = 2Hz
Expand Down Expand Up @@ -53,5 +57,10 @@ void pwm1__set_duty_cycle(pwm1_channel_e pwm1_channel, float duty_cycle_in_perce
break;
}

#ifdef PART0_ADC_PWM_ASSGNMT
const uint32_t mr1_reg_val = LPC_PWM1->MR1;
fprintf(stderr, "Current Value of MR0 and MR1 registers are : %ld and %ld \n", mr0_reg_val, mr1_reg_val);

#endif
LPC_PWM1->LER |= (1 << (pwm1_channel + 1)); ///< Enable Latch Register
}
121 changes: 121 additions & 0 deletions projects/lpc40xx_freertos/l5_application/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,136 @@
#include "periodic_scheduler.h"
#include "sj2_cli.h"

#ifdef ADC_PWM_ASSIGNMENT

#include "adc.h"
#include "lpc_peripherals.h"
#include "pwm1.h"
#include "semphr.h"

#endif

static void create_blinky_tasks(void);
static void create_uart_task(void);
static void blink_task(void *params);
static void uart_task(void *params);

#ifdef ADC_PWM_ASSIGNMENT

QueueHandle_t adc_to_pwm_q;

void pwm_task() {
pwm1__init_single_edge(1000);

// Set port 2 pin 0 as PWM1 channel 0 as an PWM output
gpio__construct_with_function(2, 0, GPIO__FUNCTION_1);

// Initialize duty cycle to 50%
pwm1__set_duty_cycle(PWM1__2_0, 50);

#ifdef PART0_ADC_PWM_ASSGNMT
uint8_t percent = 0;
bool count_down = false;
while (1) {
pwm1__set_duty_cycle(PWM1__2_0, percent);

if (count_down) {
percent -= 5;
if (percent <= 0)
count_down = false;
} else {
percent += 5;
if (percent > 100)
count_down = true;
}
vTaskDelay(50);
}
#elif defined(PART2_ADC_PWM_ASSGNMT)
uint8_t percent = 0;
// Set port 2 pin 1 as PWM1 channel 1 as an PWM output
gpio__construct_with_function(2, 1, GPIO__FUNCTION_1);

// Set port 2 pin 2 as PWM1 channel 2 as an PWM output
gpio__construct_with_function(2, 2, GPIO__FUNCTION_1);
uint16_t max_adc_value = 4096;
uint16_t convertedValue = 0;
while (1) {
if (xQueueReceive(adc_to_pwm_q, &convertedValue, 100)) {
percent = (convertedValue * 100 / max_adc_value);
pwm1__set_duty_cycle(PWM1__2_0, percent);
pwm1__set_duty_cycle(PWM1__2_1, ((percent + 30) % 100));
pwm1__set_duty_cycle(PWM1__2_2, ((percent + 60) % 100));
}
}
#endif
}

void adc_task() {
adc__initialize();
adc__enable_burst_mode();

// Make Port 0 Pin 25 functionality as ADC0[2]
gpio__construct_with_function(0, 25, GPIO__FUNCTION_1);

// Set mode and analog input bits in control register
LPC_IOCON->P0_25 &= ~(0b11 << 3);

LPC_IOCON->P0_25 &= ~(1 << 7);
uint16_t convertedValue = 0;
#ifdef PART1_ADC_PWM_ASSGNMT

double current_voltage_value = 0;
double max_adc_value = 4096;
while (1) {
// Read the ADC value in burst mode
convertedValue = adc__get_channel_reading_with_burst_mode(ADC__CHANNEL_2);
current_voltage_value = (convertedValue / max_adc_value) * (3.3);
fprintf(stderr, "Current Pot Value is %d\n", convertedValue);
fprintf(stderr, "Current voltage level is %f \n", current_voltage_value);
vTaskDelay(1000);
}
#elif defined(PART2_ADC_PWM_ASSGNMT)
while (1) {
// Read the ADC value in burst mode
convertedValue = adc__get_channel_reading_with_burst_mode(ADC__CHANNEL_2);
// Send the ADC value to PWM channels
xQueueSend(adc_to_pwm_q, &convertedValue, 0);
vTaskDelay(100);
}
#endif
}

#endif

int main(void) {

#ifdef ADC_PWM_ASSIGNMENT

#if defined(PART0_ADC_PWM_ASSGNMT) || defined(PART2_ADC_PWM_ASSGNMT)

xTaskCreate(pwm_task, "pwm", 1024 / sizeof(void *), NULL, PRIORITY_LOW, NULL);

#endif

#if defined(PART1_ADC_PWM_ASSGNMT) || defined(PART2_ADC_PWM_ASSGNMT)

xTaskCreate(adc_task, "adc", 1024 / sizeof(void *), NULL, PRIORITY_LOW, NULL);

#endif

#ifdef PART2_ADC_PWM_ASSGNMT

adc_to_pwm_q = xQueueCreate(10, sizeof(uint16_t));

#endif

#else

create_blinky_tasks();
create_uart_task();

#endif

puts("Starting RTOS");
vTaskStartScheduler(); // This function never returns unless RTOS scheduler runs out of memory and fails

Expand Down
2 changes: 2 additions & 0 deletions projects/lpc40xx_freertos/lpc40xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#ifndef __LPC407x_8x_H__
#define __LPC407x_8x_H__

#include "assignment_include.h"

/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
Expand Down