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

Assignment/spi driver #4

Open
wants to merge 6 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 doc/SPI_Assignment/LA-Part3_Erase_Success.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 doc/SPI_Assignment/LA_PART1_Man_id.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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 doc/SPI_Assignment/LA_Part3_Erase_start.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 doc/SPI_Assignment/LA_Part3_Read_Page_data.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 doc/SPI_Assignment/LA_Part3_Write_Page_data.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 doc/SPI_Assignment/Readme.pdf
Binary file not shown.
Binary file added doc/SPI_Assignment/Telemetry_Part1.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 doc/SPI_Assignment/Telemetry_Part2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions projects/lpc40xx_freertos/assignment_include.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @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 SPI
#define SPI_ASSIGNMENT
//#define PART0_SPI_ASSGNMT
//#define PART1_SPI_ASSGNMT
//#define PART2_SPI_ASSGNMT
#define PART3_SPI_ASSGNMT

#endif
60 changes: 60 additions & 0 deletions projects/lpc40xx_freertos/l3_drivers/sources/ssp2_lab.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* @file ssp2_lab.c
* @author Tejas Pidkalwar
* @date 1st Oct 2020
* @brief This file contains SSP2 driver configuration APIs
*/

#include "clock.h"
#include "delay.h"
#include "gpio.h"
#include "lpc40xx.h"
#include "lpc_peripherals.h"
#include <stdint.h>
#include <stdio.h>

void ssp2_lab_init(uint32_t max_clock_mhz) {
// Power on SSP2 peripheral
lpc_peripheral__turn_on_power_to(LPC_PERIPHERAL__SSP2);

const uint32_t cpu_clock_mhz = clock__get_core_clock_hz() / (1000 * 1000);
// Clock diviser for SSP2 as 4
LPC_SSP2->CPSR &= ~(0xFF);
LPC_SSP2->CPSR |= (cpu_clock_mhz / max_clock_mhz);

// Configure CR0 register
LPC_SSP2->CR0 |= (0b111 << 0);

// Configure CR1 register
LPC_SSP2->CR1 |= (1 << 1);
}

void ssp2_configure_pin_functions(void) {
// Select SSP pin clock
gpio__construct_with_function(GPIO__PORT_1, 0, GPIO__FUNCTION_4);

// Select SSP pin MOSI
gpio__construct_with_function(GPIO__PORT_1, 1, GPIO__FUNCTION_4);

// Select SSP pin MISO
gpio__construct_with_function(GPIO__PORT_1, 4, GPIO__FUNCTION_4);

// Select CS
gpio_s gpio_ssp_select = gpio__construct_as_output(GPIO__PORT_1, 10);
// Active low single needs be set by default
gpio__set(gpio_ssp_select);

// Select CS pin to replicate original CS operation to monitor on Logic Analyzer
gpio_s gpio_ssp_select_replicate = gpio__construct_as_output(GPIO__PORT_0, 6);
// Active low single needs be set by default
gpio__set(gpio_ssp_select_replicate);
}

uint8_t ssp2_lab_exchange_byte(uint8_t data_out) {
// Update Data Register with the given Data
LPC_SSP2->DR = data_out;
while ((LPC_SSP2->SR & (1 << 4))) {
;
}
return LPC_SSP2->DR;
}
17 changes: 17 additions & 0 deletions projects/lpc40xx_freertos/l3_drivers/ssp2_lab.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @file ssp2_lab.h
* @author Tejas Pidkalwar
* @date 1st Oct 2020
* @brief This file contains SSP2 driver configuration APIs
*/

#ifndef _SSP2_LAB_
#define _SSP2_LAB_

void ssp2_lab_init(uint32_t max_clock_mhz);

uint8_t ssp2_lab_exchange_byte(uint8_t data_out);

void ssp2_configure_pin_functions(void);

#endif
128 changes: 128 additions & 0 deletions projects/lpc40xx_freertos/l4_io/adesto_flash/adesto_flash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* @file adesto_flash.c
* @author Tejas Pidkalwar
* @date 1st Oct 2020
* @brief This file contains the Adesto flash configuration APIs
*/

#include "adesto_flash.h"
#include "ssp2_lab.h"
#include "stdio.h"

const uint8_t dummy_byte = 0xFF;

// TODO: Implement Adesto flash memory CS signal as a GPIO driver
void adesto_cs(void) {
LPC_GPIO1->CLR = (1 << 10);
LPC_GPIO0->CLR = (1 << 6);
}
void adesto_ds(void) {
LPC_GPIO1->SET = (1 << 10);
LPC_GPIO0->SET = (1 << 6);
}

#if defined(PART1_SPI_ASSGNMT) || defined(PART2_SPI_ASSGNMT)

