summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/soc/spi9bit.c
blob: e48e9e2decf060c7902439c88bf6d7fd25727fa7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>

#include "encoding.h"
#include "platform.h"

#include "eos.h"

#include "spi9bit.h"

#define BIT_GET         ((GPIO_REG(GPIO_INPUT_VAL) & (1 << IOF_SPI1_MISO)) >> IOF_SPI1_MISO)
#define BIT_PUT(b)      { clear_csr(mstatus, MSTATUS_MIE); if (b) GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_MOSI); else GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_MOSI); set_csr(mstatus, MSTATUS_MIE); }

#define SCK_UP          { clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) |=  (1 << IOF_SPI1_SCK); set_csr(mstatus, MSTATUS_MIE); }
#define SCK_DN          { clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_SCK); set_csr(mstatus, MSTATUS_MIE); }

static inline void _sleep(int n) {
    volatile int x = n;

    while(x) x--;
}

/* sck frequency for r/w operations is 0.8Mhz */
void eos_spi9bit_read(uint8_t *data) {
    int i;

    *data = 0;
    for (i=0; i<8; i++) {
        _sleep(10);
        *data = *data << 1;
        *data |= BIT_GET;
        SCK_UP;
        _sleep(10);
        SCK_DN;
    }
}

void eos_spi9bit_write(uint8_t dc, uint8_t data) {
    int i;

    BIT_PUT(dc);
    _sleep(10);
    SCK_UP;
    for (i=0; i<8; i++) {
        _sleep(10);
        SCK_DN;
        BIT_PUT(data & 0x80);
        _sleep(10);
        SCK_UP;
        data = data << 1;
    }
    _sleep(10);
    SCK_DN;
    BIT_PUT(0);
}