STM32 Timer Input Frequency Configuration (PCLKx_Timer) - embedded

I have an issue configuring the timer frequency input. I did read over the reference manual a couple of times and afterwards searched through the web to find an solution.
template <uintptr_t BASE>
void hsi_config(Config config) {
auto base = reinterpret_cast<volatile RCC_TypeDef *>(BASE);
base->CR |= RCC_CR_HSION;
while (!(base->CR & RCC_CR_HSIRDY))
;
// config flash latency
FLASH->ACR |= config.ahb_flash_latency;
// for now always use TIMPRE = 0
base->DCKCFGR1 &= ~RCC_DCKCFGR1_TIMPRE;
base->CFGR |= (config.ahb_prescaler << 4U) | (config.apb1_prescaler << 10U) | (config.apb2_prescaler << 13U);
// config PLL
base->PLLCFGR = 0;
base->PLLCFGR |= (config.pllm << 0U) | (config.plln << 6U) | (RCC_PLLCFGR_PLLSRC_HSI << 22U) | (config.pllp << 16U) | (config.pllq << 24U);
// activate PLL
base->CR |= RCC_CR_PLLON;
while (!(base->CR & RCC_CR_PLLRDY))
;
// Change HSI to PLL
base->CFGR &= ~RCC_CFGR_SW;
base->CFGR |= RCC_CFGR_SW_PLL;
while ((base->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
;
}
With example the following values:
hsi = 16MHz
pllm = 8
plln = 96
pllp = 2
=> sysclk = ((16MHz / 8) * 96) / 2 = 96MHz
ahb_prescaler = 1
=> hclk = 96MHz
apb1_prescaler = 2
=> pckl1 = 48MHz
=> pclk1_timer = pclk1 * 2 (As apb1 != 1 and TIMPRE = 0) (Rule from TIMPRE Register)
As a simple app to validate the frequency I used a timer which just counts to 1000 and then reloads.
Input 96MHz
PSC = 47999 => 2KHz frequency
ARR = 2000 => Overflow once a second
However I get an overflow after 3 seconds => the timer is not at 96MHz but at 32MHz.
I also checked that with other configurations like pclk1_timer = 48MHz it always seems that the timer input is at 32MHz. (Overflow then happens after 1.5s)
Am I missing something in my configuration?

Related

Attiny 84 Communicating with RTC Through SPI Troubles

I am currently trying to use an ATtiny84 to communicate with an RTC (DS1305) through SPI to make an buzzer vibrate every variable amount of time. I've been trying to set alarm0 on the DS1305. However, the 84 does not "technically" have SPI. It has USI which can be programmed to be like SPI. I was wondering if any of you could review my code/ board connections and let me know if you see any problems. The current problem is that I cannot get any communication going through SPI and I am having trouble finding what the issue could be.
Current board connections:
ATtiny84 | DS1305
MOSI ------ DI
MISO ------ DO
USCLK ---- CLK
Datasheets:
Attiny84
DS1305
/*
* Atmel_Jolt_Code.c
*
* Created: 11/28/2018 10:44:30 PM
* Author : Nick Hulsey
*/
#include <avr/io.h>
#define F_CPU 16000000UL
#include <avr/interrupt.h>
#include <util/delay.h>
//variables for SPI
#define SPI_DDR_PORT DDRA
#define CE_PIN DDA3 //I ADDED *****
#define DO_DD_PIN DDA5 // SHOULD WE
#define DI_DD_PIN DDA6 // THEM FLIP
#define USCK_DD_PIN DDA4
#define SPI_MODE0 0x00
#define SPI_MODE1 0x04
#define MOTOR_PIN DDA7 //I ADDED *****
void SPI_begin();
void setDataMode(uint8_t spiDataMode);
uint8_t transfer(uint8_t spiData);
void flipLatch(uint8_t on);
int main(void)
{
SPI_begin();
setDataMode(SPI_MODE1);
DDRA |= (1 << MOTOR_PIN);
//**startup**
uint8_t status_register = 0x10;
uint8_t control_register = 0x8F;
uint8_t control_byte = 0x05;
uint8_t alarm_registers[] = {0x8A, 0x89, 0x88, 0x87};
//set control
flipLatch(1);
transfer(control_register);
transfer(0);
flipLatch(0);
flipLatch(1);
transfer(control_register);
transfer(control_byte);
flipLatch(0);
//set alarm:
for (int i = 0; i < 4; i++){
flipLatch(1);
transfer(alarm_registers[i]);
transfer(0x80); //0b10000000
flipLatch(0);
}
//THIS MIGHT NEED WORK
//GIMSK |= (1 << PCIE1);//set external interrupt (A1)
PCMSK0 |= (1 << PCINT1);
sei();
while (1) //our main loop
{
//reading the flag from the status register
uint8_t status = transfer(status_register);
if(status == 0x01){//if alarm 0 has been flagged
PORTA ^= (1 << MOTOR_PIN);
_delay_ms(100);
}
}
}
//if A1 has changed state at all this function will fire
ISR(PCINT1_vect){
PORTA ^= (1 << MOTOR_PIN);//invert motor power
_delay_ms(100);
}
void SPI_begin(){
USICR &= ~((1 << USISIE) | (1 << USIOIE) | (1 << USIWM0));//Turn off these bits
USICR |= (1 << USIWM0) | (1 << USICS1) | (1 << USICLK);//Turn on these bits
//REVIEW THIS PAGE 128
//external,positive edge software clock
//What does this mean
SPI_DDR_PORT |= 1 << USCK_DD_PIN; // set the USCK pin as output
SPI_DDR_PORT |= 1 << DO_DD_PIN; // set the DO pin as output
SPI_DDR_PORT |= 1 << CE_PIN;// ******** I ADDED
SPI_DDR_PORT &= ~(1 << DI_DD_PIN); // set the DI pin as input
}
void setDataMode(uint8_t spiDataMode)
{
if (spiDataMode == SPI_MODE1)
USICR |= (1 << USICS0);
else
USICR &= (1 << USICS0);
}
//returns values returned from the IC
uint8_t transfer(uint8_t spiData)
{
USIDR = spiData;
USISR = (1 << USIOIF); // clear counter and counter overflow interrupt flag
//ATOMIC_BLOCK(ATOMIC_RESTORESTATE) // ensure a consistent clock period
//{
while ( !(USISR & (1 << USIOIF)) ) USICR |= (1 << USITC);
//}
return USIDR;
}
void flipLatch(uint8_t on){
if (on == 1)
PORTA |= (1 << CE_PIN);
else
PORTA &= ~(1 << CE_PIN);
}

Why am I only getting 0xFF when reading from the LIS3DSH accelerometer on the STM32F407G-Disc1 MCU?

So I'm learning embedded development, and I recently learned the basics of SPI. As a project, I wanted to communicate with the LIS3DSH accelerometer on my STM32F407G-DISC1 board using only the CMSIS headers.
I pasted the entire code below, but I'll explain it first because no one wants to read all that code.
As a reference, these are the pins needed (according to the MCU's datasheet) to communicate via SPI:
PA5 - SPI1_SCK
PA7 - SPI1_MOSI
PA6 - SPI1_MISO
PE3 - CS_I2C/SPI
Here's the steps I took in my code:
Enabled the clock for GPIOA and GPIOE using the AHB1ENR register.
For GPIOA, I set the three pins as alternate function, output is push-pull, speed is low, no pull-up/pull-down, and configured the alternate function as SPI.
For GPIOE, set it as GPIO mode, push-pull, low speed, pull-up, and then set it high (as in wrote to the BSSR register).
Enabled the clock for SPI using the APB2ENR register.
Configured SPI1: first disabled it, enabled 2-line unidirectional mode, set baud rate to fPCL/16 since the APB2 peripheral clock is 84MHz and the max clock of the accelerometer is 10MHz. Then set clock phase and polarity to 1. 8-bit data frame, MSB first, enabled software slave management, and also enabled master configuration. Finally, enabled SPI1.
After all this, I transmit 0x63 to the 0x20 register of the accelerometer. This sets the output rate to 100Hz and enables both the x and y axis. I have no idea if this is actually working. I'm assuming it is because the TX buffer is empty when I check the SPI status register.
Then to test whether I can recieve, I attempt to get the data from the WHO_AM_I register of the accelerometer. But I only see garbage data when I debug it (0xFF).
I've googled around to see why this may be, and a lot of people suggested that the clock polarity and phase may be incorrect. However, I've checked it multiple times, and I'm fairly certain I configured it properly.
I've tried setting interrupts. During the interrupt, even though RXNE (RX buffer not empty) is true, it still reads only 0xFF. I'm stumped as to why this is happening.
The code is below. The starting point is accelerometer_init(). The reading of the data from the WHO_AM_I register is in turn_on_accelerometer().
#include <stdint.h>
#include <stdbool.h>
#include "stm32f4xx.h"
#include "accelerometer.h"
static void gpio_clock_enable(void);
static void gpio_a_init(void);
static void gpio_e_init(void);
static void accelerometer_clock_enable(void);
static void configure_accelerometer(void);
static void pull_slave_high(void);
static void pull_slave_low(void);
static void turn_on_accelerometer(void);
static void wait_till_transmit_complete(void);
static void transmit_only(uint8_t address, uint8_t data);
static void receive_dummy_data(void);
void accelerometer_init(void) {
gpio_clock_enable();
gpio_a_init();
gpio_e_init();
accelerometer_clock_enable();
configure_accelerometer();
turn_on_accelerometer();
}
void gpio_clock_enable(void) {
RCC_TypeDef *rcc = RCC;
rcc->AHB1ENR |= (1 << 0) | (1 << 4);
}
void gpio_a_init(void) {
GPIO_TypeDef *gpio_a = GPIOA;
// Reset mode and set as alternate function
gpio_a->MODER &= ~(0x3 << 10) & ~(0x3 << 12) & ~(0x3 << 14);
gpio_a->MODER |= (0x2 << 10) | (0x2 << 12) | (0x2 << 14);
// Set output to PP
gpio_a->OTYPER &= ~(1 << 5) & ~(1 << 6) & ~(1 << 7);
// Set speed to low
gpio_a->OSPEEDR &= ~(0x3 << 10) & ~(0x3 << 12) & ~(0x3 << 14);
// Set to no pull-up / pull-down
gpio_a->PUPDR &= ~(0x3 << 10) & ~(0x3 << 12) & ~(0x3 << 14);
// Reset alternate function and set to SPI
gpio_a->AFR[0] &= ~(0xF << 20) & ~(0xF << 24) & ~(0xF << 28);
gpio_a->AFR[0] |= (0x5 << 20) | (0x5 << 24) | (0x5 << 28);
}
void gpio_e_init(void) {
GPIO_TypeDef *gpio_e = GPIOE;
// Set as general purpose output mode
gpio_e->MODER &= ~(0x3 << 6);
gpio_e->MODER |= (1 << 6);
// Set as push pull
gpio_e->OTYPER &= ~(1 << 3);
// Set as low speed
gpio_e->OSPEEDR &= ~(0x3 << 6);
// Set to pull up
gpio_e->PUPDR &= ~(0x3 << 6);
gpio_e->PUPDR |= (1 << 6);
// Set it high
pull_slave_high();
}
void accelerometer_clock_enable(void) {
RCC_TypeDef *rcc = RCC;
rcc->APB2ENR |= (1 << 12);
}
void configure_accelerometer(void) {
SPI_TypeDef *spi_1 = SPI1;
// First disable it while we configure SPI
spi_1->CR1 &= ~(1 << 6);
// 2-line unidirectional data mode enabled
spi_1->CR1 &= ~(1 << 15);
// Reset baud rate and set to fPCLK/16
// because APB2 peripheral clock currently is 84 MHz
// and the max clock of the accelerometer is 10 MHz.
spi_1->CR1 &= ~(0x7 << 3);
spi_1->CR1 |= (0x3 << 3);
// Set clock phase to 1
spi_1->CR1 |= (1 << 0);
// Set clock polarity to 1
spi_1->CR1 |= (1 << 1);
// 8 bit data frame format
spi_1->CR1 &= ~(1 << 11);
// MSB first
spi_1->CR1 &= ~(1 << 7);
// Software slave management enabled
spi_1->CR1 |= (1 << 9);
spi_1->CR1 |= (1 << 8);
// Master configuration enabled
spi_1->CR1 |= (1 << 2);
// SS output enabled
// spi_1->CR2 |= (1 << 2);
// Enable SPI
spi_1->CR1 |= (1 << 6);
// Wait a little bit for accelerometer to turn on
for (int i=0; i<1000000; i++);
}
void pull_slave_high(void) {
// Wait until SPI is no longer busy
SPI_TypeDef *spi_1 = SPI1;
while ((spi_1->SR >> 7) & 1);
GPIO_TypeDef *gpio_e = GPIOE;
gpio_e->BSRR |= (1 << 19);
}
void pull_slave_low(void) {
// Wait until SPI is no longer busy
SPI_TypeDef *spi_1 = SPI1;
while ((spi_1->SR >> 7) & 1);
GPIO_TypeDef *gpio_e = GPIOE;
gpio_e->BSRR |= (1 << 3);
}
void turn_on_accelerometer(void) {
// Set output data rate to 100Hz
// and enable X-axis, Y-axis.
transmit_only(0x20, 0x63);
receive_dummy_data();
// Temp test checking the WHO_AM_I register on the accelerometer.
SPI_TypeDef *spi_1 = SPI1;
pull_slave_low();
wait_till_transmit_complete();
uint8_t address = 0x0F | 0x80;
spi_1->DR = address;
wait_till_transmit_complete();
while (true) {
volatile bool is_busy = (spi_1->SR >> 7) & 1;
volatile bool is_rx_buffer_not_empty = (spi_1->SR >> 0) & 1;
if (!is_busy && is_rx_buffer_not_empty) {
break;
}
}
volatile uint32_t data = spi_1->DR;
pull_slave_high();
}
/*
* Transmit is synchronous.
*/
void transmit_only(uint8_t address, uint8_t data) {
SPI_TypeDef *spi_1 = SPI1;
// Select the accelerometer as the slave
pull_slave_low();
// Wait till transmit buffer is ready
wait_till_transmit_complete();
spi_1->DR = address;
// Wait till transmit buffer is ready
wait_till_transmit_complete();
spi_1->DR = data;
// Wait till transmit buffer has been read
wait_till_transmit_complete();
// Deselect the slave
pull_slave_high();
}
void wait_till_transmit_complete(void) {
SPI_TypeDef *spi_1 = SPI1;
while (true) {
volatile bool is_busy = (spi_1->SR >> 7) & 1;
volatile bool is_transmit_buffer_empty = (spi_1->SR >> 1) & 1;
if (!is_busy && is_transmit_buffer_empty) {
break;
}
}
}
void receive_dummy_data(void) {
SPI_TypeDef *spi_1 = SPI1;
spi_1->DR;
spi_1->SR;
}
You are working with SPI incorrectly.
This bus works in this way:
master (MCU) sends byte in MOSI
line at the same (!) time slave (LIS) sends byte in MISO line. In this moment slave dont know, what exactly byte master transfers to it.
To transfer one byte, you should:
write byte in data register
wait for completition of transfer
read data register
Thus, to read WHO_AM_I register, we obtain next sequence:
init SPI
flush data register (just read SPI->DR)
send command
wait
read dummy data (your 0xFF)
write second byte (0x00 or 0xFF, it doesn't matter)
wait
read correct answer from LIS

atmega 328p interrupt and timer setup [C/C++]

I am trying to set up one interrupt and one counter/timer. The interrupt is external, reading low logic from pin. Timer should increment every 100 us and add up to count variable.
I've set up the interrupt, which is working fine however, after setting up a timer, neither interrupt nor timer works. The code is such:
volatile boolean allowCount = false, timerFlag = false;
volatile unsigned int counter;
boolean pulseLow = false;
void setup(){
Serial.begin(9600);
// initialize external pin interrupt.
PCICR = 0b00000010; // 1. PCIE1: Pin Change Interrupt Enable 1
EICRA |= bit (ISC10); // set wanted flags (low logic level causes interrupt)
PCMSK1 = 0b00010000; // Enable Pin Change Interrupt for A4
// TODO Interrupt settings not working together
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count:
OCR1A = 0x18;
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 64 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS11);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
}
void loop(){
if (allowCount == true)
{ timer100_uS();
if (counter > 50 && pulseLow == false){
DDRC |= (1 << DDC3 ); // sets bit DDC3 to 1 within register DDRC
//set pin 3(A3) ouput as sourcing Vcc(HIGH)
PORTC |= (1 << PORTC3);
timerReset();
pulseLow = true;
}
if (pulseLow == true){
timer100_uS();
if (counter >= 500){
//set pin3 of port C to LOW (A3);
PORTC &= ~(1 << PORTC3);
pulseLow = false
timerReset();
}
}
// external pin interrupt
ISR(PCINT1_vect){
if (allowCount == false)
allowCount = true;
}
// timer/counter interrupt
ISR (TIMER1_COMPA_vect)
{
if (timerFlag == true){
counter++;
}
}
void timer_100uS(void){
timerFlag = true;
cli();
}
void timerReset(void){
sei();
timerFlag = false;
counter = 0;
}
Value of OCR0A is calculated to be 24 (0x18) with prescaler 64 and 16 MHz processor based on this formula:
OCRn = [ (clock_speed / Prescaler_value) * Desired_time_in_Seconds ] - 1
How to set up different interrupts so that they don't overlap eachother ?
Or better yet, is it possible to set up timer so that it does not use interrupt ?
Thanks for reading !
As I can see, you are using ATMega328 with Arduino libraries. Your problem is that Arduino library internally uses Timer 1 for its internal purposes. Therefore if you add your own interrupt handler for Timer 1, you override Arduino's interrupt handler for Timer 1 which breaks the library.
If you want to stay with Arduino library, use the library also to control the timer: Arduino Timer1
Thank you for answers #old_timer, #klasyc.
Quite late, but I solved it by using timer0 instead of timer1 with following settings in setup:
// initialize external pin interrupt.
PCICR = 0b00000010; // 1. PCIE1: Pin Change Interrupt Enable 1
EICRA |= bit (ISC10); // set wanted flags (falling edge causes interrupt)
PCMSK1 = 0b00001000; // Enable Pin Change Interrupt for A3
TCCR0B = 0;
TCCR0A = 0;
//set CTC mode
TCCR0A = ( 1 << WGM01 );
// set OCR0A value for 1 us counter (OCRxn = (freq/prescaler)*desired_value)-1
OCR0A = 15;
// set compare match counter
TIMSK0 |= (1 << OCIE0A);
//set prescaler
TCCR0B |= ( 1 << CS00);
and outside the loop:
ISR(TIMER0_COMPA_vect){
counter++;
}

AVR: volatile variable resetting to zero

I have an interrupt service routine that contains the variable count and a variable state that changes when count reaches a certain value.
What I want my code to do is change and maintain state for a certain period of time determined by the value of count in the if statements in the ISR.
e.g. I want the variable state to equal 1 for 10 counts;
I want state to equal 0 for 5 counts.
Somewhat similar to changing the duty cycle of a PWM.
The problem I am having is that the variable state resets to zero around the end of the ISR or the end of the if statement, I'm not sure.
After searching for answers, I have found that it might be related to the gcc compiler's optimisation but I cannot find a fix for this problem besides declaring volatile variables, which I have already done.
Any help is appreciated thanks.
My code:
#include <avr/io.h>
#include <avr/interrupt.h>
volatile int count = 0;
volatile int state = 0;
int main(void)
{
cli();
DDRB |= (1 << PB2);
TCCR0B |= (1 << CS02)|(0 << CS01)|(1 << CS00);
TIMSK |= (1 << TOIE0);
sei();
while(1) {
...
}
}
ISR(TIM0_OVF_vect)
{
cli();
// user code here
count = count + 1;
if ((count > 5) && (state < 1) && !(PORTB & (1 << PB2))) {
state = 1;
count = 0;
}
else if ((count > 10) && (state > 0) && (PORTB & (1 << PB2))) {
state = 0;
count = 0;
}
sei();
}
First of all your cli() has no effect in your ISR. When an interrupt happens the I flag automatically cleared and restored at the end of ISR - so sei() is needless as well. However there is rational case when sei() inserted somewhere in the middle of an ISR service to let other ISR's to interrupt it. Though it is not beginner level to build such sophisticated ISR system.
Second: if you set up a conditional structure the elementary conditions should be chained by double operators. The evaluation of (count > 5) & (state < 1) cannot be predicted, correctly written it is (count > 5) && (state < 1). Obviously for 'or'-ing || is used.
The conditions of the if statements look suspicious if you are mimicking a PWM.
Why is the pin of port B being tested? The bodies of the if statements will only be entered if the pin (button) is pressed with the correct frequency.
Do you mean to set the pin on port B instead? Then you would want
count = count + 1;
if ((count > 5) && (state < 1)) {
PORTB &= ~(1 << PB2); // clears PB2
state = 1;
count = 0;
}
else if ((count > 10) && (state > 0)) {
PORTB |= 1 << PB2; // sets PB2
state = 0;
count = 0;
}

S3c2440(ARM9) spi_read_write Flash Memory

I am working on SPI communication.Trying to communicate SST25VF032B(32 MB microchip SPI Flash).
When I am reading the Manufacturer Id it shows MF_ID =>4A25BF
but originally it is MF_ID =>BF254A. I am getting it simply reverse, means first bite in 3rd and 3rd byte in first.
What could be the possible reason for that?
My SPI Init function is here:
//Enable clock control register CLKCON 18 Bit enables SPI
CLKCON |= (0x01 << 18);//0x40000;
printk("s3c2440_clkcon=%08ld\n",CLKCON);
//Enable GPG2 Corresponding NSS port
GPGCON =0x1011;//010000 00 01 00 01
printk("s3c2440_GPGCON=%08ld\n",GPGCON);
SPNSS0_ENABLE();
//Enable GPE 11,12,13,Corresponding MISO0,MOSI0,SCK0 = 11 0x0000FC00
GPECON &= ~((3 << 22) | (3 << 24) | (3 << 26));
GPECON |= ((2 << 22) | (2 << 24) | (2 << 26));
//GPEUP Set; all disable
GPGUP &= ~(0x07 << 2);
GPEUP |= (0x07 << 11);
//SPI Register section
//SPI Prescaler register settings,
//Baud Rate=PCLK/2/(Prescaler value+1)
SPPRE0 = 0x18; //freq = 1M
printk("SPPRE0=%02X\n",SPPRE0);
//polling,en-sck,master,low,format A,nomal = 0 | TAGD = 1
SPCON0 = (0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0);
printk("SPCON1=%02ld\n",SPCON0);
//Multi-host error detection is enabled
SPPIN0 = (0 << 2) | (1 << 1) | (0 << 0);
printk("SPPIN1=%02X\n",SPPIN0);
//Initialization procedure
SPTDAT0 = 0xff;
My spi_read_write function as follows:
static char spi_read_write (unsigned char outb)
{
// Write and Read a byte on SPI interface.
int j = 0;
unsigned char inb;
SPTDAT0 = outb;
while(!SPI_TXRX_READY) for(j = 0; j < 0xFF; j++);
SPTDAT0 = outb;
//SPTDAT0 = 0xff;
while(!SPI_TXRX_READY) for(j = 0; j < 0xFF; j++);
inb = SPRDAT0;
return (inb);
}
My Calling function is:
MEM_1_CS(0);
spi_read_write(0x9F);
m1 = spi_read_write(0x00);
m2 = spi_read_write(0x00);
m3 = spi_read_write(0x00);
MEM_1_CS(1);
printk("\n\rMF_ID =>%02X-%02X-%02X",m1,m2,m3);
Please guide me what to do?
Thanks in Advance!!
There's no apparent problem with the SPI function.
The problem is with your printing function.
Arm is little endian processor. it keeps the bytes reversed in memory.
You need to print it reverse order and you'll be fine.
I was banging my head on this from last couple of days and finally I find the solution. All I needed to change my spi_read_write function as follows.
static char spi_read_write (unsigned char outb)
{
int j = 0;
unsigned char inb;
while(!SPI_TXRX_READY) for(j = 0; j < 0xFF; j++);
SPTDAT0 = outb;
while(!SPI_TXRX_READY) for(j = 0; j < 0xFF; j++);
inb = SPRDAT0;
return (inb);
}
CHANGES MADE:
First of all we have to check whether the SPI_TXRX_READY then fill the register with the value SPTDAT0 = outb;.
Thanks all for your kind support.