// TODO: Implement the code to read Adesto flash memory signature
// TODO: Create struct of type 'adesto_flash_id_s' and return it
adesto_flash_id_s adesto_read_signature(void) {
adesto_flash_id_s data = {0};
const uint8_t flash_id_read_opcode = 0x9F;
adesto_cs();
{
// Send the opcode to trigger manufacturing ID read from flash
ssp2_lab_exchange_byte(flash_id_read_opcode);
// read out the manufacturing id from Flash by sending dummy bytes
data.manufacturer_id = ssp2_lab_exchange_byte(dummy_byte);
data.device_id_1 = ssp2_lab_exchange_byte(dummy_byte);
data.device_id_2 = ssp2_lab_exchange_byte(dummy_byte);
data.extended_device_id = ssp2_lab_exchange_byte(dummy_byte);
}
adesto_ds();

return data;
}

#endif

#ifdef PART3_SPI_ASSGNMT

/**
* Send the 3 Bytes of address from the given one
* @param address Address bytes to be sent
*/
static void adesto_flash_send_address(uint32_t address) {
(void)ssp2_lab_exchange_byte((address >> 16) & 0xFF);
(void)ssp2_lab_exchange_byte((address >> 8) & 0xFF);
(void)ssp2_lab_exchange_byte((address >> 0) & 0xFF);
}

/**
* Set the write enable latch WEL bit of status register byte 1
*/
static void adesto_flash_WEL_bit_set(void) {
const uint8_t wel_bit_set_opcode = 0x06;
adesto_cs();
ssp2_lab_exchange_byte(wel_bit_set_opcode);
adesto_ds();
}

/**
* Erase the 4K block of memory starting from given address
* @param erase_address Block's starting address to be erased
*/
static void adesto_flash_erase_4k_block(const uint32_t erase_address) {
uint8_t status_reg_read_opcode = 0x05;
uint8_t status_byte1 = 0x5;
uint8_t erase_4k_block_opcode = 0x20;
// Start of Erase Sequence
adesto_flash_WEL_bit_set();
adesto_cs();
ssp2_lab_exchange_byte(erase_4k_block_opcode);
adesto_flash_send_address(erase_address);
adesto_ds();

// Wait for erase operation to complete by polling on flash status register's Busy bit
adesto_cs();
ssp2_lab_exchange_byte(status_reg_read_opcode);
do {
status_byte1 = ssp2_lab_exchange_byte(dummy_byte);
} while (status_byte1 & (1 << 0));
adesto_ds();
fprintf(stderr, "Current status register value byte1 is %x and hence ", status_byte1);
fprintf(stderr, "Erased successfully\n =>");
}

void adesto_flash_page_write(void) {
const uint8_t page_write_opcode = 0x02;
const uint32_t address_to_write = 0x000000;
const uint8_t data = 0xDA;
// Erase the memory to be written
adesto_flash_erase_4k_block(address_to_write);

// Set WEL bit of Status register
adesto_flash_WEL_bit_set();

// Start the flash write sequence
adesto_cs();
ssp2_lab_exchange_byte(page_write_opcode);
adesto_flash_send_address(address_to_write);
ssp2_lab_exchange_byte(data);
adesto_ds();
fprintf(stderr, " writen data '%X' successfully\n =>", data);
}

void adesto_flash_page_read(void) {
uint8_t read_data = 0x00;
const uint32_t address_to_write = 0x000000;
const uint8_t page_read_opcode = 0x0B;
adesto_cs();
ssp2_lab_exchange_byte(page_read_opcode);
adesto_flash_send_address(address_to_write);
ssp2_lab_exchange_byte(dummy_byte);
read_data = ssp2_lab_exchange_byte(dummy_byte);
adesto_ds();
fprintf(stderr, "Now, read data '%X' successfully\n", read_data);
}

#endif
49 changes: 49 additions & 0 deletions projects/lpc40xx_freertos/l4_io/adesto_flash/adesto_flash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* @file adesto_flash.h
* @author Tejas Pidkalwar
* @date 1st Oct 2020
* @brief This file contains the Adesto flash configuration APIs
*/
#ifndef _ADESTO_FLASH_
#define _ADESTO_FLASH_

#include "gpio.h"
#include "lpc40xx.h"

/**
* the Adesto flash 'Manufacturer and Device ID' section
*/
typedef struct {
uint8_t manufacturer_id;
uint8_t device_id_1;
uint8_t device_id_2;
uint8_t extended_device_id;
} adesto_flash_id_s;

/**
* Assert the Slave select pin for SSP2 driver
*/
void adesto_cs(void);

/**
* De-assert the Slave select pin for SSP2 driver
*/
void adesto_ds(void);

/**
* Read the Flash manufacturing and device id information
* @return flash id structure with read information
*/
adesto_flash_id_s adesto_read_signature(void);

/**
* Reads the page of a flash at given address
*/
void adesto_flash_page_read(void);

/**
* Writes the page of a flash at given address
*/
void adesto_flash_page_write(void);

#endif
Loading